Class: Rosette::Core::Commands::DiffCommand

Inherits:
DiffBaseCommand show all
Includes:
WithRepoName
Defined in:
lib/rosette/core/commands/git/diff_command.rb

Overview

Detects phrase changes between two git refs or commit ids. Identifies phrases that have been added, removed, or changed. The refs used in the comparison are referred to as a “head” and a “diff point”. In Rosette/git parlance, a “head” generally means a git ref that is currently being modified, i.e. a branch. A “diff point” is some common ref to compare “head” to, often the repository's “master” branch.

Perhaps an easier way to visualize these concepts is through a git command-line example. Imagine you're developing a feature to add widget support to your app. You start work by switching to a new git branch (i.e. git checkout -b add_widgets). After adding a few files, changing some others, and deleting old code, you want to see a complete set of all your changes. To do this, you run git diff. At this point, your “head” is your branch “add_widgets” and your “diff point” is “master” (or whichever branch you were on when you ran git checkout). You could also have run git diff master or git diff master HEAD to get the same result. You can think of DiffCommand like a git diff command of the form git diff <diff point> <head>.

Examples:

cmd = DiffCommand.new(configuration)
  .set_repo_name('my_repo')
  .set_head_ref('my_branch')
  .set_diff_point_ref('master')
  .set_paths(['config/locales/en.yml'])

cmd.execute# {
#   added: [
#     { key: 'Foo', ... },
#   ],
#   removed: [
#     { key: 'I got deleted', ... }
#   ],
#   modified: [
#     { key: 'New value', old_key: 'Old value', ... }
#   ]
# }

See Also:

Instance Attribute Summary collapse

Attributes included from WithRepoName

#repo_name

Attributes inherited from DiffBaseCommand

#strict

Attributes inherited from Command

#configuration

Instance Method Summary collapse

Methods included from WithRepoName

#set_repo_name

Methods inherited from DiffBaseCommand

#initialize, #set_strict

Methods included from WithSnapshots

#take_snapshot

Methods inherited from GitCommand

#valid?

Methods inherited from Command

#initialize, #messages, #valid?, validate, validators

Constructor Details

This class inherits a constructor from Rosette::Core::Commands::DiffBaseCommand

Instance Attribute Details

#diff_point_commit_strString (readonly)

Returns the raw diff point ref or commit id as set via #set_diff_point_ref or #set_diff_point_commit_id.

Returns:


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rosette/core/commands/git/diff_command.rb', line 59

class DiffCommand < DiffBaseCommand
  attr_reader :head_commit_str, :diff_point_commit_str, :paths

  include WithRepoName

  validate :head_commit_str, type: :commit
  validate :diff_point_commit_str, type: :commit

  # Set the head commit id. Calling this method after {#set_head_ref} will
  # overwrite the head ref value. In other words, it's generally a good idea
  # to only call one of {#set_head_commit_id} or {#set_head_ref} but not both.
  #
  # @param [String] head_commit_id The head commit id.
  # @return [self]
  def set_head_commit_id(head_commit_id)
    @head_commit_str = head_commit_id
    self
  end

  # Set the head ref (i.e. a branch name). Calling this method after
  # {#set_head_commit_id} will overwrite the head commit id value. In other
  # words, it's generally a good idea to only call one of {#set_head_commit_id}
  # or {#set_head_ref} but not both.
  #
  # @param [String] head_ref The head ref.
  # @return [self]
  def set_head_ref(head_ref)
    @head_commit_str = head_ref
    self
  end

  # Set the diff point commit id. Calling this method after {#set_head_ref}
  # will overwrite the head ref value. In other words, it's generally a good
  # idea to only call one of {#set_head_commit_id} or {#set_head_ref} but
  # not both.
  #
  # @param [String] diff_point_commit_id The diff point commit id.
  # @return [self]
  def set_diff_point_commit_id(diff_point_commit_id)
    @diff_point_commit_str = diff_point_commit_id
    self
  end

  # Set the diff point ref (i.e. master). Calling this method after
  # {#set_diff_point_commit_id} will overwrite the diff point commit id value.
  # In other words, it's generally a good idea to only call one of
  # {#set_diff_point_commit_id} or {#set_diff_point_ref} but not both.
  #
  # @param [String] diff_point_ref The diff point ref.
  # @return [self]
  def set_diff_point_ref(diff_point_ref)
    @diff_point_commit_str = diff_point_ref
    self
  end

  # Set the list of paths to consider when computing the diff. Any paths not
  # in this list will not appear in the diff.
  #
  # @param [Array] paths The list of paths.
  # @return [self]
  def set_paths(paths)
    @paths = paths
    self
  end

  # Resolves the given head git ref or commit id and returns the corresponding
  # commit id. If {#set_head_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_head_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_head_ref} or
  #   {#set_head_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def head_commit_id
    @head_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(head_commit_str)
      .getId
      .name
  end

  # Resolves the given diff point git ref or commit id and returns the corresponding
  # commit id. If {#set_diff_point_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_diff_point_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_diff_point_ref} or
  #   {#set_diff_point_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def diff_point_commit_id
    @diff_point_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(diff_point_commit_str)
      .getId
      .name
  end

  # Computes the diff.
  # @return [Hash] a hash of differences, grouped by added/removed/modified keys. Each
  #   value is an array of phrases. For added and removed phrases, the phrase hashes
  #   will contain normal phrase attributes. For changed phrases, the phrase hashes
  #   will contain normal phrase attributes plus a special +old_key+ attribute that
  #   contains the previous key of the phrase. See the example above for a visual
  #   representation of the diff hash.
  def execute
    diff_between(head_commit_id, Array(parent_commit_id))
  end

  protected

  def diff_point_exists?
    commit_exists?(repo_name, diff_point_commit_id)
  end

  def parent_commit_id
    parent_commit_id = if strict? || diff_point_exists?
      diff_point_commit_id
    else
      get_closest_processed_parent(diff_point_commit_id)
    end
  end
end

#head_commit_strString (readonly)

Returns the raw head ref or commit id as set via #set_head_ref or #set_head_commit_id.

Returns:


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rosette/core/commands/git/diff_command.rb', line 59

class DiffCommand < DiffBaseCommand
  attr_reader :head_commit_str, :diff_point_commit_str, :paths

  include WithRepoName

  validate :head_commit_str, type: :commit
  validate :diff_point_commit_str, type: :commit

  # Set the head commit id. Calling this method after {#set_head_ref} will
  # overwrite the head ref value. In other words, it's generally a good idea
  # to only call one of {#set_head_commit_id} or {#set_head_ref} but not both.
  #
  # @param [String] head_commit_id The head commit id.
  # @return [self]
  def set_head_commit_id(head_commit_id)
    @head_commit_str = head_commit_id
    self
  end

  # Set the head ref (i.e. a branch name). Calling this method after
  # {#set_head_commit_id} will overwrite the head commit id value. In other
  # words, it's generally a good idea to only call one of {#set_head_commit_id}
  # or {#set_head_ref} but not both.
  #
  # @param [String] head_ref The head ref.
  # @return [self]
  def set_head_ref(head_ref)
    @head_commit_str = head_ref
    self
  end

  # Set the diff point commit id. Calling this method after {#set_head_ref}
  # will overwrite the head ref value. In other words, it's generally a good
  # idea to only call one of {#set_head_commit_id} or {#set_head_ref} but
  # not both.
  #
  # @param [String] diff_point_commit_id The diff point commit id.
  # @return [self]
  def set_diff_point_commit_id(diff_point_commit_id)
    @diff_point_commit_str = diff_point_commit_id
    self
  end

  # Set the diff point ref (i.e. master). Calling this method after
  # {#set_diff_point_commit_id} will overwrite the diff point commit id value.
  # In other words, it's generally a good idea to only call one of
  # {#set_diff_point_commit_id} or {#set_diff_point_ref} but not both.
  #
  # @param [String] diff_point_ref The diff point ref.
  # @return [self]
  def set_diff_point_ref(diff_point_ref)
    @diff_point_commit_str = diff_point_ref
    self
  end

  # Set the list of paths to consider when computing the diff. Any paths not
  # in this list will not appear in the diff.
  #
  # @param [Array] paths The list of paths.
  # @return [self]
  def set_paths(paths)
    @paths = paths
    self
  end

  # Resolves the given head git ref or commit id and returns the corresponding
  # commit id. If {#set_head_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_head_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_head_ref} or
  #   {#set_head_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def head_commit_id
    @head_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(head_commit_str)
      .getId
      .name
  end

  # Resolves the given diff point git ref or commit id and returns the corresponding
  # commit id. If {#set_diff_point_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_diff_point_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_diff_point_ref} or
  #   {#set_diff_point_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def diff_point_commit_id
    @diff_point_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(diff_point_commit_str)
      .getId
      .name
  end

  # Computes the diff.
  # @return [Hash] a hash of differences, grouped by added/removed/modified keys. Each
  #   value is an array of phrases. For added and removed phrases, the phrase hashes
  #   will contain normal phrase attributes. For changed phrases, the phrase hashes
  #   will contain normal phrase attributes plus a special +old_key+ attribute that
  #   contains the previous key of the phrase. See the example above for a visual
  #   representation of the diff hash.
  def execute
    diff_between(head_commit_id, Array(parent_commit_id))
  end

  protected

  def diff_point_exists?
    commit_exists?(repo_name, diff_point_commit_id)
  end

  def parent_commit_id
    parent_commit_id = if strict? || diff_point_exists?
      diff_point_commit_id
    else
      get_closest_processed_parent(diff_point_commit_id)
    end
  end
end

#pathsArray (readonly)

Returns the list of paths to include in the diff. The diff will not contain phrases that were added/removed/modified in files that are not contained within this list.

Returns:

  • (Array)

    the list of paths to include in the diff. The diff will not contain phrases that were added/removed/modified in files that are not contained within this list.


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rosette/core/commands/git/diff_command.rb', line 59

class DiffCommand < DiffBaseCommand
  attr_reader :head_commit_str, :diff_point_commit_str, :paths

  include WithRepoName

  validate :head_commit_str, type: :commit
  validate :diff_point_commit_str, type: :commit

  # Set the head commit id. Calling this method after {#set_head_ref} will
  # overwrite the head ref value. In other words, it's generally a good idea
  # to only call one of {#set_head_commit_id} or {#set_head_ref} but not both.
  #
  # @param [String] head_commit_id The head commit id.
  # @return [self]
  def set_head_commit_id(head_commit_id)
    @head_commit_str = head_commit_id
    self
  end

  # Set the head ref (i.e. a branch name). Calling this method after
  # {#set_head_commit_id} will overwrite the head commit id value. In other
  # words, it's generally a good idea to only call one of {#set_head_commit_id}
  # or {#set_head_ref} but not both.
  #
  # @param [String] head_ref The head ref.
  # @return [self]
  def set_head_ref(head_ref)
    @head_commit_str = head_ref
    self
  end

  # Set the diff point commit id. Calling this method after {#set_head_ref}
  # will overwrite the head ref value. In other words, it's generally a good
  # idea to only call one of {#set_head_commit_id} or {#set_head_ref} but
  # not both.
  #
  # @param [String] diff_point_commit_id The diff point commit id.
  # @return [self]
  def set_diff_point_commit_id(diff_point_commit_id)
    @diff_point_commit_str = diff_point_commit_id
    self
  end

  # Set the diff point ref (i.e. master). Calling this method after
  # {#set_diff_point_commit_id} will overwrite the diff point commit id value.
  # In other words, it's generally a good idea to only call one of
  # {#set_diff_point_commit_id} or {#set_diff_point_ref} but not both.
  #
  # @param [String] diff_point_ref The diff point ref.
  # @return [self]
  def set_diff_point_ref(diff_point_ref)
    @diff_point_commit_str = diff_point_ref
    self
  end

  # Set the list of paths to consider when computing the diff. Any paths not
  # in this list will not appear in the diff.
  #
  # @param [Array] paths The list of paths.
  # @return [self]
  def set_paths(paths)
    @paths = paths
    self
  end

  # Resolves the given head git ref or commit id and returns the corresponding
  # commit id. If {#set_head_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_head_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_head_ref} or
  #   {#set_head_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def head_commit_id
    @head_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(head_commit_str)
      .getId
      .name
  end

  # Resolves the given diff point git ref or commit id and returns the corresponding
  # commit id. If {#set_diff_point_ref} was used to set a git ref (i.e. branch name),
  # this method looks up and returns the corresponding commit id. If
  # {#set_diff_point_commit_id} was used to set a commit id, then that commit id is
  # validated and returned.
  #
  # @return [String] The commit id set via either {#set_diff_point_ref} or
  #   {#set_diff_point_commit_id}.
  #
  # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
  #   If either the commit id doesn't exist or the ref can't be found.
  def diff_point_commit_id
    @diff_point_commit_id ||= get_repo(repo_name)
      .repo.get_rev_commit(diff_point_commit_str)
      .getId
      .name
  end

  # Computes the diff.
  # @return [Hash] a hash of differences, grouped by added/removed/modified keys. Each
  #   value is an array of phrases. For added and removed phrases, the phrase hashes
  #   will contain normal phrase attributes. For changed phrases, the phrase hashes
  #   will contain normal phrase attributes plus a special +old_key+ attribute that
  #   contains the previous key of the phrase. See the example above for a visual
  #   representation of the diff hash.
  def execute
    diff_between(head_commit_id, Array(parent_commit_id))
  end

  protected

  def diff_point_exists?
    commit_exists?(repo_name, diff_point_commit_id)
  end

  def parent_commit_id
    parent_commit_id = if strict? || diff_point_exists?
      diff_point_commit_id
    else
      get_closest_processed_parent(diff_point_commit_id)
    end
  end
end

Instance Method Details

#diff_point_commit_idString

Resolves the given diff point git ref or commit id and returns the corresponding commit id. If #set_diff_point_ref was used to set a git ref (i.e. branch name), this method looks up and returns the corresponding commit id. If #set_diff_point_commit_id was used to set a commit id, then that commit id is validated and returned.

Returns:

Raises:

  • (Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException)

    If either the commit id doesn't exist or the ref can't be found.


153
154
155
156
157
158
# File 'lib/rosette/core/commands/git/diff_command.rb', line 153

def diff_point_commit_id
  @diff_point_commit_id ||= get_repo(repo_name)
    .repo.get_rev_commit(diff_point_commit_str)
    .getId
    .name
end

#executeHash

Computes the diff.

Returns:

  • (Hash)

    a hash of differences, grouped by added/removed/modified keys. Each value is an array of phrases. For added and removed phrases, the phrase hashes will contain normal phrase attributes. For changed phrases, the phrase hashes will contain normal phrase attributes plus a special old_key attribute that contains the previous key of the phrase. See the example above for a visual representation of the diff hash.


167
168
169
# File 'lib/rosette/core/commands/git/diff_command.rb', line 167

def execute
  diff_between(head_commit_id, Array(parent_commit_id))
end

#head_commit_idString

Resolves the given head git ref or commit id and returns the corresponding commit id. If #set_head_ref was used to set a git ref (i.e. branch name), this method looks up and returns the corresponding commit id. If #set_head_commit_id was used to set a commit id, then that commit id is validated and returned.

Returns:

Raises:

  • (Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException)

    If either the commit id doesn't exist or the ref can't be found.


135
136
137
138
139
140
# File 'lib/rosette/core/commands/git/diff_command.rb', line 135

def head_commit_id
  @head_commit_id ||= get_repo(repo_name)
    .repo.get_rev_commit(head_commit_str)
    .getId
    .name
end

#set_diff_point_commit_id(diff_point_commit_id) ⇒ self

Set the diff point commit id. Calling this method after #set_head_ref will overwrite the head ref value. In other words, it's generally a good idea to only call one of #set_head_commit_id or #set_head_ref but not both.

Parameters:

  • diff_point_commit_id (String)

    The diff point commit id.

Returns:

  • (self)

97
98
99
100
# File 'lib/rosette/core/commands/git/diff_command.rb', line 97

def set_diff_point_commit_id(diff_point_commit_id)
  @diff_point_commit_str = diff_point_commit_id
  self
end

#set_diff_point_ref(diff_point_ref) ⇒ self

Set the diff point ref (i.e. master). Calling this method after #set_diff_point_commit_id will overwrite the diff point commit id value. In other words, it's generally a good idea to only call one of #set_diff_point_commit_id or #set_diff_point_ref but not both.

Parameters:

  • diff_point_ref (String)

    The diff point ref.

Returns:

  • (self)

109
110
111
112
# File 'lib/rosette/core/commands/git/diff_command.rb', line 109

def set_diff_point_ref(diff_point_ref)
  @diff_point_commit_str = diff_point_ref
  self
end

#set_head_commit_id(head_commit_id) ⇒ self

Set the head commit id. Calling this method after #set_head_ref will overwrite the head ref value. In other words, it's generally a good idea to only call one of #set_head_commit_id or #set_head_ref but not both.

Parameters:

  • head_commit_id (String)

    The head commit id.

Returns:

  • (self)

73
74
75
76
# File 'lib/rosette/core/commands/git/diff_command.rb', line 73

def set_head_commit_id(head_commit_id)
  @head_commit_str = head_commit_id
  self
end

#set_head_ref(head_ref) ⇒ self

Set the head ref (i.e. a branch name). Calling this method after #set_head_commit_id will overwrite the head commit id value. In other words, it's generally a good idea to only call one of #set_head_commit_id or #set_head_ref but not both.

Parameters:

  • head_ref (String)

    The head ref.

Returns:

  • (self)

85
86
87
88
# File 'lib/rosette/core/commands/git/diff_command.rb', line 85

def set_head_ref(head_ref)
  @head_commit_str = head_ref
  self
end

#set_paths(paths) ⇒ self

Set the list of paths to consider when computing the diff. Any paths not in this list will not appear in the diff.

Parameters:

  • paths (Array)

    The list of paths.

Returns:

  • (self)

119
120
121
122
# File 'lib/rosette/core/commands/git/diff_command.rb', line 119

def set_paths(paths)
  @paths = paths
  self
end