Skip to content

Commit ef269d2

Browse files
committed
feat: check .codeowner within directory if it is provided to for_file
1 parent d06c919 commit ef269d2

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

lib/code_ownership/private/ownership_mappers/directory_ownership.rb

+29-17
Original file line numberDiff line numberDiff line change
@@ -74,36 +74,48 @@ def owner_for_codeowners_file(codeowners_file)
7474
)
7575
end
7676

77-
# takes a file and finds the relevant `.codeowner` file by walking up the directory
77+
# Takes a file and finds the relevant `.codeowner` file by walking up the directory
7878
# structure. Example, given `a/b/c.rb`, this looks for `a/b/.codeowner`, `a/.codeowner`,
7979
# and `.codeowner` in that order, stopping at the first file to actually exist.
80+
# If the parovided file is a directory, it will look for `.codeowner` in that directory.
8081
# We do additional caching so that we don't have to check for file existence every time
8182
sig { params(file: String).returns(T.nilable(CodeTeams::Team)) }
8283
def map_file_to_relevant_owner(file)
8384
file_path = Pathname.new(file)
84-
path_components = file_path.each_filename.to_a.map { |path| Pathname.new(path) }
85+
team = T.let(nil, T.nilable(CodeTeams::Team))
8586

86-
(path_components.length - 1).downto(0).each do |i|
87-
potential_relative_path_name = T.must(path_components[0...i]).reduce(Pathname.new('')) { |built_path, path| built_path.join(path) }
88-
potential_codeowners_file = potential_relative_path_name.join(CODEOWNERS_DIRECTORY_FILE_NAME)
87+
if File.directory?(file)
88+
team = get_team_from_codeowners_file_within_directory(file_path)
89+
return team unless team.nil?
90+
end
91+
92+
while file_path != Pathname('.') && file_path != Pathname('/')
93+
file_path = file_path.parent
94+
team = get_team_from_codeowners_file_within_directory(file_path)
95+
return team unless team.nil?
96+
end
8997

90-
potential_codeowners_file_name = potential_codeowners_file.to_s
98+
nil
99+
end
91100

92-
team = nil
93-
if @@directory_cache.key?(potential_codeowners_file_name)
94-
team = @@directory_cache[potential_codeowners_file_name]
95-
elsif potential_codeowners_file.exist?
96-
team = owner_for_codeowners_file(potential_codeowners_file)
101+
sig { params(directory: Pathname).returns(T.nilable(CodeTeams::Team)) }
102+
def get_team_from_codeowners_file_within_directory(directory)
103+
potential_codeowners_file = directory.join(CODEOWNERS_DIRECTORY_FILE_NAME)
97104

98-
@@directory_cache[potential_codeowners_file_name] = team
99-
else
100-
@@directory_cache[potential_codeowners_file_name] = nil
101-
end
105+
potential_codeowners_file_name = potential_codeowners_file.to_s
102106

103-
return team unless team.nil?
107+
team = nil
108+
if @@directory_cache.key?(potential_codeowners_file_name)
109+
team = @@directory_cache[potential_codeowners_file_name]
110+
elsif potential_codeowners_file.exist?
111+
team = owner_for_codeowners_file(potential_codeowners_file)
112+
113+
@@directory_cache[potential_codeowners_file_name] = team
114+
else
115+
@@directory_cache[potential_codeowners_file_name] = nil
104116
end
105117

106-
nil
118+
return team
107119
end
108120
end
109121
end

spec/lib/code_ownership/private/ownership_mappers/directory_ownership_spec.rb

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ module CodeOwnership
2121
it 'can find the owner of files in a sub-directory of a team-owned directory' do
2222
expect(CodeOwnership.for_file('a/b/c/c_file.jsx').name).to eq 'Bar'
2323
end
24+
25+
it 'looks for codeowner file within directory' do
26+
expect(CodeOwnership.for_file('a/b').name).to eq 'Bar'
27+
end
2428
end
2529
end
2630
end

0 commit comments

Comments
 (0)