Module: CodeOwners

Defined in:
lib/code_owners.rb,
lib/code_owners/version.rb

Constant Summary collapse

VERSION =
"1.0.1"

Class Method Summary collapse

Class Method Details

.ownershipsObject

github’s CODEOWNERS rules (help.github.com/articles/about-codeowners/) are allegedly based on the gitignore format. but you can’t tell ls-files to ignore tracked files via an arbitrary pattern file so we need to jump through some hacky git-fu hoops

-c “core.excludesfiles=somefile” -> tells git to use this as our gitignore pattern source check-ignore -> debug gitignore / exclude files –no-index -> don’t look in the index when checking, can be used to debug why a path became tracked -v -> verbose, outputs details about the matching pattern (if any) for each given pathname -n -> non-matching, shows given paths which don’t match any pattern



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/code_owners.rb', line 16

def ownerships
  patterns, owners = pattern_owners.transpose

  raw_git_ownership(patterns).map do |status|
    _, _exfile, line, pattern, file = status.match(/^(.*):(\d*):(.*)\t(.*)$/).to_a
    if line.empty?
      { file: file, owner: "UNOWNED" }
    else
      { file: file, owner: owners[line.to_i - 1], line: line, pattern: pattern }
    end
  end
end

.pattern_ownersObject

read the github file and spit out a slightly formatted list of patterns and their owners



30
31
32
33
34
# File 'lib/code_owners.rb', line 30

def pattern_owners
  File.read(".github/CODEOWNERS").split("\n").map do |line|
    line.gsub(/#.*/, '').gsub(/^$/, " @").split(/\s+@/, 2)
  end
end

.raw_git_ownership(patterns) ⇒ Object

expects an array of gitignore compliant patterns generates a check-ignore formatted string for each file in the repo



38
39
40
41
42
43
44
45
# File 'lib/code_owners.rb', line 38

def raw_git_ownership(patterns)
  Tempfile.open('codeowner_patterns') do |file|
    file.write(patterns.join("\n"))
    file.rewind
    cmd = "git ls-files | xargs -- git -c \"core.excludesfile=#{file.path}\" check-ignore --no-index -v -n"
    `#{cmd}`.lines.map(&:strip)
  end
end