Class: Codeowners::Checker

Inherits:
Object
  • Object
show all
Defined in:
lib/codeowners/checker.rb,
lib/codeowners/checker/array.rb,
lib/codeowners/checker/group.rb,
lib/codeowners/checker/version.rb,
lib/codeowners/checker/group/line.rb,
lib/codeowners/checker/code_owners.rb,
lib/codeowners/checker/group/empty.rb,
lib/codeowners/checker/line_grouper.rb,
lib/codeowners/checker/file_as_array.rb,
lib/codeowners/checker/group/comment.rb,
lib/codeowners/checker/group/pattern.rb,
lib/codeowners/checker/group/group_end_comment.rb,
lib/codeowners/checker/group/unrecognized_line.rb,
lib/codeowners/checker/group/group_begin_comment.rb

Overview

Check if code owners are consistent between a git repository and the CODEOWNERS file. It compares what’s being changed in the PR and check if the current files and folders are also being declared in the CODEOWNERS file.

Defined Under Namespace

Modules: Array Classes: CodeOwners, FileAsArray, Group, LineGrouper

Constant Summary collapse

VERSION =
'1.0.0'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo, from, to) ⇒ Checker

Get repo metadata and compare with the owners



18
19
20
21
22
23
# File 'lib/codeowners/checker.rb', line 18

def initialize(repo, from, to)
  @git = Git.open(repo, log: Logger.new(IO::NULL))
  @repo_dir = repo
  @from = from || 'HEAD'
  @to = to
end

Instance Attribute Details

#when_new_fileObject

Returns the value of attribute when_new_file.



15
16
17
# File 'lib/codeowners/checker.rb', line 15

def when_new_file
  @when_new_file
end

#when_useless_patternObject

Returns the value of attribute when_useless_pattern.



15
16
17
# File 'lib/codeowners/checker.rb', line 15

def when_useless_pattern
  @when_useless_pattern
end

Instance Method Details

#added_filesObject



33
34
35
# File 'lib/codeowners/checker.rb', line 33

def added_files
  changes_to_analyze.select { |_k, v| v == 'A' }.keys
end

#changes_for_patterns(patterns) ⇒ Object



44
45
46
# File 'lib/codeowners/checker.rb', line 44

def changes_for_patterns(patterns)
  @git.diff(@from, @to).path(patterns).name_status.keys
end

#changes_to_analyzeObject



29
30
31
# File 'lib/codeowners/checker.rb', line 29

def changes_to_analyze
  @git.diff(@from, @to).name_status
end

#changes_with_ownership(owner = '') ⇒ Object



61
62
63
64
65
66
67
# File 'lib/codeowners/checker.rb', line 61

def changes_with_ownership(owner = '')
  patterns_by_owner.each_with_object({}) do |(own, patterns), changes_with_owners|
    next if (owner != '') && (own != owner)

    changes_with_owners[own] = changes_for_patterns(patterns)
  end
end

#check!Object



37
38
39
40
41
42
# File 'lib/codeowners/checker.rb', line 37

def check!
  {
    missing_ref: missing_reference,
    useless_pattern: useless_pattern
  }
end

#codeownersObject



99
100
101
102
103
104
# File 'lib/codeowners/checker.rb', line 99

def codeowners
  @codeowners ||= CodeOwners.new(
    FileAsArray.new(codeowners_filename),
    transformers: transformers
  )
end

#commit_changes!Object



110
111
112
113
# File 'lib/codeowners/checker.rb', line 110

def commit_changes!
  @git.add(codeowners_filename)
  @git.commit('Fix pattern :robot:')
end

#defined_owner?(file) ⇒ Boolean

Returns:



88
89
90
91
92
93
94
95
96
97
# File 'lib/codeowners/checker.rb', line 88

def defined_owner?(file)
  codeowners.find do |line|
    next unless line.pattern?

    return true if line.match_file?(file)
  end

  @when_new_file&.call(file) if @when_new_file
  false
end

#hash_of_arraysObject



57
58
59
# File 'lib/codeowners/checker.rb', line 57

def hash_of_arrays
  Hash.new { |h, k| h[k] = [] }
end

#main_groupObject



106
107
108
# File 'lib/codeowners/checker.rb', line 106

def main_group
  codeowners.main_group
end

#missing_referenceObject



80
81
82
# File 'lib/codeowners/checker.rb', line 80

def missing_reference
  added_files.reject(&method(:defined_owner?))
end

#pattern_has_files(pattern) ⇒ Object



84
85
86
# File 'lib/codeowners/checker.rb', line 84

def pattern_has_files(pattern)
  @git.ls_files(pattern).any?
end

#patterns_by_ownerObject



48
49
50
51
52
53
54
55
# File 'lib/codeowners/checker.rb', line 48

def patterns_by_owner
  @patterns_by_owner ||=
    codeowners.each_with_object(hash_of_arrays) do |line, patterns_by_owner|
      next unless line.pattern?

      line.owners.each { |owner| patterns_by_owner[owner] << line.pattern }
    end
end

#transformersObject



25
26
27
# File 'lib/codeowners/checker.rb', line 25

def transformers
  @transformers ||= []
end

#useless_patternObject



69
70
71
72
73
74
75
76
77
78
# File 'lib/codeowners/checker.rb', line 69

def useless_pattern
  codeowners.select do |line|
    next unless line.pattern?

    unless pattern_has_files(line.pattern)
      @when_useless_pattern&.call(line)
      true
    end
  end
end