Skip to content

Commit 8734913

Browse files
authored
Skip untracked files (#76)
* presence of .codeowners-skip-untracked-files skips untracked files * config file as yml * only validate tracked files using tracked files map * updating tests
1 parent f3badee commit 8734913

File tree

18 files changed

+286
-324
lines changed

18 files changed

+286
-324
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "codeowners"
3-
version = "0.2.11"
3+
version = "0.2.13"
44
edition = "2024"
55

66
[profile.release]
@@ -34,6 +34,6 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
3434
[dev-dependencies]
3535
assert_cmd = "2.0.16"
3636
rusty-hook = "^0.11.2"
37-
predicates = "3.1.2"
37+
predicates = "3.1.3"
3838
pretty_assertions = "1.4.1" # Shows a more readable diff when comparing objects
3939
indoc = "2.0.5"

src/config.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ pub struct Config {
2424

2525
#[serde(default = "default_ignore_dirs")]
2626
pub ignore_dirs: Vec<String>,
27-
28-
#[serde(default = "default_skip_untracked_files")]
29-
pub skip_untracked_files: bool,
3027
}
3128

3229
#[allow(dead_code)]
@@ -63,10 +60,6 @@ fn vendored_gems_path() -> String {
6360
"vendored/".to_string()
6461
}
6562

66-
fn default_skip_untracked_files() -> bool {
67-
true
68-
}
69-
7063
fn default_ignore_dirs() -> Vec<String> {
7164
vec![
7265
".cursor".to_owned(),

src/files.rs

Lines changed: 0 additions & 157 deletions
This file was deleted.

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ pub mod cache;
22
pub(crate) mod common_test;
33
pub mod config;
44
pub mod crosscheck;
5-
pub(crate) mod files;
65
pub mod ownership;
76
pub(crate) mod project;
87
pub mod project_builder;
98
pub mod project_file_builder;
109
pub mod runner;
10+
pub(crate) mod tracked_files;

src/ownership/for_file_fast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ mod tests {
303303
vendored_gems_path: vendored_path.to_string(),
304304
cache_directory: "tmp/cache/codeowners".to_string(),
305305
ignore_dirs: vec![],
306-
skip_untracked_files: false,
307306
}
308307
}
309308

src/project_builder.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ use tracing::{instrument, warn};
1313
use crate::{
1414
cache::Cache,
1515
config::Config,
16-
files,
1716
project::{DirectoryCodeownersFile, Error, Package, PackageType, Project, ProjectFile, Team, VendoredGem, deserializers},
1817
project_file_builder::ProjectFileBuilder,
18+
tracked_files,
1919
};
2020

2121
type AbsolutePath = PathBuf;
@@ -61,16 +61,16 @@ impl<'a> ProjectBuilder<'a> {
6161
// Prune traversal early: skip heavy and irrelevant directories
6262
let ignore_dirs = self.config.ignore_dirs.clone();
6363
let base_path = self.base_path.clone();
64-
let untracked_files = if self.config.skip_untracked_files {
65-
files::untracked_files(&base_path).unwrap_or_default()
66-
} else {
67-
vec![]
68-
};
64+
let tracked_files = tracked_files::find_tracked_files(&self.base_path);
6965

7066
builder.filter_entry(move |entry: &DirEntry| {
7167
let path = entry.path();
7268
let file_name = entry.file_name().to_str().unwrap_or("");
73-
if !untracked_files.is_empty() && untracked_files.contains(&path.to_path_buf()) {
69+
if let Some(tracked_files) = &tracked_files
70+
&& let Some(ft) = entry.file_type()
71+
&& ft.is_file()
72+
&& !tracked_files.contains_key(path)
73+
{
7474
return false;
7575
}
7676
if let Some(ft) = entry.file_type()

src/tracked_files.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use std::{
2+
collections::HashMap,
3+
path::{Path, PathBuf},
4+
process::Command,
5+
};
6+
7+
pub(crate) fn find_tracked_files(base_path: &Path) -> Option<HashMap<PathBuf, bool>> {
8+
let output = Command::new("git")
9+
.args(["ls-files", "--full-name", "-z", "--", "."])
10+
.current_dir(base_path)
11+
.output()
12+
.ok()?;
13+
14+
if !output.status.success() {
15+
return None;
16+
}
17+
18+
let results: HashMap<PathBuf, bool> = output
19+
.stdout
20+
.split(|&b| b == b'\0')
21+
.filter(|chunk| !chunk.is_empty())
22+
.map(|rel| std::str::from_utf8(rel).ok().map(|s| (base_path.join(s), true)))
23+
.collect::<Option<HashMap<PathBuf, bool>>>()?;
24+
25+
Some(results)
26+
}
27+
28+
#[cfg(test)]
29+
mod tests {
30+
use super::*;
31+
32+
#[test]
33+
fn test_untracked_files() {
34+
let tmp_dir = tempfile::tempdir().unwrap();
35+
assert!(find_tracked_files(tmp_dir.path()).is_none());
36+
37+
std::process::Command::new("git")
38+
.arg("init")
39+
.current_dir(tmp_dir.path())
40+
.output()
41+
.expect("failed to run git init");
42+
43+
std::fs::write(tmp_dir.path().join("test.txt"), "test").unwrap();
44+
let tracked = find_tracked_files(tmp_dir.path()).unwrap();
45+
assert!(tracked.is_empty());
46+
47+
std::process::Command::new("git")
48+
.arg("add")
49+
.arg("test.txt")
50+
.current_dir(tmp_dir.path())
51+
.output()
52+
.expect("failed to add test.txt");
53+
54+
let tracked = find_tracked_files(tmp_dir.path()).unwrap();
55+
assert!(tracked.len() == 1);
56+
assert!(tracked.get(&tmp_dir.path().join("test.txt")).unwrap());
57+
}
58+
}

0 commit comments

Comments
 (0)