Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit bb4290c

Browse files
authored
Remove usage of codeowner-checker from project and pulled in required classes (#11)
1 parent de0cfef commit bb4290c

21 files changed

+1211
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@
1111
- Update to support ruby 3.2 ([#9](https://github.com/cerner/codeowner_validator/pull/9))
1212

1313
# 0.3.1
14-
- Back version of ruby to be in RVM supported set ([#10](https://github.com/cerner/codeowner_validator/pull/10))
14+
- Back version of ruby to be in RVM supported set ([#10](https://github.com/cerner/codeowner_validator/pull/10))
15+
16+
# 0.4.0
17+
- Remove usage of codeowner-checker from project and pulled in required classes ([#11](https://github.com/cerner/codeowner_validator/pull/11))

codeowner_validator.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ Gem::Specification.new do |spec|
3333
# rubocop:enable Gemspec/RequiredRubyVersion
3434

3535
spec.add_dependency 'rainbow', '>= 2.0', '< 4.0.0'
36-
spec.add_dependency 'thor', '>= 0.19'
36+
spec.add_dependency 'thor', '>= 1.0'
3737

3838
spec.add_dependency 'tty-prompt', '~> 0.12'
3939
spec.add_dependency 'tty-spinner', '~> 0.4'
4040
spec.add_dependency 'tty-table', '~> 0.8'
4141

42-
spec.add_dependency 'codeowners-checker', '~> 1.1'
4342
spec.add_dependency 'git', '~> 1.0'
43+
spec.add_dependency 'pathspec', '>= 0.2'
4444
end

lib/codeowner_validator.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
# frozen_string_literal: true
22

33
require 'thor'
4-
require 'codeowners/checker'
5-
# pull in monkeypatch for codeowners-checker
6-
require_relative 'codeowners/checker/group/line'
74
Dir.glob(File.join(File.dirname(__FILE__), 'codeowner_validator', '**/*.rb'), &method(:require))
5+
Dir.glob(File.join(File.dirname(__FILE__), 'codeowners', '**/*.rb'), &method(:require))
86

97
# Public: The code owner validator space is utilized for validations against
108
# the code owner file for a given repository.

lib/codeowner_validator/code_owners.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
require 'pathname'
44
require_relative 'helpers/utility_helper'
55
require 'codeowner_validator/lists/whitelist'
6-
require 'codeowners/checker/group'
7-
require_relative '../codeowners/checker/group/line'
6+
require_relative '../codeowners/checker/group'
87

98
# rubocop:disable Style/ImplicitRuntimeError
109
module CodeownerValidator

lib/codeowner_validator/helpers/utility_helper.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ module UtilityHelper
1313
def in_folder(folder)
1414
raise "The folder location '#{folder}' does not exists" unless File.directory?(folder)
1515

16-
with_clean_env do
16+
if defined?(Bundler)
17+
method = Bundler.respond_to?(:with_unbundled_env) ? :with_unbundled_env : :with_clean_env
18+
Bundler.send(method) do
19+
Dir.chdir folder do
20+
yield
21+
end
22+
end
23+
else
1724
Dir.chdir folder do
1825
yield
1926
end

lib/codeowner_validator/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
module CodeownerValidator
4-
VERSION = '0.3.1'
4+
VERSION = '0.4.0'
55

66
# version module
77
module Version

lib/codeowners/checker/array.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
module Codeowners
4+
class Checker
5+
# Array.delete in contrary to Ruby documentation uses == instead of equal? for comparison.
6+
# safe_delete removes an object from an array comparing objects by equal? method.
7+
module Array
8+
def safe_delete(object)
9+
delete_at(index { |item| item.equal?(object) })
10+
end
11+
end
12+
end
13+
end
14+
15+
Array.prepend(Codeowners::Checker::Array)

lib/codeowners/checker/group.rb

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'line_grouper'
4+
require_relative 'group/line'
5+
require_relative 'array'
6+
7+
module Codeowners
8+
class Checker
9+
# Manage the groups content and handle operations on the groups.
10+
class Group
11+
include Enumerable
12+
13+
attr_accessor :parent
14+
15+
def self.parse(lines)
16+
new.parse(lines)
17+
end
18+
19+
def initialize
20+
@list = []
21+
end
22+
23+
def each(&block)
24+
@list.each do |object|
25+
if object.is_a?(Group)
26+
object.each(&block)
27+
else
28+
yield(object)
29+
end
30+
end
31+
end
32+
33+
def parse(lines)
34+
LineGrouper.call(self, lines)
35+
end
36+
37+
def to_content
38+
@list.flat_map(&:to_content)
39+
end
40+
41+
def to_file
42+
@list.flat_map(&:to_file)
43+
end
44+
45+
# Returns an array of strings representing the structure of the group.
46+
# It indent internal subgroups for readability and debugging purposes.
47+
def to_tree(indentation = '')
48+
@list.each_with_index.flat_map do |item, index|
49+
if indentation.empty?
50+
item.to_tree(indentation + ' ')
51+
elsif index.zero?
52+
item.to_tree(indentation + '+ ')
53+
elsif index == @list.length - 1
54+
item.to_tree(indentation + '\\ ')
55+
else
56+
item.to_tree(indentation + '| ')
57+
end
58+
end
59+
end
60+
# rubocop:enable Metrics/MethodLength
61+
# rubocop:enable Metrics/AbcSize
62+
63+
def owner
64+
owners.first
65+
end
66+
67+
# Owners are ordered by the amount of occurrences
68+
def owners
69+
all_owners.group_by(&:itself).sort_by do |_owner, occurrences|
70+
-occurrences.count
71+
end.map(&:first)
72+
end
73+
74+
def subgroups_owned_by(owner)
75+
@list.flat_map do |item|
76+
next unless item.is_a?(Group)
77+
78+
a = []
79+
a << item if item.owner == owner
80+
a += item.subgroups_owned_by(owner)
81+
a
82+
end.compact
83+
end
84+
85+
def title
86+
@list.first.to_s
87+
end
88+
89+
def create_subgroup
90+
group = self.class.new
91+
group.parent = self
92+
@list << group
93+
group
94+
end
95+
96+
def add(line)
97+
line.parent = self
98+
@list << line
99+
end
100+
101+
def insert(line)
102+
line.parent = self
103+
index = insert_at_index(line)
104+
@list.insert(index, line)
105+
end
106+
107+
def remove(line)
108+
@list.safe_delete(line)
109+
remove! unless any? { |object| object.is_a? Pattern }
110+
end
111+
112+
def remove!
113+
@list.clear
114+
parent&.remove(self)
115+
self.parent = nil
116+
end
117+
118+
def ==(other)
119+
other.is_a?(Group) && other.list == list
120+
end
121+
122+
protected
123+
124+
attr_accessor :list
125+
126+
private
127+
128+
def all_owners
129+
flat_map do |item|
130+
item.owners if item.pattern?
131+
end.compact
132+
end
133+
134+
# rubocop:disable Metrics/AbcSize
135+
def insert_at_index(line)
136+
new_patterns_sorted = @list.grep(Pattern).dup.push(line).sort
137+
previous_line_index = new_patterns_sorted.index { |l| l.equal? line } - 1
138+
previous_line = new_patterns_sorted[previous_line_index]
139+
padding = previous_line.pattern.size + previous_line.whitespace - line.pattern.size
140+
line.whitespace = [1, padding].max
141+
142+
if previous_line_index >= 0
143+
@list.index { |l| l.equal? previous_line } + 1
144+
else
145+
find_last_line_of_initial_comments
146+
end
147+
end
148+
# rubocop:enable Metrics/AbcSize
149+
150+
def find_last_line_of_initial_comments
151+
@list.each_with_index do |item, index|
152+
return index unless item.is_a?(Comment)
153+
end
154+
0
155+
end
156+
end
157+
end
158+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'line'
4+
5+
module Codeowners
6+
class Checker
7+
class Group
8+
# Define and manage comment line.
9+
class Comment < Line
10+
# Matches if the line is a comment.
11+
# @return [Boolean] if the line start with `#`
12+
def self.match?(line)
13+
line.start_with?('#')
14+
end
15+
16+
# Return the comment level if the comment works like a markdown
17+
# headers.
18+
# @return [Integer] with the heading level.
19+
#
20+
# @example
21+
# Comment.new('# First level').level # => 1
22+
# Comment.new('## Second').level # => 2
23+
def level
24+
(@line[/^#+/] || '').size
25+
end
26+
end
27+
end
28+
end
29+
end
30+
31+
require_relative 'group_begin_comment'
32+
require_relative 'group_end_comment'

lib/codeowners/checker/group/empty.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'line'
4+
5+
module Codeowners
6+
class Checker
7+
class Group
8+
# Define line type empty line.
9+
class Empty < Line
10+
def self.match?(line)
11+
line.empty?
12+
end
13+
end
14+
end
15+
end
16+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'comment'
4+
5+
module Codeowners
6+
class Checker
7+
class Group
8+
# Define line type GroupBeginComment which is used for defining the beggining
9+
# of a group.
10+
class GroupBeginComment < Comment
11+
def self.match?(line)
12+
line.lstrip =~ /^#+ BEGIN/
13+
end
14+
end
15+
end
16+
end
17+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'comment'
4+
5+
module Codeowners
6+
class Checker
7+
class Group
8+
# Define line type GroupEndComment which is used for defining the end
9+
# of a group.
10+
class GroupEndComment < Comment
11+
def self.match?(line)
12+
line.lstrip =~ /^#+ END/
13+
end
14+
end
15+
end
16+
end
17+
end

0 commit comments

Comments
 (0)