Skip to content

Commit 467d35d

Browse files
committed
teams_for_file optimization
1 parent c9666a0 commit 467d35d

File tree

8 files changed

+141
-68
lines changed

8 files changed

+141
-68
lines changed

Cargo.lock

Lines changed: 19 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/code_ownership/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ rb-sys = { version = "0.9.111", features = [
1717
magnus = { version = "0.7.1" }
1818
serde = { version = "1.0.219", features = ["derive"] }
1919
serde_magnus = "0.9.0"
20-
codeowners = { git = "https://github.com/rubyatscale/codeowners-rs.git", tag = "v0.2.14" }
20+
# codeowners = { git = "https://github.com/rubyatscale/codeowners-rs.git", tag = "v0.2.14" }
21+
codeowners = { path = "../../../codeowners-rs" }
2122

2223
[dev-dependencies]
2324
rb-sys = { version = "0.9.117", features = [

ext/code_ownership/src/lib.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{env, path::PathBuf};
1+
use std::{collections::HashMap, env, path::PathBuf};
22

33
use codeowners::runner::{self, RunConfig};
44
use magnus::{Error, Ruby, Value, function, prelude::*};
@@ -18,6 +18,30 @@ fn for_team(team_name: String) -> Result<Value, Error> {
1818
validate_result(&team)
1919
}
2020

21+
fn team_names_for_files(file_paths: Vec<String>) -> Result<Value, Error> {
22+
let run_config = build_run_config();
23+
let path_teams = runner::teams_for_files_from_codeowners(&run_config, &file_paths);
24+
match path_teams {
25+
Ok(path_teams) => {
26+
let mut teams_map: HashMap<String, Option<Team>> = HashMap::new();
27+
for (path, team) in path_teams {
28+
if let Some(found_team) = team {
29+
teams_map.insert(path, Some(Team {
30+
team_name: found_team.name.to_string(),
31+
team_config_yml: found_team.name.to_string(),
32+
reasons: vec![],
33+
}));
34+
} else {
35+
teams_map.insert(path, None);
36+
}
37+
}
38+
let serialized: Value = serialize(&teams_map)?;
39+
Ok(serialized)
40+
}
41+
Err(e) => Err(Error::new(magnus::exception::runtime_error(), e.to_string())),
42+
}
43+
}
44+
2145
fn for_file(file_path: String) -> Result<Option<Value>, Error> {
2246
let run_config = build_run_config();
2347

@@ -102,6 +126,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
102126
module.define_singleton_method("validate", function!(validate, 0))?;
103127
module.define_singleton_method("for_team", function!(for_team, 1))?;
104128
module.define_singleton_method("version", function!(version, 0))?;
129+
module.define_singleton_method("team_names_for_files", function!(team_names_for_files, 1))?;
105130

106131
Ok(())
107132
}

lib/code_ownership.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ def for_file(file)
4545
Private::TeamFinder.for_file(file)
4646
end
4747

48+
sig { params(files: T::Array[String]).returns(T::Hash[String, T.nilable(CodeTeams::Team)]) }
49+
def team_names_for_files(files)
50+
::RustCodeOwners.team_names_for_files(files).transform_values do |team|
51+
team ? CodeTeams.find(team[:team_name]) : nil
52+
end
53+
end
54+
4855
sig { params(file: String).returns(T.nilable(T::Hash[Symbol, String])) }
4956
def for_file_verbose(file)
5057
::RustCodeOwners.for_file(file)
@@ -56,9 +63,6 @@ def for_team(team)
5663
::RustCodeOwners.for_team(team.name)
5764
end
5865

59-
class InvalidCodeOwnershipConfigurationError < StandardError
60-
end
61-
6266
sig do
6367
params(
6468
autocorrect: T::Boolean,
529 KB
Binary file not shown.

lib/code_ownership/version.rb

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

33
module CodeOwnership
4-
VERSION = '2.0.0-2'
4+
VERSION = '2.0.0-3'
55
end

sorbet/rbi/manual.rbi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ module RustCodeOwners
1818

1919
def version
2020
end
21+
22+
def team_names_for_files(files)
23+
end
2124
end
2225
end

spec/lib/code_ownership_spec.rb

Lines changed: 83 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,101 @@
55
expect(CodeOwnership::VERSION).not_to be nil
66
end
77

8-
describe '.for_file' do
9-
subject { CodeOwnership.for_file(file_path) }
10-
context 'rust codeowners' do
11-
context 'when config is not found' do
12-
let(:file_path) { 'app/javascript/[test]/test.js' }
13-
it 'raises an error' do
14-
expect { subject }.to raise_error(RuntimeError, /Can't open config file:/)
8+
describe '.team_names_for_files' do
9+
subject { CodeOwnership.team_names_for_files(files) }
10+
let(:files) { ['app/services/my_file.rb'] }
11+
12+
context 'when config is not found' do
13+
let(:files) { ['app/javascript/[test]/test.js'] }
14+
it 'raises an error' do
15+
expect { subject }.to raise_error(RuntimeError, /Can't open config file:/)
16+
end
17+
end
18+
19+
context 'with non-empty application' do
20+
before do
21+
create_non_empty_application
22+
# codeowners-rs is matching files against the codeowners file
23+
::RustCodeOwners.generate_and_validate(false)
24+
end
25+
26+
context 'when no ownership is found' do
27+
let(:files) { ['app/madeup/file.rb'] }
28+
it 'properly assigns ownership' do
29+
expect(subject).to eq({ 'app/madeup/file.rb' => nil })
1530
end
1631
end
1732

18-
context 'with non-empty application' do
33+
context 'when file path starts with ./' do
34+
let(:files) { ['./app/javascript/[test]/test.js'] }
35+
it 'properly assigns ownership' do
36+
expect(subject).to eq({ './app/javascript/[test]/test.js' => nil })
37+
end
38+
end
39+
40+
context 'when ownership is found' do
41+
let(:files) { ['packs/my_pack/owned_file.rb'] }
42+
it 'returns the correct team' do
43+
expect(subject).to eq({ 'packs/my_pack/owned_file.rb' => CodeTeams.find('Bar') })
44+
end
45+
end
46+
47+
context 'when ownership is found but team is not found' do
48+
let(:file_path) { ['packs/my_pack/owned_file.rb'] }
1949
before do
20-
create_non_empty_application
50+
allow(RustCodeOwners).to receive(:team_names_for_files).and_return({ file_path.first => {team_name: 'Made Up Team'} })
51+
end
52+
53+
it 'returns nil' do
54+
expect(subject).to eq({ 'packs/my_pack/owned_file.rb' => nil })
2155
end
56+
end
57+
end
58+
end
59+
60+
describe '.for_file' do
61+
subject { CodeOwnership.for_file(file_path) }
62+
context 'when config is not found' do
63+
let(:file_path) { 'app/javascript/[test]/test.js' }
64+
it 'raises an error' do
65+
expect { subject }.to raise_error(RuntimeError, /Can't open config file:/)
66+
end
67+
end
68+
69+
context 'with non-empty application' do
70+
before do
71+
create_non_empty_application
72+
end
2273

23-
context 'when no ownership is found' do
24-
let(:file_path) { 'app/madeup/file.rb' }
25-
it 'properly assigns ownership' do
26-
expect(subject).to be_nil
27-
end
74+
context 'when no ownership is found' do
75+
let(:file_path) { 'app/madeup/file.rb' }
76+
it 'properly assigns ownership' do
77+
expect(subject).to be_nil
2878
end
79+
end
2980

30-
context 'when file path starts with ./' do
31-
let(:file_path) { './app/javascript/[test]/test.js' }
32-
it 'properly assigns ownership' do
33-
expect(subject).to be_nil
34-
end
81+
context 'when file path starts with ./' do
82+
let(:file_path) { './app/javascript/[test]/test.js' }
83+
it 'properly assigns ownership' do
84+
expect(subject).to be_nil
3585
end
86+
end
3687

37-
context 'when ownership is found' do
38-
let(:file_path) { 'packs/my_pack/owned_file.rb' }
39-
it 'returns the correct team' do
40-
expect(subject).to eq CodeTeams.find('Bar')
41-
end
88+
context 'when ownership is found' do
89+
let(:file_path) { 'packs/my_pack/owned_file.rb' }
90+
it 'returns the correct team' do
91+
expect(subject).to eq CodeTeams.find('Bar')
4292
end
93+
end
4394

44-
context 'when ownership is found but team is not found' do
45-
let(:file_path) { 'packs/my_pack/owned_file.rb' }
46-
before do
47-
allow(RustCodeOwners).to receive(:for_file).and_return({ team_name: 'Made Up Team' })
48-
end
95+
context 'when ownership is found but team is not found' do
96+
let(:file_path) { 'packs/my_pack/owned_file.rb' }
97+
before do
98+
allow(RustCodeOwners).to receive(:for_file).and_return({ team_name: 'Made Up Team' })
99+
end
49100

50-
it 'raises an error' do
51-
expect { subject }.to raise_error(StandardError, /Could not find team with name: `Made Up Team`. Make sure the team is one of/)
52-
end
101+
it 'raises an error' do
102+
expect { subject }.to raise_error(StandardError, /Could not find team with name: `Made Up Team`. Make sure the team is one of/)
53103
end
54104
end
55105
end
@@ -215,7 +265,7 @@
215265

216266
describe '.version' do
217267
it 'returns the version' do
218-
expect(described_class.version).to eq ["code_ownership version: #{CodeOwnership::VERSION}", "codeowners-rs version: #{::RustCodeOwners.version}"]
268+
expect(described_class.version).to eq ["code_ownership version: #{CodeOwnership::VERSION}", "codeowners-rs version: #{RustCodeOwners.version}"]
219269
end
220270
end
221271
end

0 commit comments

Comments
 (0)