code_ownership 2.1.1 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cargo/config +2 -2
- data/Cargo.lock +9 -2
- data/README.md +8 -8
- data/ext/cargo-vendor/codeowners-0.3.3/.cargo-checksum.json +1 -0
- data/ext/cargo-vendor/codeowners-0.3.3/.github/CODEOWNERS +1 -0
- data/ext/cargo-vendor/codeowners-0.3.3/AGENTS.md +38 -0
- data/ext/cargo-vendor/codeowners-0.3.3/CLAUDE.md +1 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/Cargo.lock +8 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/Cargo.toml +18 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/README.md +11 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/cli.rs +9 -5
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/config.rs +81 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/crosscheck.rs +5 -8
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/codeowners_file_parser.rs +3 -3
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/file_generator.rs +119 -9
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/file_owner_resolver.rs +3 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/package_mapper.rs +2 -2
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper.rs +2 -2
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/validator.rs +84 -17
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership.rs +1 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/project.rs +3 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/project_builder.rs +111 -44
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/runner/api.rs +7 -6
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/runner/types.rs +2 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/runner.rs +67 -16
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/tracked_files.rs +29 -1
- data/ext/cargo-vendor/codeowners-0.3.3/tests/codeowners_path_test.rs +92 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/common/mod.rs +2 -1
- data/ext/cargo-vendor/codeowners-0.3.3/tests/executable_name_config_test.rs +88 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_codeowners_path/config/code_ownership.yml +11 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_codeowners_path/config/teams/test_team.yml +6 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_codeowners_path/docs/CODEOWNERS +14 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_codeowners_path/expected/CODEOWNERS +14 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_codeowners_path/ruby/app/models/test.rb +3 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/.github/CODEOWNERS +10 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/app/foo.rb +3 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/config/code_ownership.yml +4 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/config/teams/foo.yml +5 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/config/teams/payments.yml +6 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/custom_executable_name/ruby/app/payments/foo.rb +4 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/default_executable_name/.github/CODEOWNERS +11 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/default_executable_name/app/bar.rb +3 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/default_executable_name/config/code_ownership.yml +5 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/default_executable_name/config/teams/bar.yml +5 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/missing_github_team/.github/CODEOWNERS +10 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/missing_github_team/config/code_ownership.yml +10 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/missing_github_team/config/teams/bad_team.yml +1 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/missing_github_team/config/teams/good.yml +3 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/fixtures/valid_project/gems/pets/dog.rb +5 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/git_stage_test.rs +4 -1
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/invalid_project_test.rs +30 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/missing_github_team_test.rs +23 -0
- data/ext/cargo-vendor/codeowners-0.3.3/tests/run_config_executable_override_test.rs +98 -0
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/runner_api.rs +8 -4
- data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/valid_project_test.rs +3 -3
- data/ext/cargo-vendor/codeowners-0.3.3/tests/validate_files_test.rs +378 -0
- data/ext/cargo-vendor/similar-2.7.0/.cargo/config.toml +2 -0
- data/ext/cargo-vendor/similar-2.7.0/.cargo-checksum.json +1 -0
- data/ext/cargo-vendor/similar-2.7.0/.cargo_vcs_info.json +6 -0
- data/ext/cargo-vendor/similar-2.7.0/.github/FUNDING.yml +1 -0
- data/ext/cargo-vendor/similar-2.7.0/.github/workflows/clippy.yml +16 -0
- data/ext/cargo-vendor/similar-2.7.0/.github/workflows/rustfmt.yml +16 -0
- data/ext/cargo-vendor/similar-2.7.0/.github/workflows/tests.yml +49 -0
- data/ext/cargo-vendor/similar-2.7.0/.vscode/settings.json +5 -0
- data/ext/cargo-vendor/similar-2.7.0/CHANGELOG.md +132 -0
- data/ext/cargo-vendor/similar-2.7.0/Cargo.lock +373 -0
- data/ext/cargo-vendor/similar-2.7.0/Cargo.lock.msrv +266 -0
- data/ext/cargo-vendor/similar-2.7.0/Cargo.toml +149 -0
- data/ext/cargo-vendor/similar-2.7.0/Cargo.toml.orig +73 -0
- data/ext/cargo-vendor/similar-2.7.0/LICENSE +201 -0
- data/ext/cargo-vendor/similar-2.7.0/Makefile +31 -0
- data/ext/cargo-vendor/similar-2.7.0/README.md +59 -0
- data/ext/cargo-vendor/similar-2.7.0/clippy.toml +1 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/close-matches.rs +15 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/large.rs +8 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/nonstring.rs +13 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/original-slices.rs +11 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/patience.rs +48 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/serde.rs +15 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/terminal-inline.rs +60 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/terminal.rs +20 -0
- data/ext/cargo-vendor/similar-2.7.0/examples/udiff.rs +24 -0
- data/ext/cargo-vendor/similar-2.7.0/scripts/wasmtime-wrapper.sh +4 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/capture.rs +117 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/compact.rs +351 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/hook.rs +178 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/lcs.rs +294 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/mod.rs +134 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/myers.rs +442 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/patience.rs +198 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/replace.rs +221 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping-2.snap +60 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping.snap +64 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__contiguous.snap +28 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__diff.snap +22 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__pat.snap +31 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__same.snap +12 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__contiguous.snap +28 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__deadline_reached.snap +22 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__diff.snap +22 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__pat.snap +31 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience.snap +45 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience_out_of_bounds_bug.snap +16 -0
- data/ext/cargo-vendor/similar-2.7.0/src/algorithms/utils.rs +379 -0
- data/ext/cargo-vendor/similar-2.7.0/src/common.rs +185 -0
- data/ext/cargo-vendor/similar-2.7.0/src/deadline_support.rs +37 -0
- data/ext/cargo-vendor/similar-2.7.0/src/iter.rs +195 -0
- data/ext/cargo-vendor/similar-2.7.0/src/lib.rs +176 -0
- data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff.snap +25 -0
- data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint-2.snap +10 -0
- data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint.snap +11 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/abstraction.rs +446 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/inline.rs +342 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/mod.rs +792 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_ops.snap +22 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_word_ops.snap +202 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__char_diff.snap +39 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__line_ops_inline.snap +126 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__serde.snap +107 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__lifetimes_on_iter.snap +42 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__line_ops.snap +42 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde.snap +55 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde_ops.snap +38 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__unified_diff.snap +12 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__virtual_newlines.snap +32 -0
- data/ext/cargo-vendor/similar-2.7.0/src/text/utils.rs +55 -0
- data/ext/cargo-vendor/similar-2.7.0/src/types.rs +502 -0
- data/ext/cargo-vendor/similar-2.7.0/src/udiff.rs +359 -0
- data/ext/cargo-vendor/similar-2.7.0/src/utils.rs +412 -0
- data/ext/cargo-vendor/unicode-ident-1.0.19/.cargo-checksum.json +1 -1
- data/ext/code_ownership/Cargo.toml +1 -1
- data/ext/code_ownership/src/lib.rs +2 -2
- data/lib/code_ownership/private/file_path_finder.rb +19 -3
- data/lib/code_ownership/private/team_finder.rb +1 -2
- data/lib/code_ownership/version.rb +1 -1
- data/lib/code_ownership.rb +2 -0
- metadata +252 -152
- data/ext/cargo-vendor/codeowners-0.3.0/.cargo-checksum.json +0 -1
- data/ext/cargo-vendor/codeowners-0.3.0/tests/validate_files_test.rs +0 -144
- data/ext/cargo-vendor/unicode-ident-1.0.19/tests/fst/.gitignore +0 -1
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/.github/workflows/audit.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/.github/workflows/ci.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/.github/workflows/dotslash-config.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/.rustfmt.toml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/.rusty-hook.toml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/dev/run_benchmarks_for_file.sh +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/dev/run_benchmarks_for_gv.sh +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/rust-toolchain.toml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/cache/file.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/cache/mod.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/cache/noop.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/common_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/lib.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/main.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/codeowners_query.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/file_owner_finder.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/annotated_file_mapper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/directory_mapper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/escaper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/team_gem_mapper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/team_glob_mapper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/team_yml_mapper.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/path_utils.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/project_file_builder.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/cache_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/crosscheck_owners_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/.github/CODEOWNERS +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/code_ownership.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payments.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payroll.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/gems/payroll_calculator/calculator.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/bank_account.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/blockchain.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/payroll.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/payments/nacha.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/multi_owned.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/unowned.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/packages/payroll_flow/package.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.github/CODEOWNERS +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.keep +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/code_ownership.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/design.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/frontend.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/apps/public/index.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/package.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/src/index.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/src/button.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0/tests/fixtures/valid_project → codeowners-0.3.3/tests/fixtures/missing_github_team}/gems/pets/dog.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/.github/CODEOWNERS +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/deep/nesting/nestdir/deep_file.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/one_owner.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/some_other_file.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/code_ownership.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/bar.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/foo.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/.github/CODEOWNERS +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/.ignore +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/config/code_ownership.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payments.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payroll.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/ux.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/gems/payroll_calculator/calculator.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/index.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/package.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/pay.ts +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/item.ts +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/list/page-admin.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/bank_account.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/payroll.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/ownedby_payroll.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/nacha.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/payroll.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/edit.erb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/index.html.erb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/new.html.erb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/ignored_files/git_ignored.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/packages/payroll_flow/package.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project/should_be_ignored/an_ignored_file.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/.github/CODEOWNERS +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/code_ownership.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/brewers.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/cubs.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/giants.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/rockies.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/package.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/src/picks/dp.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/package.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/src/item.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/package.json +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/field.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/fields/small.tsx +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/apollo/lib/apollo.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/ivy/lib/ivy.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/lager/lib/lager.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/summit/lib/summit.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/app/services/stats.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/package.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/app/services/capacity.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/package.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/app/services/date.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/package.yml +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/lib/util.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/services/play.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/.codeowner +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/db/price.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/entertainment.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/play.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/giants/services/play.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/rockies/services/play.rb +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/invalid_project_structure_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/multiple_directory_owners_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/untracked_files_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tests/valid_project_with_overrides_test.rs +0 -0
- /data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/tmp/.gitkeep +0 -0
|
@@ -49,17 +49,37 @@ impl FileGenerator {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
pub fn compare_lines(a: &String, b: &String) -> Ordering {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
let path_a = extract_path(a);
|
|
53
|
+
let path_b = extract_path(b);
|
|
54
|
+
|
|
55
|
+
let mut comps_a = path_a.split('/');
|
|
56
|
+
let mut comps_b = path_b.split('/');
|
|
57
|
+
|
|
58
|
+
loop {
|
|
59
|
+
match (comps_a.next(), comps_b.next()) {
|
|
60
|
+
(None, None) => return a.cmp(b),
|
|
61
|
+
(None, Some(_)) => return Ordering::Less,
|
|
62
|
+
(Some(_), None) => return Ordering::Greater,
|
|
63
|
+
(Some(ca), Some(cb)) => match compare_component(ca, cb) {
|
|
64
|
+
Ordering::Equal => continue,
|
|
65
|
+
ord => return ord,
|
|
66
|
+
},
|
|
67
|
+
}
|
|
56
68
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn extract_path(line: &str) -> &str {
|
|
72
|
+
let stripped = line.strip_prefix("# ").unwrap_or(line);
|
|
73
|
+
stripped.split_once(' ').map(|(p, _)| p).unwrap_or(stripped)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fn compare_component(a: &str, b: &str) -> Ordering {
|
|
77
|
+
match (a == "**", b == "**") {
|
|
78
|
+
(true, true) => Ordering::Equal,
|
|
79
|
+
(true, false) => Ordering::Less,
|
|
80
|
+
(false, true) => Ordering::Greater,
|
|
81
|
+
(false, false) => a.cmp(b),
|
|
61
82
|
}
|
|
62
|
-
a.cmp(b)
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
#[cfg(test)]
|
|
@@ -181,6 +201,96 @@ mod tests {
|
|
|
181
201
|
assert_eq!(sorted, vec!["/directory/owner1/** @foo", "/directory/owner2/** @bar"]);
|
|
182
202
|
}
|
|
183
203
|
|
|
204
|
+
#[test]
|
|
205
|
+
fn test_compare_lines_is_antisymmetric_for_shared_double_star_prefix() {
|
|
206
|
+
let a = "/foo/**/*bar* @org/example-team".to_string();
|
|
207
|
+
let b = "/foo/**/baz/**/* @org/example-team".to_string();
|
|
208
|
+
|
|
209
|
+
assert_eq!(compare_lines(&a, &b), Ordering::Less);
|
|
210
|
+
assert_eq!(compare_lines(&b, &a), Ordering::Greater);
|
|
211
|
+
|
|
212
|
+
let mut forward = vec![a.clone(), b.clone()];
|
|
213
|
+
let mut reverse = vec![b.clone(), a.clone()];
|
|
214
|
+
forward.sort_by(compare_lines);
|
|
215
|
+
reverse.sort_by(compare_lines);
|
|
216
|
+
assert_eq!(forward, reverse);
|
|
217
|
+
assert_eq!(forward, vec![a, b]);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
fn special_character_set() -> Vec<String> {
|
|
221
|
+
vec![
|
|
222
|
+
"/directory/** @bop".to_string(),
|
|
223
|
+
"/directory/owner/** @bar".to_string(),
|
|
224
|
+
"/directory/owner/(my_folder)/**/** @foo".to_string(),
|
|
225
|
+
"/directory/owner/(my_folder)/without_glob @zoo".to_string(),
|
|
226
|
+
"/directory/owner/my_folder/** @baz".to_string(),
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
#[test]
|
|
231
|
+
fn test_compare_lines_is_antisymmetric_across_special_character_set() {
|
|
232
|
+
let lines = special_character_set();
|
|
233
|
+
for x in &lines {
|
|
234
|
+
assert_eq!(compare_lines(x, x), Ordering::Equal);
|
|
235
|
+
for y in &lines {
|
|
236
|
+
if x == y {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
let xy = compare_lines(x, y);
|
|
240
|
+
let yx = compare_lines(y, x);
|
|
241
|
+
assert_eq!(xy.reverse(), yx, "asymmetric for {x:?} vs {y:?}");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#[test]
|
|
247
|
+
fn test_compare_lines_is_transitive_across_special_character_set() {
|
|
248
|
+
let lines = special_character_set();
|
|
249
|
+
for x in &lines {
|
|
250
|
+
for y in &lines {
|
|
251
|
+
for z in &lines {
|
|
252
|
+
let xy = compare_lines(x, y);
|
|
253
|
+
let yz = compare_lines(y, z);
|
|
254
|
+
let xz = compare_lines(x, z);
|
|
255
|
+
if xy != Ordering::Greater && yz != Ordering::Greater {
|
|
256
|
+
assert_ne!(xz, Ordering::Greater, "transitivity broken: {x:?} <= {y:?} <= {z:?} but x > z");
|
|
257
|
+
}
|
|
258
|
+
if xy != Ordering::Less && yz != Ordering::Less {
|
|
259
|
+
assert_ne!(xz, Ordering::Less, "transitivity broken: {x:?} >= {y:?} >= {z:?} but x < z");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
#[test]
|
|
267
|
+
fn test_compare_lines_orders_shorter_path_before_longer_extension() {
|
|
268
|
+
let shorter = "/foo @a".to_string();
|
|
269
|
+
let longer = "/foo/bar @b".to_string();
|
|
270
|
+
|
|
271
|
+
assert_eq!(compare_lines(&shorter, &longer), Ordering::Less);
|
|
272
|
+
assert_eq!(compare_lines(&longer, &shorter), Ordering::Greater);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
#[test]
|
|
276
|
+
fn test_compare_lines_falls_back_to_full_line_when_paths_equal() {
|
|
277
|
+
let a = "/foo/** @a".to_string();
|
|
278
|
+
let b = "/foo/** @b".to_string();
|
|
279
|
+
|
|
280
|
+
assert_eq!(compare_lines(&a, &b), Ordering::Less);
|
|
281
|
+
assert_eq!(compare_lines(&b, &a), Ordering::Greater);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#[test]
|
|
285
|
+
fn test_compare_lines_ignores_disabled_comment_prefix() {
|
|
286
|
+
let enabled = "/foo/owner/** @bar".to_string();
|
|
287
|
+
let disabled = "# /foo/owner/** @bar".to_string();
|
|
288
|
+
let other = "/foo/owner/(extra)/file @baz".to_string();
|
|
289
|
+
|
|
290
|
+
assert_eq!(compare_lines(&enabled, &other), compare_lines(&disabled, &other));
|
|
291
|
+
assert_eq!(compare_lines(&other, &enabled), compare_lines(&other, &disabled));
|
|
292
|
+
}
|
|
293
|
+
|
|
184
294
|
#[test]
|
|
185
295
|
fn test_sorting_with_special_characters() {
|
|
186
296
|
let entries = vec![
|
data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/file_owner_resolver.rs
RENAMED
|
@@ -116,7 +116,7 @@ fn load_teams(project_root: &Path, team_file_globs: &[String]) -> std::result::R
|
|
|
116
116
|
match Team::from_team_file_path(path.clone()) {
|
|
117
117
|
Ok(team) => teams.push(team),
|
|
118
118
|
Err(e) => {
|
|
119
|
-
eprintln!("Error parsing team file: {}, path: {}",
|
|
119
|
+
eprintln!("Error parsing team file: {e:?}, path: {}", path.display());
|
|
120
120
|
continue;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -293,6 +293,8 @@ mod tests {
|
|
|
293
293
|
vendored_gems_path: vendored_path.to_string(),
|
|
294
294
|
cache_directory: "tmp/cache/codeowners".to_string(),
|
|
295
295
|
ignore_dirs: vec![],
|
|
296
|
+
executable_name: "codeowners".to_string(),
|
|
297
|
+
codeowners_path: ".github".to_string(),
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
|
data/ext/cargo-vendor/{codeowners-0.3.0 → codeowners-0.3.3}/src/ownership/mapper/package_mapper.rs
RENAMED
|
@@ -95,7 +95,7 @@ impl PackageMapper {
|
|
|
95
95
|
let packages: Vec<&Package> = packages.iter().filter(|package| &package.package_type == package_type).collect();
|
|
96
96
|
|
|
97
97
|
// Nested packs can create a duplicate ownership false positive.
|
|
98
|
-
// We avoid it by treating nested packs as a single top
|
|
98
|
+
// We avoid it by treating nested packs as a single top-level pack for the purposes of validation.
|
|
99
99
|
let packages = remove_nested_packages(&packages);
|
|
100
100
|
|
|
101
101
|
for package in packages {
|
|
@@ -147,7 +147,7 @@ mod tests {
|
|
|
147
147
|
use std::{error::Error, path::Path};
|
|
148
148
|
#[test]
|
|
149
149
|
fn test_remove_nested_packages() {
|
|
150
|
-
let packages =
|
|
150
|
+
let packages = [
|
|
151
151
|
Package {
|
|
152
152
|
path: Path::new("packs/a/package.yml").to_owned(),
|
|
153
153
|
package_type: PackageType::Ruby,
|
|
@@ -48,7 +48,7 @@ impl Display for Source {
|
|
|
48
48
|
Source::TeamGem => write!(f, "Owner specified in Team YML's `owned_gems`"),
|
|
49
49
|
Source::TeamGlob(glob) => write!(f, "Owner specified in Team YML as an owned_glob `{}`", glob),
|
|
50
50
|
Source::Package(package_path, glob) => {
|
|
51
|
-
write!(f, "Owner defined in `{}` with
|
|
51
|
+
write!(f, "Owner defined in `{}` with implicitly owned glob: `{}`", package_path, glob)
|
|
52
52
|
}
|
|
53
53
|
Source::TeamYml => write!(f, "Teams own their configuration files"),
|
|
54
54
|
}
|
|
@@ -208,7 +208,7 @@ mod tests {
|
|
|
208
208
|
);
|
|
209
209
|
assert_eq!(
|
|
210
210
|
Source::Package("packs/bam/packag.yml".to_string(), "packs/bam/**/**".to_string()).to_string(),
|
|
211
|
-
"Owner defined in `packs/bam/packag.yml` with
|
|
211
|
+
"Owner defined in `packs/bam/packag.yml` with implicitly owned glob: `packs/bam/**/**`"
|
|
212
212
|
);
|
|
213
213
|
assert_eq!(Source::TeamYml.to_string(), "Teams own their configuration files");
|
|
214
214
|
}
|
|
@@ -9,6 +9,7 @@ use error_stack::Context;
|
|
|
9
9
|
use itertools::Itertools;
|
|
10
10
|
use rayon::prelude::IntoParallelRefIterator;
|
|
11
11
|
use rayon::prelude::ParallelIterator;
|
|
12
|
+
use similar::{ChangeTag, TextDiff};
|
|
12
13
|
use tracing::debug;
|
|
13
14
|
use tracing::instrument;
|
|
14
15
|
|
|
@@ -21,6 +22,7 @@ pub struct Validator {
|
|
|
21
22
|
pub project: Arc<Project>,
|
|
22
23
|
pub mappers: Vec<Box<dyn Mapper>>,
|
|
23
24
|
pub file_generator: FileGenerator,
|
|
25
|
+
pub executable_name: String,
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
#[derive(Debug)]
|
|
@@ -28,7 +30,7 @@ enum Error {
|
|
|
28
30
|
InvalidTeam { name: String, path: PathBuf },
|
|
29
31
|
FileWithoutOwner { path: PathBuf },
|
|
30
32
|
FileWithMultipleOwners { path: PathBuf, owners: Vec<Owner> },
|
|
31
|
-
CodeownershipFileIsStale,
|
|
33
|
+
CodeownershipFileIsStale { executable_name: String, diff: String },
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
#[derive(Debug)]
|
|
@@ -126,16 +128,15 @@ impl Validator {
|
|
|
126
128
|
|
|
127
129
|
fn validate_codeowners_file(&self) -> Vec<Error> {
|
|
128
130
|
let generated_file = self.file_generator.generate_file();
|
|
131
|
+
let current_file = self.project.get_codeowners_file().unwrap_or_default();
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
Err(_) => vec![Error::CodeownershipFileIsStale], // Treat any read error as stale file
|
|
133
|
+
if generated_file == current_file {
|
|
134
|
+
vec![]
|
|
135
|
+
} else {
|
|
136
|
+
vec![Error::CodeownershipFileIsStale {
|
|
137
|
+
executable_name: self.executable_name.to_string(),
|
|
138
|
+
diff: codeowners_diff(¤t_file, &generated_file),
|
|
139
|
+
}]
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
|
|
@@ -158,16 +159,36 @@ impl Validator {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
|
|
162
|
+
/// Builds a line-oriented diff between the current (on-disk) CODEOWNERS file and the
|
|
163
|
+
/// freshly generated one, so that validation failures explain *what* is out of date
|
|
164
|
+
/// rather than just *that* it is. Only changed lines are emitted: removals (present
|
|
165
|
+
/// on disk but no longer expected) are prefixed with `-` and additions (expected but
|
|
166
|
+
/// missing) are prefixed with `+`.
|
|
167
|
+
fn codeowners_diff(current: &str, generated: &str) -> String {
|
|
168
|
+
let diff = TextDiff::from_lines(current, generated);
|
|
169
|
+
|
|
170
|
+
diff.iter_all_changes()
|
|
171
|
+
.filter_map(|change| {
|
|
172
|
+
let line = change.value().trim_end_matches('\n');
|
|
173
|
+
match change.tag() {
|
|
174
|
+
ChangeTag::Delete => Some(format!("-{line}")),
|
|
175
|
+
ChangeTag::Insert => Some(format!("+{line}")),
|
|
176
|
+
ChangeTag::Equal => None,
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
.join("\n")
|
|
180
|
+
}
|
|
181
|
+
|
|
161
182
|
impl Error {
|
|
162
183
|
pub fn category(&self) -> String {
|
|
163
184
|
match self {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
185
|
+
Error::FileWithoutOwner { path: _ } => "Some files are missing ownership".to_owned(),
|
|
186
|
+
Error::FileWithMultipleOwners { path: _, owners: _ } => "Code ownership should only be defined for each file in one way. The following files have declared ownership in multiple ways".to_owned(),
|
|
187
|
+
Error::CodeownershipFileIsStale { executable_name, diff: _ } => {
|
|
188
|
+
format!("CODEOWNERS out of date. Run `{}` to update the CODEOWNERS file", executable_name)
|
|
189
|
+
}
|
|
190
|
+
Error::InvalidTeam { name: _, path: _ } => "Found invalid team annotations".to_owned(),
|
|
168
191
|
}
|
|
169
|
-
Error::InvalidTeam { name: _, path: _ } => "Found invalid team annotations".to_owned(),
|
|
170
|
-
}
|
|
171
192
|
}
|
|
172
193
|
|
|
173
194
|
pub fn messages(&self) -> Vec<String> {
|
|
@@ -187,7 +208,13 @@ impl Error {
|
|
|
187
208
|
|
|
188
209
|
vec![messages.join("\n")]
|
|
189
210
|
}
|
|
190
|
-
Error::CodeownershipFileIsStale =>
|
|
211
|
+
Error::CodeownershipFileIsStale { executable_name: _, diff } => {
|
|
212
|
+
if diff.is_empty() {
|
|
213
|
+
vec![]
|
|
214
|
+
} else {
|
|
215
|
+
vec![format!("The following changes are required (- current, + expected):\n{diff}")]
|
|
216
|
+
}
|
|
217
|
+
}
|
|
191
218
|
Error::InvalidTeam { name, path } => vec![format!("- {} is referencing an invalid team - '{}'", path.to_string_lossy(), name)],
|
|
192
219
|
}
|
|
193
220
|
}
|
|
@@ -216,3 +243,43 @@ impl Display for Errors {
|
|
|
216
243
|
}
|
|
217
244
|
|
|
218
245
|
impl Context for Errors {}
|
|
246
|
+
|
|
247
|
+
#[cfg(test)]
|
|
248
|
+
mod tests {
|
|
249
|
+
use super::*;
|
|
250
|
+
use indoc::indoc;
|
|
251
|
+
|
|
252
|
+
#[test]
|
|
253
|
+
fn test_codeowners_diff_reports_added_and_removed_lines() {
|
|
254
|
+
let current = indoc! {"
|
|
255
|
+
# Team A
|
|
256
|
+
/app/a.rb @TeamA
|
|
257
|
+
/app/old.rb @TeamA
|
|
258
|
+
"};
|
|
259
|
+
let generated = indoc! {"
|
|
260
|
+
# Team A
|
|
261
|
+
/app/a.rb @TeamA
|
|
262
|
+
/app/b.rb @TeamB
|
|
263
|
+
"};
|
|
264
|
+
|
|
265
|
+
let diff = codeowners_diff(current, generated);
|
|
266
|
+
|
|
267
|
+
assert_eq!(diff, "-/app/old.rb @TeamA\n+/app/b.rb @TeamB");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#[test]
|
|
271
|
+
fn test_codeowners_diff_against_empty_file_is_all_additions() {
|
|
272
|
+
let generated = "# Team A\n/app/a.rb @TeamA\n";
|
|
273
|
+
|
|
274
|
+
let diff = codeowners_diff("", generated);
|
|
275
|
+
|
|
276
|
+
assert_eq!(diff, "+# Team A\n+/app/a.rb @TeamA");
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
#[test]
|
|
280
|
+
fn test_codeowners_diff_is_empty_when_identical() {
|
|
281
|
+
let file = "# Team A\n/app/a.rb @TeamA\n";
|
|
282
|
+
|
|
283
|
+
assert_eq!(codeowners_diff(file, file), "");
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -17,6 +17,7 @@ pub struct Project {
|
|
|
17
17
|
pub codeowners_file_path: PathBuf,
|
|
18
18
|
pub directory_codeowner_files: Vec<DirectoryCodeownersFile>,
|
|
19
19
|
pub teams_by_name: HashMap<String, Team>,
|
|
20
|
+
pub executable_name: String,
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
#[derive(Clone, Debug)]
|
|
@@ -111,6 +112,7 @@ pub mod deserializers {
|
|
|
111
112
|
#[derive(Deserialize)]
|
|
112
113
|
pub struct RubyPackage {
|
|
113
114
|
pub owner: Option<String>,
|
|
115
|
+
pub metadata: Option<Metadata>,
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
#[derive(Deserialize)]
|
|
@@ -219,6 +221,7 @@ mod tests {
|
|
|
219
221
|
codeowners_file_path: PathBuf::from(".github/CODEOWNERS"),
|
|
220
222
|
directory_codeowner_files: vec![],
|
|
221
223
|
teams_by_name: HashMap::new(),
|
|
224
|
+
executable_name: "codeowners generate".to_string(),
|
|
222
225
|
};
|
|
223
226
|
|
|
224
227
|
let map = project.vendored_gem_by_name();
|
|
@@ -8,7 +8,7 @@ use error_stack::{Report, Result, ResultExt};
|
|
|
8
8
|
use fast_glob::glob_match;
|
|
9
9
|
use ignore::{DirEntry, WalkBuilder, WalkParallel, WalkState};
|
|
10
10
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
|
11
|
-
use tracing::
|
|
11
|
+
use tracing::instrument;
|
|
12
12
|
|
|
13
13
|
use crate::{
|
|
14
14
|
cache::Cache,
|
|
@@ -178,9 +178,17 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
fn build_project_from_entry_types(&mut self, entry_types: Vec<EntryType>) -> Result<Project, Error> {
|
|
181
|
-
|
|
181
|
+
type Accumulator = (
|
|
182
|
+
Vec<ProjectFile>,
|
|
183
|
+
Vec<Package>,
|
|
184
|
+
Vec<VendoredGem>,
|
|
185
|
+
Vec<DirectoryCodeownersFile>,
|
|
186
|
+
Vec<Team>,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
let (project_files, packages, vendored_gems, directory_codeowners, teams): Accumulator = entry_types
|
|
182
190
|
.into_par_iter()
|
|
183
|
-
.
|
|
191
|
+
.try_fold(
|
|
184
192
|
|| {
|
|
185
193
|
(
|
|
186
194
|
Vec::<ProjectFile>::with_capacity(INITIAL_VECTOR_CAPACITY),
|
|
@@ -197,18 +205,20 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
197
205
|
}
|
|
198
206
|
EntryType::Directory(absolute_path, relative_path) => {
|
|
199
207
|
if relative_path.parent() == Some(Path::new(&self.config.vendored_gems_path)) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
path:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
+
let file_name = relative_path.file_name().ok_or_else(|| {
|
|
209
|
+
error_stack::report!(Error::Io)
|
|
210
|
+
.attach_printable(format!("Vendored gem path has no file name: {}", relative_path.display()))
|
|
211
|
+
})?;
|
|
212
|
+
gems.push(VendoredGem {
|
|
213
|
+
path: absolute_path,
|
|
214
|
+
name: file_name.to_string_lossy().to_string(),
|
|
215
|
+
});
|
|
208
216
|
}
|
|
209
217
|
}
|
|
210
218
|
EntryType::RubyPackage(absolute_path, relative_path) => {
|
|
211
|
-
match ruby_package_owner(&absolute_path)
|
|
219
|
+
match ruby_package_owner(&absolute_path)
|
|
220
|
+
.attach_printable_lazy(|| format!("Failed to read ruby package: {}", absolute_path.display()))
|
|
221
|
+
{
|
|
212
222
|
Ok(Some(owner)) => {
|
|
213
223
|
pkgs.push(Package {
|
|
214
224
|
path: relative_path.clone(),
|
|
@@ -217,13 +227,13 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
217
227
|
});
|
|
218
228
|
}
|
|
219
229
|
Ok(None) => { /* No owner, do nothing */ }
|
|
220
|
-
Err(e) =>
|
|
221
|
-
warn!("Error reading ruby package owner for {:?}: {:?}", absolute_path, e);
|
|
222
|
-
}
|
|
230
|
+
Err(e) => return Err(e),
|
|
223
231
|
}
|
|
224
232
|
}
|
|
225
233
|
EntryType::JavascriptPackage(absolute_path, relative_path) => {
|
|
226
|
-
match javascript_package_owner(&absolute_path)
|
|
234
|
+
match javascript_package_owner(&absolute_path)
|
|
235
|
+
.attach_printable_lazy(|| format!("Failed to read javascript package: {}", absolute_path.display()))
|
|
236
|
+
{
|
|
227
237
|
Ok(Some(owner)) => {
|
|
228
238
|
pkgs.push(Package {
|
|
229
239
|
path: relative_path.clone(),
|
|
@@ -232,37 +242,31 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
232
242
|
});
|
|
233
243
|
}
|
|
234
244
|
Ok(None) => { /* No owner, do nothing */ }
|
|
235
|
-
Err(e) =>
|
|
236
|
-
warn!("Error reading javascript package owner for {:?}: {:?}", absolute_path, e);
|
|
237
|
-
}
|
|
245
|
+
Err(e) => return Err(e),
|
|
238
246
|
}
|
|
239
247
|
}
|
|
240
|
-
EntryType::CodeownerFile(absolute_path, relative_path) =>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
Err(e) => {
|
|
257
|
-
warn!("Error building team from team file path: {}", e);
|
|
258
|
-
}
|
|
259
|
-
},
|
|
248
|
+
EntryType::CodeownerFile(absolute_path, relative_path) => {
|
|
249
|
+
let owner = std::fs::read_to_string(&absolute_path)
|
|
250
|
+
.change_context(Error::Io)
|
|
251
|
+
.attach_printable_lazy(|| format!("Failed to read codeowner file: {}", absolute_path.display()))?;
|
|
252
|
+
let owner = owner.trim().to_owned();
|
|
253
|
+
codeowners.push(DirectoryCodeownersFile {
|
|
254
|
+
path: relative_path.clone(),
|
|
255
|
+
owner,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
EntryType::TeamFile(absolute_path, _relative_path) => {
|
|
259
|
+
let team = Team::from_team_file_path(absolute_path.clone())
|
|
260
|
+
.change_context(Error::Io)
|
|
261
|
+
.attach_printable_lazy(|| format!("Failed to read team file: {}", absolute_path.display()))?;
|
|
262
|
+
team_files.push(team);
|
|
263
|
+
}
|
|
260
264
|
EntryType::NullEntry() => {}
|
|
261
265
|
}
|
|
262
|
-
(project_files, pkgs, gems, codeowners, team_files)
|
|
266
|
+
Ok((project_files, pkgs, gems, codeowners, team_files))
|
|
263
267
|
},
|
|
264
268
|
)
|
|
265
|
-
.
|
|
269
|
+
.try_reduce(
|
|
266
270
|
|| (Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new()),
|
|
267
271
|
|mut acc, item| {
|
|
268
272
|
acc.0.extend(item.0);
|
|
@@ -270,9 +274,9 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
270
274
|
acc.2.extend(item.2);
|
|
271
275
|
acc.3.extend(item.3);
|
|
272
276
|
acc.4.extend(item.4);
|
|
273
|
-
acc
|
|
277
|
+
Ok(acc)
|
|
274
278
|
},
|
|
275
|
-
)
|
|
279
|
+
)?;
|
|
276
280
|
let teams_by_name = teams
|
|
277
281
|
.iter()
|
|
278
282
|
.flat_map(|team| vec![(team.name.clone(), team.clone()), (team.github_team.clone(), team.clone())])
|
|
@@ -294,6 +298,7 @@ impl<'a> ProjectBuilder<'a> {
|
|
|
294
298
|
codeowners_file_path: self.codeowners_file_path.to_path_buf(),
|
|
295
299
|
directory_codeowner_files: directory_codeowners,
|
|
296
300
|
teams_by_name,
|
|
301
|
+
executable_name: self.config.executable_name.clone(),
|
|
297
302
|
})
|
|
298
303
|
}
|
|
299
304
|
}
|
|
@@ -309,7 +314,19 @@ fn ruby_package_owner(path: &Path) -> Result<Option<String>, Error> {
|
|
|
309
314
|
let file = File::open(path).change_context(Error::Io)?;
|
|
310
315
|
let deserializer: deserializers::RubyPackage = serde_yaml::from_reader(file).change_context(Error::SerdeYaml)?;
|
|
311
316
|
|
|
312
|
-
|
|
317
|
+
let top_level_owner = deserializer.owner;
|
|
318
|
+
let metadata_owner = deserializer.metadata.and_then(|metadata| metadata.owner);
|
|
319
|
+
|
|
320
|
+
// Error if both are present with different values
|
|
321
|
+
match (top_level_owner.as_ref(), metadata_owner.as_ref()) {
|
|
322
|
+
(Some(top), Some(meta)) if top != meta => Err(error_stack::report!(Error::Io).attach_printable(format!(
|
|
323
|
+
"Package at {} has conflicting owners: 'owner: {}' vs 'metadata.owner: {}'. Please use only one.",
|
|
324
|
+
path.display(),
|
|
325
|
+
top,
|
|
326
|
+
meta
|
|
327
|
+
))),
|
|
328
|
+
_ => Ok(top_level_owner.or(metadata_owner)),
|
|
329
|
+
}
|
|
313
330
|
}
|
|
314
331
|
|
|
315
332
|
fn javascript_package_owner(path: &Path) -> Result<Option<String>, Error> {
|
|
@@ -334,4 +351,54 @@ mod tests {
|
|
|
334
351
|
fn test_glob_match() {
|
|
335
352
|
assert!(glob_match(OWNED_GLOB, "script/.eslintrc.js"));
|
|
336
353
|
}
|
|
354
|
+
|
|
355
|
+
#[test]
|
|
356
|
+
fn test_ruby_package_owner_top_level() {
|
|
357
|
+
let yaml = "owner: TeamA\n";
|
|
358
|
+
let temp_file = tempfile::NamedTempFile::new().unwrap();
|
|
359
|
+
std::fs::write(temp_file.path(), yaml).unwrap();
|
|
360
|
+
|
|
361
|
+
let owner = ruby_package_owner(temp_file.path()).unwrap();
|
|
362
|
+
assert_eq!(owner, Some("TeamA".to_string()));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#[test]
|
|
366
|
+
fn test_ruby_package_owner_metadata() {
|
|
367
|
+
let yaml = "metadata:\n owner: TeamB\n";
|
|
368
|
+
let temp_file = tempfile::NamedTempFile::new().unwrap();
|
|
369
|
+
std::fs::write(temp_file.path(), yaml).unwrap();
|
|
370
|
+
|
|
371
|
+
let owner = ruby_package_owner(temp_file.path()).unwrap();
|
|
372
|
+
assert_eq!(owner, Some("TeamB".to_string()));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
#[test]
|
|
376
|
+
fn test_ruby_package_owner_errors_when_both_present_and_different() {
|
|
377
|
+
let yaml = "owner: TeamA\nmetadata:\n owner: TeamB\n";
|
|
378
|
+
let temp_file = tempfile::NamedTempFile::new().unwrap();
|
|
379
|
+
std::fs::write(temp_file.path(), yaml).unwrap();
|
|
380
|
+
|
|
381
|
+
let result = ruby_package_owner(temp_file.path());
|
|
382
|
+
assert!(result.is_err());
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
#[test]
|
|
386
|
+
fn test_ruby_package_owner_allows_both_when_same() {
|
|
387
|
+
let yaml = "owner: TeamA\nmetadata:\n owner: TeamA\n";
|
|
388
|
+
let temp_file = tempfile::NamedTempFile::new().unwrap();
|
|
389
|
+
std::fs::write(temp_file.path(), yaml).unwrap();
|
|
390
|
+
|
|
391
|
+
let owner = ruby_package_owner(temp_file.path()).unwrap();
|
|
392
|
+
assert_eq!(owner, Some("TeamA".to_string()));
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
#[test]
|
|
396
|
+
fn test_ruby_package_owner_no_owner() {
|
|
397
|
+
let yaml = "name: my_package\n";
|
|
398
|
+
let temp_file = tempfile::NamedTempFile::new().unwrap();
|
|
399
|
+
std::fs::write(temp_file.path(), yaml).unwrap();
|
|
400
|
+
|
|
401
|
+
let owner = ruby_package_owner(temp_file.path()).unwrap();
|
|
402
|
+
assert_eq!(owner, None);
|
|
403
|
+
}
|
|
337
404
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
use std::collections::HashMap;
|
|
2
2
|
|
|
3
|
-
use crate::ownership::FileOwner;
|
|
4
3
|
use crate::project::Team;
|
|
4
|
+
use crate::{ownership::FileOwner, runner::config_from_run_config};
|
|
5
5
|
|
|
6
|
-
use super::{Error, ForFileResult, RunConfig, RunResult,
|
|
6
|
+
use super::{Error, ForFileResult, RunConfig, RunResult, run};
|
|
7
7
|
|
|
8
8
|
pub fn for_file(run_config: &RunConfig, file_path: &str, from_codeowners: bool, json: bool) -> RunResult {
|
|
9
9
|
if from_codeowners {
|
|
@@ -38,7 +38,7 @@ pub fn crosscheck_owners(run_config: &RunConfig) -> RunResult {
|
|
|
38
38
|
|
|
39
39
|
// Returns all owners for a file without creating a Runner (performance optimized)
|
|
40
40
|
pub fn owners_for_file(run_config: &RunConfig, file_path: &str) -> error_stack::Result<Vec<FileOwner>, Error> {
|
|
41
|
-
let config =
|
|
41
|
+
let config = config_from_run_config(run_config)?;
|
|
42
42
|
use crate::ownership::file_owner_resolver::find_file_owners;
|
|
43
43
|
let owners = find_file_owners(&run_config.project_root, &config, std::path::Path::new(file_path)).map_err(Error::Io)?;
|
|
44
44
|
Ok(owners)
|
|
@@ -60,10 +60,11 @@ pub fn teams_for_files_from_codeowners(
|
|
|
60
60
|
run_config: &RunConfig,
|
|
61
61
|
file_paths: &[String],
|
|
62
62
|
) -> error_stack::Result<HashMap<String, Option<Team>>, Error> {
|
|
63
|
-
let config =
|
|
63
|
+
let config = config_from_run_config(run_config)?;
|
|
64
|
+
let codeowners_file_path = super::resolve_codeowners_file_path(run_config, &config);
|
|
64
65
|
let res = crate::ownership::codeowners_query::teams_for_files_from_codeowners(
|
|
65
66
|
&run_config.project_root,
|
|
66
|
-
&
|
|
67
|
+
&codeowners_file_path,
|
|
67
68
|
&config.team_file_glob,
|
|
68
69
|
file_paths,
|
|
69
70
|
)
|
|
@@ -80,7 +81,7 @@ pub fn team_for_file_from_codeowners(run_config: &RunConfig, file_path: &str) ->
|
|
|
80
81
|
|
|
81
82
|
// Fast path that avoids creating a full Runner for single file queries
|
|
82
83
|
fn for_file_optimized(run_config: &RunConfig, file_path: &str, json: bool) -> RunResult {
|
|
83
|
-
let config = match
|
|
84
|
+
let config = match config_from_run_config(run_config) {
|
|
84
85
|
Ok(c) => c,
|
|
85
86
|
Err(err) => {
|
|
86
87
|
return RunResult::from_io_error(Error::Io(err.to_string()), json);
|
|
@@ -14,9 +14,10 @@ pub struct RunResult {
|
|
|
14
14
|
#[derive(Debug, Clone)]
|
|
15
15
|
pub struct RunConfig {
|
|
16
16
|
pub project_root: PathBuf,
|
|
17
|
-
pub codeowners_file_path: PathBuf
|
|
17
|
+
pub codeowners_file_path: Option<PathBuf>,
|
|
18
18
|
pub config_path: PathBuf,
|
|
19
19
|
pub no_cache: bool,
|
|
20
|
+
pub executable_name: Option<String>,
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
#[derive(Debug, Serialize)]
|