From 78f07e2e9e9a56356a944c0b2df4dd0623d11a14 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 11:46:01 +0200 Subject: [PATCH 1/9] feat(bundle-jvm): Add JVM extension filtering and default excludes Filter collected sources by JVM file extensions (java, kt, scala, groovy, kts) and exclude common build output directories by default (build, .gradle, .cxx, node_modules). Also respect .gitignore rules as an additional layer of defense. Users can provide extra --exclude glob patterns on top of the defaults. This enables invoking bundle-jvm directly on a project root without needing to pre-copy sources into a separate directory. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 35 ++++++++++++++++++++++++-- src/utils/file_search.rs | 17 +++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index 884c944e35..cd1dde32e8 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -7,7 +7,7 @@ use crate::utils::file_upload::SourceFile; use crate::utils::fs::path_as_url; use crate::utils::source_bundle::{self, BundleContext}; use anyhow::{bail, Context as _, Result}; -use clap::{Arg, ArgMatches, Command}; +use clap::{Arg, ArgAction, ArgMatches, Command}; use sentry::types::DebugId; use std::collections::BTreeMap; use std::fs; @@ -16,6 +16,12 @@ use std::str::FromStr as _; use std::sync::Arc; use symbolic::debuginfo::sourcebundle::SourceFileType; +/// File extensions for JVM-based languages. +const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy", "kts"]; + +/// Default directory patterns to exclude from source collection. +const DEFAULT_EXCLUDES: &[&str] = &["!build", "!.gradle", "!.cxx", "!node_modules"]; + pub fn make_command(command: Command) -> Command { command .hide(true) // experimental for now @@ -47,6 +53,16 @@ pub fn make_command(command: Command) -> Command { .value_parser(DebugId::from_str) .help("Debug ID (UUID) to use for the source bundle."), ) + .arg( + Arg::new("exclude") + .long("exclude") + .value_name("PATTERN") + .action(ArgAction::Append) + .help( + "Glob pattern to exclude files/directories. Can be repeated. \ + By default, 'build', '.gradle', and '.cxx' directories are excluded.", + ), + ) } pub fn execute(matches: &ArgMatches) -> Result<()> { @@ -75,7 +91,22 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { ))?; } - let sources = ReleaseFileSearch::new(path.clone()).collect_files()?; + let user_excludes: Vec = matches + .get_many::("exclude") + .map(|vals| vals.map(|v| format!("!{v}")).collect()) + .unwrap_or_default(); + + let all_excludes: Vec<&str> = DEFAULT_EXCLUDES + .iter() + .copied() + .chain(user_excludes.iter().map(|s| s.as_str())) + .collect(); + + let sources = ReleaseFileSearch::new(path.clone()) + .extensions(JVM_EXTENSIONS.iter().copied()) + .ignores(all_excludes) + .respect_ignores(true) + .collect_files()?; let files = sources.iter().map(|source| { let local_path = source.path.strip_prefix(&source.base_path).unwrap(); let local_path_jvm_ext = local_path.with_extension("jvm"); diff --git a/src/utils/file_search.rs b/src/utils/file_search.rs index 6e11e5a63b..50138e1308 100644 --- a/src/utils/file_search.rs +++ b/src/utils/file_search.rs @@ -20,6 +20,7 @@ pub struct ReleaseFileSearch { ignores: BTreeSet, ignore_file: Option, decompress: bool, + respect_ignores: bool, } #[derive(Eq, PartialEq, Hash)] @@ -37,6 +38,7 @@ impl ReleaseFileSearch { ignore_file: None, ignores: BTreeSet::new(), decompress: false, + respect_ignores: false, } } @@ -78,6 +80,11 @@ impl ReleaseFileSearch { self } + pub fn respect_ignores(&mut self, respect: bool) -> &mut Self { + self.respect_ignores = respect; + self + } + pub fn collect_file(path: PathBuf) -> Result { // NOTE: `collect_file` currently do not handle gzip decompression, // as its mostly used for 3rd tools like xcode or gradle. @@ -105,11 +112,11 @@ impl ReleaseFileSearch { let mut collected = Vec::new(); let mut builder = WalkBuilder::new(&self.path); - builder - .follow_links(true) - .git_exclude(false) - .git_ignore(false) - .ignore(false); + builder.follow_links(true); + + if !self.respect_ignores { + builder.git_exclude(false).git_ignore(false).ignore(false); + } if !&self.extensions.is_empty() { let mut types_builder = TypesBuilder::new(); From 15aa294deecfa4348e8cff4a89cb1ad2bf90404a Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 11:46:32 +0200 Subject: [PATCH 2/9] ref(bundle-jvm): Remove kts from JVM extensions list Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index cd1dde32e8..02d36b3f69 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use symbolic::debuginfo::sourcebundle::SourceFileType; /// File extensions for JVM-based languages. -const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy", "kts"]; +const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy"]; /// Default directory patterns to exclude from source collection. const DEFAULT_EXCLUDES: &[&str] = &["!build", "!.gradle", "!.cxx", "!node_modules"]; From 3d3c972e85063373241c5c77a8e59d1cdcc32a67 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 11:52:16 +0200 Subject: [PATCH 3/9] fix(bundle-jvm): Include node_modules in help text for default excludes Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index 02d36b3f69..4aba06a403 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -60,7 +60,7 @@ pub fn make_command(command: Command) -> Command { .action(ArgAction::Append) .help( "Glob pattern to exclude files/directories. Can be repeated. \ - By default, 'build', '.gradle', and '.cxx' directories are excluded.", + By default, 'build', '.gradle', '.cxx', and 'node_modules' directories are excluded.", ), ) } From b6494f140c60b66a9bc02659b94afd18703613db Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 11:59:58 +0200 Subject: [PATCH 4/9] fix(bundle-jvm): Update help snapshot and add changelog entry Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 ++++ .../_cases/debug_files/debug_files-bundle-jvm-help.trycmd | 3 +++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d63809dc6..e02337eb24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- (bundle-jvm) Filter sources by JVM extensions, respect `.gitignore`, and add default directory excludes and `--exclude` option ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) + ### Fixes - Replace `eprintln!` with `log::info!` for progress bar completion messages when the progress bar is disabled (e.g. in CI). This avoids spurious stderr output that some CI systems treat as errors ([#3223](https://github.com/getsentry/sentry-cli/pull/3223)). diff --git a/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd b/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd index 8f3b704e73..625414bb37 100644 --- a/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd +++ b/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd @@ -18,6 +18,9 @@ Options: --debug-id Debug ID (UUID) to use for the source bundle. --log-level Set the log output verbosity. [possible values: trace, debug, info, warn, error] + --exclude Glob pattern to exclude files/directories. Can be repeated. By + default, 'build', '.gradle', '.cxx', and 'node_modules' directories + are excluded. --quiet Do not print any output while preserving correct exit code. This flag is currently implemented only for selected subcommands. [aliases: --silent] From cf43f3f3cb0e55e29f198542e33f036fd64c62dc Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 12:05:48 +0200 Subject: [PATCH 5/9] docs(changelog): Improve bundle-jvm changelog entry Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e02337eb24..b6d4ccc598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- (bundle-jvm) Filter sources by JVM extensions, respect `.gitignore`, and add default directory excludes and `--exclude` option ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) +- (bundle-jvm) Allow running directly on a project root (including multi-module repos) by automatically collecting only JVM source files (`.java`, `.kt`, `.scala`, `.groovy`), respecting `.gitignore`, and excluding common build output directories. Add `--exclude` option for custom glob patterns ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) ### Fixes From a74c1d4b16383b8e03672cf277e55cde1452bebb Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 12:06:23 +0200 Subject: [PATCH 6/9] docs(changelog): Split bundle-jvm changelog into separate entries Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d4ccc598..14e55b3b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ ### Features -- (bundle-jvm) Allow running directly on a project root (including multi-module repos) by automatically collecting only JVM source files (`.java`, `.kt`, `.scala`, `.groovy`), respecting `.gitignore`, and excluding common build output directories. Add `--exclude` option for custom glob patterns ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) +- (bundle-jvm) Allow running directly on a project root (including multi-module repos) by automatically collecting only JVM source files (`.java`, `.kt`, `.scala`, `.groovy`), respecting `.gitignore`, and excluding common build output directories ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) +- (bundle-jvm) Add `--exclude` option for custom glob patterns to exclude files/directories from source collection ([#3260](https://github.com/getsentry/sentry-cli/pull/3260)) ### Fixes From 4a3285550abed13e265da0c28759f7e3f272a15c Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 12:15:14 +0200 Subject: [PATCH 7/9] feat(bundle-jvm): Add clojure extensions and more default excludes Add .clj and .cljc to JVM extensions. Expand default excludes to cover Maven (target, .mvn), IDE (.idea, .vscode, .eclipse, .settings, .fleet), and common output dirs (bin, out, .kotlin). Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 22 ++++++++++++++++--- .../debug_files-bundle-jvm-help.trycmd | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index 4aba06a403..b7dac962c3 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -17,10 +17,25 @@ use std::sync::Arc; use symbolic::debuginfo::sourcebundle::SourceFileType; /// File extensions for JVM-based languages. -const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy"]; +const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy", "clj", "cljc"]; /// Default directory patterns to exclude from source collection. -const DEFAULT_EXCLUDES: &[&str] = &["!build", "!.gradle", "!.cxx", "!node_modules"]; +const DEFAULT_EXCLUDES: &[&str] = &[ + "!build", + "!.gradle", + "!.cxx", + "!node_modules", + "!target", + "!.mvn", + "!.idea", + "!.vscode", + "!.eclipse", + "!.settings", + "!bin", + "!out", + "!.kotlin", + "!.fleet", +]; pub fn make_command(command: Command) -> Command { command @@ -60,7 +75,8 @@ pub fn make_command(command: Command) -> Command { .action(ArgAction::Append) .help( "Glob pattern to exclude files/directories. Can be repeated. \ - By default, 'build', '.gradle', '.cxx', and 'node_modules' directories are excluded.", + By default, common build output and IDE directories are excluded \ + (build, .gradle, target, .idea, .vscode, out, bin, etc.).", ), ) } diff --git a/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd b/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd index 625414bb37..6dd75ce9d1 100644 --- a/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd +++ b/tests/integration/_cases/debug_files/debug_files-bundle-jvm-help.trycmd @@ -19,8 +19,8 @@ Options: --log-level Set the log output verbosity. [possible values: trace, debug, info, warn, error] --exclude Glob pattern to exclude files/directories. Can be repeated. By - default, 'build', '.gradle', '.cxx', and 'node_modules' directories - are excluded. + default, common build output and IDE directories are excluded + (build, .gradle, target, .idea, .vscode, out, bin, etc.). --quiet Do not print any output while preserving correct exit code. This flag is currently implemented only for selected subcommands. [aliases: --silent] From 13f2d822490e72c5b81358b7367a8c1b7066f691 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 12:16:41 +0200 Subject: [PATCH 8/9] feat(bundle-jvm): Expand JVM extensions to cover all JVM-based languages Include Scala (.scala, .sc), Groovy (.groovy, .gvy, .gy, .gsh), Gradle (.gradle), Clojure (.clj, .cljs, .cljc, .edn), JRuby (.rb), and Jython (.py). Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index b7dac962c3..84f0cb72ca 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -17,7 +17,10 @@ use std::sync::Arc; use symbolic::debuginfo::sourcebundle::SourceFileType; /// File extensions for JVM-based languages. -const JVM_EXTENSIONS: &[&str] = &["java", "kt", "scala", "groovy", "clj", "cljc"]; +const JVM_EXTENSIONS: &[&str] = &[ + "java", "kt", "scala", "sc", "groovy", "gvy", "gy", "gsh", "gradle", "clj", "cljs", "cljc", + "edn", "rb", "py", +]; /// Default directory patterns to exclude from source collection. const DEFAULT_EXCLUDES: &[&str] = &[ From 40acfc0a9665b6f053245d4f557803490f952ed7 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Fri, 10 Apr 2026 12:18:57 +0200 Subject: [PATCH 9/9] ref(bundle-jvm): Drop rb, py, gradle, edn from JVM extensions Co-Authored-By: Claude Opus 4.6 (1M context) --- src/commands/debug_files/bundle_jvm.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/debug_files/bundle_jvm.rs b/src/commands/debug_files/bundle_jvm.rs index 84f0cb72ca..a077eafd07 100644 --- a/src/commands/debug_files/bundle_jvm.rs +++ b/src/commands/debug_files/bundle_jvm.rs @@ -18,8 +18,7 @@ use symbolic::debuginfo::sourcebundle::SourceFileType; /// File extensions for JVM-based languages. const JVM_EXTENSIONS: &[&str] = &[ - "java", "kt", "scala", "sc", "groovy", "gvy", "gy", "gsh", "gradle", "clj", "cljs", "cljc", - "edn", "rb", "py", + "java", "kt", "scala", "sc", "groovy", "gvy", "gy", "gsh", "clj", "cljs", "cljc", ]; /// Default directory patterns to exclude from source collection.