Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/oxfmt/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ pub struct BasicOptions {
/// Ignore Options
#[derive(Debug, Clone, Bpaf)]
pub struct IgnoreOptions {
/// Path to ignore file(s). Can be specified multiple times.
/// If not specified, .gitignore and .prettierignore in the current directory are used.
#[bpaf(argument("PATH"), many)]
pub ignore_path: Vec<PathBuf>,
/// Format code in node_modules directory (skipped by default)
#[bpaf(switch, hide_usage)]
pub with_node_modules: bool,
Expand Down
7 changes: 6 additions & 1 deletion apps/oxfmt/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ impl FormatRunner {
}
};

let walker = match Walk::build(&cwd, &paths, ignore_options.with_node_modules) {
let walker = match Walk::build(
&cwd,
&paths,
&ignore_options.ignore_path,
ignore_options.with_node_modules,
) {
Ok(walker) => walker,
Err(err) => {
print_and_flush_stdout(
Expand Down
35 changes: 29 additions & 6 deletions apps/oxfmt/src/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl Walk {
pub fn build(
cwd: &PathBuf,
paths: &[PathBuf],
ignore_paths: &[PathBuf],
with_node_modules: bool,
) -> Result<Self, String> {
let (target_paths, exclude_patterns) = normalize_paths(cwd, paths);
Expand Down Expand Up @@ -44,12 +45,12 @@ impl Walk {
inner.overrides(overrides);
}

// TODO: Support ignoring files
// --ignore-path PATH1 --ignore-path PATH2
// or default cwd/{.gitignore,.prettierignore}
// if let Some(err) = inner.add_ignore(path) {
// return Err(format!("Failed to add ignore file: {}", err));
// }
// Handle ignore files
for ignore_path in load_ignore_paths(cwd, ignore_paths) {
if inner.add_ignore(&ignore_path).is_some() {
return Err(format!("Failed to add ignore file: {}", ignore_path.display()));
}
}

// NOTE: If return `false` here, it will not be `visit()`ed at all
inner.filter_entry(move |entry| {
Expand Down Expand Up @@ -92,7 +93,10 @@ impl Walk {
.hidden(false)
// Do not respect `.gitignore` automatically, we handle it manually
.ignore(false)
.parents(false)
.git_global(false)
.git_ignore(false)
.git_exclude(false)
.build_parallel();
Ok(Self { inner })
}
Expand Down Expand Up @@ -155,6 +159,25 @@ fn normalize_paths(cwd: &Path, input_paths: &[PathBuf]) -> (Vec<PathBuf>, Vec<St
(target_paths, exclude_patterns)
}

fn load_ignore_paths(cwd: &Path, ignore_paths: &[PathBuf]) -> Vec<PathBuf> {
// If specified, just resolves absolute paths
if !ignore_paths.is_empty() {
return ignore_paths
.iter()
.map(|path| if path.is_absolute() { path.clone() } else { cwd.join(path) })
.collect();
}

// Else, search for default ignore files in cwd
[".gitignore", ".prettierignore"]
.iter()
.filter_map(|file_name| {
let path = cwd.join(file_name);
if path.exists() { Some(path) } else { None }
})
.collect::<Vec<_>>()
}

// ---

pub struct WalkEntry {
Expand Down
1 change: 1 addition & 0 deletions apps/oxfmt/tests/fixtures/ignore_patterns/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
not-formatted/
1 change: 1 addition & 0 deletions apps/oxfmt/tests/fixtures/ignore_patterns/custom.ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ignored/
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Foo {}
1 change: 1 addition & 0 deletions apps/oxfmt/tests/fixtures/ignore_patterns/gitignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ignored/
1 change: 1 addition & 0 deletions apps/oxfmt/tests/fixtures/ignore_patterns/good.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Foo {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Baz { }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Baz2 { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This should be ignored - only cwd/.prettierignore should be used
*.js
*.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Bar { }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Qux { }
22 changes: 22 additions & 0 deletions apps/oxfmt/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,25 @@ fn exclude_nested_paths_with_dot() {
&["--check", "./foo", "!foo/bar"],
]);
}

#[test]
fn ignore_patterns() {
// Test ignore file handling with different configurations
// .prettierignore (cwd) contains: not-formatted/
// not-formatted/.prettierignore (subdirectory) should be ignored
// gitignore.txt contains: ignored/
// custom.ignore contains: ignored/ (only)
Tester::new()
.with_cwd(PathBuf::from("tests/fixtures/ignore_patterns"))
.test_and_snapshot_multiple(&[
// Default: auto-detects only cwd/.prettierignore (ignores not-formatted/ dir)
// Note: not-formatted/.prettierignore exists but should be ignored
&["--check"],
// Explicit: uses gitignore.txt (ignores ignored/ dir, checks not-formatted/)
&["--check", "--ignore-path", "gitignore.txt"],
// Multiple files: ignores both dirs
&["--check", "--ignore-path", "gitignore.txt", "--ignore-path", ".prettierignore"],
// Nonexistent file should error
&["--check", "--ignore-path", "nonexistent.ignore"],
]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
source: apps/oxfmt/tests/tester.rs
---
##########
arguments: --check
working directory: tests/fixtures/ignore_patterns
----------
Checking formatting...
ignored/should-be-ignored.js (<variable>ms)
ignored/should-be-ignored.ts (<variable>ms)

Format issues found in above 2 files. Run without `--check` to fix.
Finished in <variable>ms on 4 files using 1 threads.
----------
CLI result: FormatMismatch
----------

##########
arguments: --check --ignore-path gitignore.txt
working directory: tests/fixtures/ignore_patterns
----------
Checking formatting...
not-formatted/bad.js (<variable>ms)
not-formatted/bad.ts (<variable>ms)

Format issues found in above 2 files. Run without `--check` to fix.
Finished in <variable>ms on 4 files using 1 threads.
----------
CLI result: FormatMismatch
----------

##########
arguments: --check --ignore-path gitignore.txt --ignore-path .prettierignore
working directory: tests/fixtures/ignore_patterns
----------
Checking formatting...

All matched files use the correct format.
Finished in <variable>ms on 2 files using 1 threads.
----------
CLI result: FormatSucceeded
----------

##########
arguments: --check --ignore-path nonexistent.ignore
working directory: tests/fixtures/ignore_patterns
----------
Failed to parse target paths or ignore settings.
Failed to add ignore file: <cwd>/tests/fixtures/ignore_patterns/nonexistent.ignore
----------
CLI result: InvalidOptionConfig
----------
Loading