diff --git a/src/commands/sourcemaps/inject.rs b/src/commands/sourcemaps/inject.rs index d1c876cb10..a2824cadbf 100644 --- a/src/commands/sourcemaps/inject.rs +++ b/src/commands/sourcemaps/inject.rs @@ -35,7 +35,7 @@ pub fn make_command(command: Command) -> Command { .short('i') .value_name("IGNORE") .action(ArgAction::Append) - .help("Ignores all files and folders matching the given glob"), + .help("Ignores all files and folders matching the given glob. Patterns are relative to the current directory, or absolute if starting with `/`."), ) .arg( Arg::new("ignore_file") diff --git a/src/commands/sourcemaps/upload.rs b/src/commands/sourcemaps/upload.rs index 2eaaa51aa0..fc11804125 100644 --- a/src/commands/sourcemaps/upload.rs +++ b/src/commands/sourcemaps/upload.rs @@ -161,7 +161,7 @@ pub fn make_command(command: Command) -> Command { .short('i') .value_name("IGNORE") .action(ArgAction::Append) - .help("Ignores all files and folders matching the given glob"), + .help("Ignores all files and folders matching the given glob. Patterns are relative to the current directory, or absolute if starting with `/`."), ) .arg( Arg::new("ignore_file") diff --git a/src/utils/file_search.rs b/src/utils/file_search.rs index dab73b4035..c65d0360c4 100644 --- a/src/utils/file_search.rs +++ b/src/utils/file_search.rs @@ -1,11 +1,12 @@ use std::collections::BTreeSet; +use std::env; use std::fs; use std::io::Read as _; use std::path::PathBuf; use anyhow::Result; use console::style; -use ignore::overrides::OverrideBuilder; +use glob::Pattern; use ignore::types::TypesBuilder; use ignore::WalkBuilder; use log::{info, warn}; @@ -126,12 +127,43 @@ impl ReleaseFileSearch { builder.add_ignore(ignore_file); } - if !&self.ignores.is_empty() { - let mut override_builder = OverrideBuilder::new(&self.path); - for ignore in &self.ignores { - override_builder.add(ignore)?; - } - builder.overrides(override_builder.build()?); + // Compile ignore patterns relative to CWD (not relative to search path) + let cwd = env::current_dir()?; + let ignore_patterns: Vec = self + .ignores + .iter() + .filter_map(|pattern| { + // Patterns starting with ! are negations (handled in upload.rs/inject.rs) + // Remove the ! prefix for glob pattern compilation + let pattern_str = pattern.strip_prefix('!').unwrap_or(pattern); + match Pattern::new(pattern_str) { + Ok(p) => Some(p), + Err(e) => { + warn!("Invalid ignore pattern '{}': {}", pattern_str, e); + None + } + } + }) + .collect(); + + // Use filter_entry to match patterns relative to CWD + if !ignore_patterns.is_empty() { + builder.filter_entry(move |entry| { + let entry_path = entry.path(); + + // Try to make the path relative to CWD, or use absolute path if that fails + let check_path = entry_path.strip_prefix(&cwd).unwrap_or(entry_path); + + // Check if any pattern matches - if so, ignore (return false) + for pattern in &ignore_patterns { + if pattern.matches_path(check_path) { + return false; + } + } + + // No patterns matched, keep this entry + true + }); } for result in builder.build() { diff --git a/tests/integration/_cases/sourcemaps/sourcemaps-inject-help.trycmd b/tests/integration/_cases/sourcemaps/sourcemaps-inject-help.trycmd index d105fb757c..5c05375d17 100644 --- a/tests/integration/_cases/sourcemaps/sourcemaps-inject-help.trycmd +++ b/tests/integration/_cases/sourcemaps/sourcemaps-inject-help.trycmd @@ -15,7 +15,8 @@ Arguments: Options: -i, --ignore - Ignores all files and folders matching the given glob + Ignores all files and folders matching the given glob. Patterns are relative to the + current directory, or absolute if starting with `/`. -o, --org The organization ID or slug. diff --git a/tests/integration/_cases/sourcemaps/sourcemaps-inject-ignore-relative.trycmd b/tests/integration/_cases/sourcemaps/sourcemaps-inject-ignore-relative.trycmd new file mode 100644 index 0000000000..3067058436 --- /dev/null +++ b/tests/integration/_cases/sourcemaps/sourcemaps-inject-ignore-relative.trycmd @@ -0,0 +1,23 @@ +``` +$ sentry-cli sourcemaps inject path_a path_b --ignore "**/path_a/test/**" --dry-run +? success +> Searching path_a +> Found 2 files +> Searching path_b +> Found 4 files +> Analyzing 6 sources +> Analyzing completed in [..] +> Injecting debug ids + +Source Map Debug ID Injection Report + Modified: The following source files have been modified to have debug ids + [..]-[..]-[..]-[..]-[..] - path_a/keep/file3.js + [..]-[..]-[..]-[..]-[..] - path_b/keep/file4.js + [..]-[..]-[..]-[..]-[..] - path_b/test/file2.js + Modified: The following sourcemap files have been modified to have debug ids + [..]-[..]-[..]-[..]-[..] - path_a/keep/file3.js.map + [..]-[..]-[..]-[..]-[..] - path_b/keep/file4.js.map + [..]-[..]-[..]-[..]-[..] - path_b/test/file2.js.map + + +``` diff --git a/tests/integration/_cases/sourcemaps/sourcemaps-upload-help.trycmd b/tests/integration/_cases/sourcemaps/sourcemaps-upload-help.trycmd index 63c096ef92..44f0d0296a 100644 --- a/tests/integration/_cases/sourcemaps/sourcemaps-upload-help.trycmd +++ b/tests/integration/_cases/sourcemaps/sourcemaps-upload-help.trycmd @@ -67,7 +67,8 @@ Options: --strip-common-prefix Similar to --strip-prefix but strips the most common prefix on all sources references. -i, --ignore - Ignores all files and folders matching the given glob + Ignores all files and folders matching the given glob. Patterns are relative to the + current directory, or absolute if starting with `/`. -I, --ignore-file Ignore all files and folders specified in the given ignore file, e.g. .gitignore. --bundle diff --git a/tests/integration/_cases/sourcemaps/sourcemaps-upload-ignore-relative.trycmd b/tests/integration/_cases/sourcemaps/sourcemaps-upload-ignore-relative.trycmd new file mode 100644 index 0000000000..a59d0831d3 --- /dev/null +++ b/tests/integration/_cases/sourcemaps/sourcemaps-upload-ignore-relative.trycmd @@ -0,0 +1,17 @@ +``` +$ sentry-cli sourcemaps upload path_a path_b --ignore "**/path_a/test/**" --url-prefix "~/" --validate +? failed +> Found 2 files +> Found 4 files +> Analyzing 6 sources +> Analyzing completed in [..] +> Rewriting sources +> Rewriting completed in [..] +> Adding source map references +> Validating sources +error: Cannot upload: You must either specify a release or have debug ids injected into your sources + +Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. +Please attach the full debug log to all bug reports. + +``` diff --git a/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js b/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js new file mode 100644 index 0000000000..dd3bf2db1e --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js @@ -0,0 +1,2 @@ +// This file should be kept +console.log("path_a/keep/file3.js"); diff --git a/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js.map b/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js.map new file mode 100644 index 0000000000..7ca7085f29 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_a/keep/file3.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["file3.js"],"names":[],"mappings":"AAAA"} diff --git a/tests/integration/_fixtures/ignore_test/path_a/test/file1.js b/tests/integration/_fixtures/ignore_test/path_a/test/file1.js new file mode 100644 index 0000000000..58170e4957 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_a/test/file1.js @@ -0,0 +1,2 @@ +// This file should be ignored +console.log("path_a/test/file1.js"); diff --git a/tests/integration/_fixtures/ignore_test/path_a/test/file1.js.map b/tests/integration/_fixtures/ignore_test/path_a/test/file1.js.map new file mode 100644 index 0000000000..6cfa1948d1 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_a/test/file1.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["file1.js"],"names":[],"mappings":"AAAA"} diff --git a/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js b/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js new file mode 100644 index 0000000000..38cf2f520e --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js @@ -0,0 +1,2 @@ +// This file should be kept +console.log("path_b/keep/file4.js"); diff --git a/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js.map b/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js.map new file mode 100644 index 0000000000..41452381a1 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_b/keep/file4.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["file4.js"],"names":[],"mappings":"AAAA"} diff --git a/tests/integration/_fixtures/ignore_test/path_b/test/file2.js b/tests/integration/_fixtures/ignore_test/path_b/test/file2.js new file mode 100644 index 0000000000..b1cd2446e0 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_b/test/file2.js @@ -0,0 +1,2 @@ +// This file should NOT be ignored (path_b/test is different from path_a/test) +console.log("path_b/test/file2.js"); diff --git a/tests/integration/_fixtures/ignore_test/path_b/test/file2.js.map b/tests/integration/_fixtures/ignore_test/path_b/test/file2.js.map new file mode 100644 index 0000000000..9d4cabf942 --- /dev/null +++ b/tests/integration/_fixtures/ignore_test/path_b/test/file2.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["file2.js"],"names":[],"mappings":"AAAA"} diff --git a/tests/integration/sourcemaps/inject.rs b/tests/integration/sourcemaps/inject.rs index 1323ba9398..6d8451dfd3 100644 --- a/tests/integration/sourcemaps/inject.rs +++ b/tests/integration/sourcemaps/inject.rs @@ -216,6 +216,22 @@ fn command_sourcemaps_inject_double_association() { ); } +#[test] +fn command_sourcemaps_inject_ignore_relative() { + let testcase_cwd_path = + "tests/integration/_cases/sourcemaps/sourcemaps-inject-ignore-relative.in/"; + if std::path::Path::new(testcase_cwd_path).exists() { + remove_dir_all(testcase_cwd_path).unwrap(); + } + copy_recursively( + "tests/integration/_fixtures/ignore_test/", + testcase_cwd_path, + ) + .unwrap(); + + TestManager::new().register_trycmd_test("sourcemaps/sourcemaps-inject-ignore-relative.trycmd"); +} + /// Recursively assert that the contents of two directories are equal. /// /// We only support directories that contain exclusively text files. diff --git a/tests/integration/sourcemaps/upload.rs b/tests/integration/sourcemaps/upload.rs index 8820022d0e..c8236b3c0e 100644 --- a/tests/integration/sourcemaps/upload.rs +++ b/tests/integration/sourcemaps/upload.rs @@ -107,3 +107,25 @@ fn command_sourcemaps_upload_skip_invalid_utf8() { .register_trycmd_test("sourcemaps/sourcemaps-with-invalid-utf8.trycmd") .with_default_token(); } + +#[test] +fn command_sourcemaps_upload_ignore_relative() { + use crate::integration::copy_recursively; + use std::fs::remove_dir_all; + + let testcase_cwd_path = + "tests/integration/_cases/sourcemaps/sourcemaps-upload-ignore-relative.in/"; + if std::path::Path::new(testcase_cwd_path).exists() { + remove_dir_all(testcase_cwd_path).unwrap(); + } + copy_recursively( + "tests/integration/_fixtures/ignore_test/", + testcase_cwd_path, + ) + .unwrap(); + + TestManager::new() + .mock_common_upload_endpoints(None, None) + .register_trycmd_test("sourcemaps/sourcemaps-upload-ignore-relative.trycmd") + .with_default_token(); +}