Class: Gitlab::Diff::Position

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/diff/position.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ Position

A position can belong to a text line or to an image coordinate it depends of the position_type argument. Text position will have: new_line and old_line Image position will have: width, height, x, y


28
29
30
# File 'lib/gitlab/diff/position.rb', line 28

def initialize(attrs = {})
  @formatter = get_formatter_class(attrs[:position_type]).new(attrs)
end

Instance Attribute Details

#formatterObject

Returns the value of attribute formatter


8
9
10
# File 'lib/gitlab/diff/position.rb', line 8

def formatter
  @formatter
end

Instance Method Details

#==(other) ⇒ Object


51
52
53
54
55
56
57
# File 'lib/gitlab/diff/position.rb', line 51

def ==(other)
  other.is_a?(self.class) &&
    other.diff_refs == diff_refs &&
    other.old_path == old_path &&
    other.new_path == new_path &&
    other.formatter == formatter
end

#added?Boolean

Returns:

  • (Boolean)

91
92
93
# File 'lib/gitlab/diff/position.rb', line 91

def added?
  type == 'new'
end

#as_json(opts = nil) ⇒ Object


75
76
77
# File 'lib/gitlab/diff/position.rb', line 75

def as_json(opts = nil)
  to_h.as_json(opts)
end

#complete?Boolean

Returns:

  • (Boolean)

67
68
69
# File 'lib/gitlab/diff/position.rb', line 67

def complete?
  file_path.present? && formatter.complete? && diff_refs.complete?
end

#diff_file(repository) ⇒ Object


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/gitlab/diff/position.rb', line 115

def diff_file(repository)
  return @diff_file if defined?(@diff_file)

  @diff_file = begin
    key = {
      project_id: repository.project.id,
      start_sha: start_sha,
      head_sha: head_sha,
      path: file_path
    }

    # Takes action when creating diff notes (multiple calls are
    # submitted to this method).
    Gitlab::SafeRequestStore.fetch(key) { find_diff_file(repository) }
  end

  # We need to unfold diff lines according to the position in order
  # to correctly calculate the line code and trace position changes.
  @diff_file&.tap { |file| file.unfold_diff_lines(self) }
end

#diff_line(repository) ⇒ Object


140
141
142
# File 'lib/gitlab/diff/position.rb', line 140

def diff_line(repository)
  @diff_line ||= diff_file(repository)&.line_for_position(self)
end

#diff_optionsObject


136
137
138
# File 'lib/gitlab/diff/position.rb', line 136

def diff_options
  { paths: paths, expanded: true, include_stats: false }
end

#diff_refsObject


107
108
109
# File 'lib/gitlab/diff/position.rb', line 107

def diff_refs
  @diff_refs ||= DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha)
end

#encode_with(coder) ⇒ Object


43
44
45
# File 'lib/gitlab/diff/position.rb', line 43

def encode_with(coder)
  coder['attributes'] = formatter.to_h
end

#file_hashObject


148
149
150
# File 'lib/gitlab/diff/position.rb', line 148

def file_hash
  @file_hash ||= Digest::SHA1.hexdigest(file_path)
end

#file_pathObject


103
104
105
# File 'lib/gitlab/diff/position.rb', line 103

def file_path
  new_path.presence || old_path
end

#find_diff_file_from(diffable) ⇒ Object


160
161
162
163
164
165
166
167
168
# File 'lib/gitlab/diff/position.rb', line 160

def find_diff_file_from(diffable)
  diff_files = diffable.diffs(diff_options).diff_files

  if Feature.enabled?(:file_identifier_hash) && file_identifier_hash.present?
    diff_files.find { |df| df.file_identifier_hash == file_identifier_hash }
  else
    diff_files.first
  end
end

#init_with(coder) ⇒ Object

`Gitlab::Diff::Position` objects are stored as serialized attributes in `DiffNote`, which use YAML to encode and decode objects. `#init_with` and `#encode_with` can be used to customize the en/decoding behavior. In this case, we override these to prevent memoized instance variables like `@diff_file` and `@diff_line` from being serialized.


37
38
39
40
41
# File 'lib/gitlab/diff/position.rb', line 37

def init_with(coder)
  initialize(coder['attributes'])

  self
end

#inspectObject


63
64
65
# File 'lib/gitlab/diff/position.rb', line 63

def inspect
  %(#<#{self.class}:#{object_id} #{to_h}>)
end

#keyObject


47
48
49
# File 'lib/gitlab/diff/position.rb', line 47

def key
  formatter.key
end

#line_code(repository) ⇒ Object


144
145
146
# File 'lib/gitlab/diff/position.rb', line 144

def line_code(repository)
  @line_code ||= diff_file(repository)&.line_code_for_position(self)
end

#on_image?Boolean

Returns:

  • (Boolean)

152
153
154
# File 'lib/gitlab/diff/position.rb', line 152

def on_image?
  position_type == 'image'
end

#on_text?Boolean

Returns:

  • (Boolean)

156
157
158
# File 'lib/gitlab/diff/position.rb', line 156

def on_text?
  position_type == 'text'
end

#pathsObject


99
100
101
# File 'lib/gitlab/diff/position.rb', line 99

def paths
  [old_path, new_path].compact.uniq
end

#removed?Boolean

Returns:

  • (Boolean)

95
96
97
# File 'lib/gitlab/diff/position.rb', line 95

def removed?
  type == 'old'
end

#to_hObject


59
60
61
# File 'lib/gitlab/diff/position.rb', line 59

def to_h
  formatter.to_h
end

#to_json(opts = nil) ⇒ Object


71
72
73
# File 'lib/gitlab/diff/position.rb', line 71

def to_json(opts = nil)
  Gitlab::Json.generate(formatter.to_h, opts)
end

#typeObject


79
80
81
# File 'lib/gitlab/diff/position.rb', line 79

def type
  formatter.line_age
end

#unchanged?Boolean

Returns:

  • (Boolean)

87
88
89
# File 'lib/gitlab/diff/position.rb', line 87

def unchanged?
  type.nil?
end

#unfoldable?Boolean

Returns:

  • (Boolean)

83
84
85
# File 'lib/gitlab/diff/position.rb', line 83

def unfoldable?
  on_text? && unchanged?
end

#unfolded_diff?(repository) ⇒ Boolean

Returns:

  • (Boolean)

111
112
113
# File 'lib/gitlab/diff/position.rb', line 111

def unfolded_diff?(repository)
  diff_file(repository)&.unfolded?
end