Module: Datadog::CI::Git::LocalRepository

Defined in:
lib/datadog/ci/git/local_repository.rb

Defined Under Namespace

Classes: GitCommandExecutionError

Constant Summary collapse

COMMAND_RETRY_COUNT =
3

Class Method Summary collapse

Class Method Details

.current_folder_nameObject



59
60
61
# File 'lib/datadog/ci/git/local_repository.rb', line 59

def self.current_folder_name
  File.basename(root)
end

.git_branchObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/datadog/ci/git/local_repository.rb', line 93

def self.git_branch
  Telemetry.git_command(Ext::Telemetry::Command::GET_BRANCH)
  res = nil

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    res = exec_git_command("git rev-parse --abbrev-ref HEAD")
  end

  Telemetry.git_command_ms(Ext::Telemetry::Command::GET_BRANCH, duration_ms)
  res
rescue => e
  log_failure(e, "git branch")
  telemetry_track_error(e, Ext::Telemetry::Command::GET_BRANCH)
  nil
end

.git_commit_messageObject



116
117
118
119
120
121
# File 'lib/datadog/ci/git/local_repository.rb', line 116

def self.git_commit_message
  exec_git_command("git show -s --format=%s")
rescue => e
  log_failure(e, "git commit message")
  nil
end

.git_commit_shaObject



86
87
88
89
90
91
# File 'lib/datadog/ci/git/local_repository.rb', line 86

def self.git_commit_sha
  exec_git_command("git rev-parse HEAD")
rescue => e
  log_failure(e, "git commit sha")
  nil
end

.git_commit_usersObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/datadog/ci/git/local_repository.rb', line 123

def self.git_commit_users
  # Get committer and author information in one command.
  output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'")
  unless output
    Datadog.logger.debug(
      "Unable to read git commit users: git command output is nil"
    )
    nil_user = NilUser.new
    return [nil_user, nil_user]
  end

  author_name, author_email, author_timestamp,
    committer_name, committer_email, committer_timestamp = output.split("\t").each(&:strip!)

  author = User.new(author_name, author_email, author_timestamp)
  committer = User.new(committer_name, committer_email, committer_timestamp)

  [author, committer]
rescue => e
  log_failure(e, "git commit users")

  nil_user = NilUser.new
  [nil_user, nil_user]
end

.git_commitsObject

returns maximum of 1000 latest commits in the last month



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/datadog/ci/git/local_repository.rb', line 149

def self.git_commits
  Telemetry.git_command(Ext::Telemetry::Command::GET_LOCAL_COMMITS)

  output = nil
  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    output = exec_git_command("git log --format=%H -n 1000 --since=\"1 month ago\"")
  end

  Telemetry.git_command_ms(Ext::Telemetry::Command::GET_LOCAL_COMMITS, duration_ms)

  return [] if output.nil?

  # @type var output: String
  output.split("\n")
rescue => e
  log_failure(e, "git commits")
  telemetry_track_error(e, Ext::Telemetry::Command::GET_LOCAL_COMMITS)
  []
end

.git_commits_rev_list(included_commits:, excluded_commits:) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/datadog/ci/git/local_repository.rb', line 169

def self.git_commits_rev_list(included_commits:, excluded_commits:)
  Telemetry.git_command(Ext::Telemetry::Command::GET_OBJECTS)
  included_commits = filter_invalid_commits(included_commits).join(" ")
  excluded_commits = filter_invalid_commits(excluded_commits).map! { |sha| "^#{sha}" }.join(" ")

  res = nil

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    res = exec_git_command(
      "git rev-list " \
      "--objects " \
      "--no-object-names " \
      "--filter=blob:none " \
      "--since=\"1 month ago\" " \
      "#{excluded_commits} #{included_commits}"
    )
  end

  Telemetry.git_command_ms(Ext::Telemetry::Command::GET_OBJECTS, duration_ms)

  res
rescue => e
  log_failure(e, "git commits rev list")
  telemetry_track_error(e, Ext::Telemetry::Command::GET_OBJECTS)
  nil
end

.git_generate_packfiles(included_commits:, excluded_commits:, path:) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/datadog/ci/git/local_repository.rb', line 196

def self.git_generate_packfiles(included_commits:, excluded_commits:, path:)
  return nil unless File.exist?(path)

  commit_tree = git_commits_rev_list(included_commits: included_commits, excluded_commits: excluded_commits)
  return nil if commit_tree.nil?

  basename = SecureRandom.hex(4)

  Telemetry.git_command(Ext::Telemetry::Command::PACK_OBJECTS)

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    exec_git_command(
      "git pack-objects --compression=9 --max-pack-size=3m #{path}/#{basename}",
      stdin: commit_tree
    )
  end
  Telemetry.git_command_ms(Ext::Telemetry::Command::PACK_OBJECTS, duration_ms)

  basename
rescue => e
  log_failure(e, "git generate packfiles")
  telemetry_track_error(e, Ext::Telemetry::Command::PACK_OBJECTS)
  nil
end

.git_repository_urlObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/datadog/ci/git/local_repository.rb', line 63

def self.git_repository_url
  Telemetry.git_command(Ext::Telemetry::Command::GET_REPOSITORY)
  res = nil

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    res = exec_git_command("git ls-remote --get-url")
  end

  Telemetry.git_command_ms(Ext::Telemetry::Command::GET_REPOSITORY, duration_ms)
  res
rescue => e
  log_failure(e, "git repository url")
  telemetry_track_error(e, Ext::Telemetry::Command::GET_REPOSITORY)
  nil
end

.git_rootObject



79
80
81
82
83
84
# File 'lib/datadog/ci/git/local_repository.rb', line 79

def self.git_root
  exec_git_command("git rev-parse --show-toplevel")
rescue => e
  log_failure(e, "git root path")
  nil
end

.git_shallow_clone?Boolean

Returns:

  • (Boolean)


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/datadog/ci/git/local_repository.rb', line 221

def self.git_shallow_clone?
  Telemetry.git_command(Ext::Telemetry::Command::CHECK_SHALLOW)
  res = false

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    res = exec_git_command("git rev-parse --is-shallow-repository") == "true"
  end
  Telemetry.git_command_ms(Ext::Telemetry::Command::CHECK_SHALLOW, duration_ms)

  res
rescue => e
  log_failure(e, "git shallow clone")
  telemetry_track_error(e, Ext::Telemetry::Command::CHECK_SHALLOW)
  false
end

.git_tagObject



109
110
111
112
113
114
# File 'lib/datadog/ci/git/local_repository.rb', line 109

def self.git_tag
  exec_git_command("git tag --points-at HEAD")
rescue => e
  log_failure(e, "git tag")
  nil
end

.git_unshallowObject



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/datadog/ci/git/local_repository.rb', line 237

def self.git_unshallow
  Telemetry.git_command(Ext::Telemetry::Command::UNSHALLOW)
  res = nil

  duration_ms = Core::Utils::Time.measure(:float_millisecond) do
    res = exec_git_command(
      "git fetch " \
      "--shallow-since=\"1 month ago\" " \
      "--update-shallow " \
      "--filter=\"blob:none\" " \
      "--recurse-submodules=no " \
      "$(git config --default origin --get clone.defaultRemoteName) $(git rev-parse HEAD)"
    )
  end
  Telemetry.git_command_ms(Ext::Telemetry::Command::UNSHALLOW, duration_ms)

  res
rescue => e
  log_failure(e, "git unshallow")
  telemetry_track_error(e, Ext::Telemetry::Command::UNSHALLOW)
  nil
end

.relative_to_root(path) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/datadog/ci/git/local_repository.rb', line 33

def self.relative_to_root(path)
  return "" if path.nil?

  root_path = root
  return path if root_path.nil?

  path = Pathname.new(File.expand_path(path))
  root_path = Pathname.new(root_path)

  path.relative_path_from(root_path).to_s
end

.repository_nameObject



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/datadog/ci/git/local_repository.rb', line 45

def self.repository_name
  return @repository_name if defined?(@repository_name)

  git_remote_url = git_repository_url

  # return git repository name from remote url without .git extension
  last_path_segment = git_remote_url.split("/").last if git_remote_url
  @repository_name = last_path_segment.gsub(".git", "") if last_path_segment
  @repository_name ||= current_folder_name
rescue => e
  log_failure(e, "git repository name")
  @repository_name = current_folder_name
end

.rootObject



27
28
29
30
31
# File 'lib/datadog/ci/git/local_repository.rb', line 27

def self.root
  return @root if defined?(@root)

  @root = git_root || Dir.pwd
end