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.



7
8
9
# File 'lib/danger/scm_source/git_repo.rb', line 7

def diff
  @diff
end

#folderObject

Returns the value of attribute folder.



7
8
9
# File 'lib/danger/scm_source/git_repo.rb', line 7

def folder
  @folder
end

#logObject

Returns the value of attribute log.



7
8
9
# File 'lib/danger/scm_source/git_repo.rb', line 7

def log
  @log
end

Instance Method Details

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



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

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



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

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



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

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



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

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



61
62
63
# File 'lib/danger/scm_source/git_repo.rb', line 61

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

#originsObject



69
70
71
# File 'lib/danger/scm_source/git_repo.rb', line 69

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

#renamed_filesObject



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

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



65
66
67
# File 'lib/danger/scm_source/git_repo.rb', line 65

def tags
  exec("tag")
end