Class: Danger::GitRepo

Inherits:
Object
  • Object
show all
Defined in:
lib/danger/scm_source/git_repo.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#diffObject

Returns the value of attribute diff.



9
10
11
# File 'lib/danger/scm_source/git_repo.rb', line 9

def diff
  @diff
end

#folderObject

Returns the value of attribute folder.



9
10
11
# File 'lib/danger/scm_source/git_repo.rb', line 9

def folder
  @folder
end

#logObject

Returns the value of attribute log.



9
10
11
# File 'lib/danger/scm_source/git_repo.rb', line 9

def log
  @log
end

Instance Method Details

#diff_for_folder(folder, from: "master", to: "HEAD", lookup_top_level: false) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/danger/scm_source/git_repo.rb', line 11

def diff_for_folder(folder, from: "master", to: "HEAD", lookup_top_level: false)
  self.folder = folder
  git_top_level = find_git_top_level_if_needed!(folder, lookup_top_level)

  repo = Git.open(git_top_level)

  ensure_commitish_exists!(from)
  ensure_commitish_exists!(to)

  merge_base = find_merge_base(repo, from, to)
  commits_in_branch_count = commits_in_branch_count(from, to)

  self.diff = repo.diff(merge_base, to)
  self.log = repo.log(commits_in_branch_count).between(from, to)
end

#ensure_commitish_exists!(commitish) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/danger/scm_source/git_repo.rb', line 75

def ensure_commitish_exists!(commitish)
  return ensure_commitish_exists_on_branch!(commitish, commitish) if commit_is_ref?(commitish)
  return if commit_exists?(commitish)

  git_in_depth_fetch
  raise_if_we_cannot_find_the_commit(commitish) if commit_not_exists?(commitish)
end

#ensure_commitish_exists_on_branch!(branch, commitish) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/danger/scm_source/git_repo.rb', line 83

def ensure_commitish_exists_on_branch!(branch, commitish)
  return if commit_exists?(commitish)

  depth = 0
  success =
    (3..6).any? do |factor|
      depth += Math.exp(factor).to_i

      git_fetch_branch_to_depth(branch, depth)
      commit_exists?(commitish)
    end

  return if success

  git_in_depth_fetch
  raise_if_we_cannot_find_the_commit(commitish) if commit_not_exists?(commitish)
end

#exec(string) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/danger/scm_source/git_repo.rb', line 53

def exec(string)
  require "open3"
  Dir.chdir(self.folder || ".") do
    git_command = string.split(" ").dup.unshift("git")
    Open3.popen2(default_env, *git_command) do |_stdin, stdout, _wait_thr|
      stdout.read.rstrip
    end
  end
end

#head_commitObject



63
64
65
# File 'lib/danger/scm_source/git_repo.rb', line 63

def head_commit
  exec("rev-parse HEAD")
end

#originsObject



71
72
73
# File 'lib/danger/scm_source/git_repo.rb', line 71

def origins
  exec("remote show origin -n").lines.grep(/Fetch URL/)[0].split(": ", 2)[1].chomp
end

#renamed_filesObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/danger/scm_source/git_repo.rb', line 27

def renamed_files
  # Get raw diff with --find-renames --diff-filter
  # We need to pass --find-renames cause
  # older versions of git don't use this flag as default
  diff = exec(
    "diff #{self.diff.from} #{self.diff.to} --find-renames --diff-filter=R"
  ).lines.map { |line| line.tr("\n", "") }

  before_name_regexp = /^rename from (.*)$/
  after_name_regexp = /^rename to (.*)$/

  # Extract old and new paths via regexp
  diff.each_with_index.map do |line, index|
    before_match = line.match(before_name_regexp)
    next unless before_match

    after_match = diff.fetch(index + 1, "").match(after_name_regexp)
    next unless after_match

    {
      before: before_match.captures.first,
      after: after_match.captures.first
    }
  end.compact
end

#tagsObject



67
68
69
# File 'lib/danger/scm_source/git_repo.rb', line 67

def tags
  exec("tag")
end