Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package Bear for openSUSE:Factory checked in at 2026-09-17 15:20:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/Bear (Old) and /work/SRC/openSUSE:Factory/.Bear.new.383539 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "Bear" Thu Sep 17 15:20:09 2026 rev:16 rq:1378323 version:4.2.2 Changes: -------- --- /work/SRC/openSUSE:Factory/Bear/Bear.changes 2026-09-02 17:12:36.754961861 +0200 +++ /work/SRC/openSUSE:Factory/.Bear.new.383539/Bear.changes 2026-09-17 15:21:26.900085846 +0200 @@ -1,0 +2,15 @@ +Sun Sep 13 06:41:05 UTC 2026 - Martin Pluskal <[email protected]> + +- Update to version 4.2.2: + * New --overwrite flag wherever --append is accepted, naming + the current default before appending becomes the default; + passing it together with --append is a usage error. + * Fixed the ambiguous-name probe test reading the dispatch + verdict instead of log substrings (false failure with + GCC-mentioning environments, upstream issue #716). + * Lockfile refresh (serde-saphyr 1.2.0 and other + semver-compatible updates, no advisories). + * Man page dated for the release. +- Regenerate vendor.tar.zst via cargo_vendor service. + +------------------------------------------------------------------- Old: ---- Bear-4.2.1.tar.zst New: ---- Bear-4.2.2.tar.zst ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ Bear.spec ++++++ --- /var/tmp/diff_new_pack.YbdeGX/_old 2026-09-17 15:21:28.231141675 +0200 +++ /var/tmp/diff_new_pack.YbdeGX/_new 2026-09-17 15:21:28.232141716 +0200 @@ -19,7 +19,7 @@ %bcond_without tests Name: Bear -Version: 4.2.1 +Version: 4.2.2 Release: 0 Summary: Tool that generates a compilation database for clang tooling License: GPL-3.0-or-later ++++++ Bear-4.2.1.tar.zst -> Bear-4.2.2.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/Cargo.lock new/Bear-4.2.2/Cargo.lock --- old/Bear-4.2.1/Cargo.lock 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/Cargo.lock 1970-01-01 01:00:00.000000000 +0100 @@ -77,13 +77,13 @@ [[package]] name = "base64" -version = "0.22.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" [[package]] name = "bear" -version = "4.2.1" +version = "4.2.2" dependencies = [ "clap", "crossbeam-channel", @@ -104,7 +104,7 @@ [[package]] name = "bear-completions" -version = "4.2.1" +version = "4.2.2" dependencies = [ "bear", "clap_complete", @@ -112,7 +112,7 @@ [[package]] name = "bear-driver" -version = "4.2.1" +version = "4.2.2" dependencies = [ "anyhow", "bear", @@ -123,7 +123,7 @@ [[package]] name = "bear-test-tools" -version = "4.2.1" +version = "4.2.2" dependencies = [ "anyhow", "clap", @@ -135,7 +135,7 @@ [[package]] name = "bear-wrapper" -version = "4.2.1" +version = "4.2.2" dependencies = [ "anyhow", "intercept", @@ -177,9 +177,9 @@ [[package]] name = "cc" -version = "1.4.3" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "shlex", @@ -230,7 +230,7 @@ "heck", "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.5", ] [[package]] @@ -241,7 +241,7 @@ [[package]] name = "compilers-codegen" -version = "4.2.1" +version = "4.2.2" dependencies = [ "anyhow", "insta", @@ -380,9 +380,9 @@ [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "float-cmp" @@ -469,9 +469,9 @@ [[package]] name = "granit-parser" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccd1be9ebf2bd5520dbfcfb72b70ef492f654061299a097056f3e73410e38ec" +checksum = "65ec0d45986cd51c847c75c5b69a00852c4fc84d0e5e79f041173f73437d0cdf" dependencies = [ "arraydeque", "smallvec", @@ -513,7 +513,7 @@ [[package]] name = "integration-tests" -version = "4.2.1" +version = "4.2.2" dependencies = [ "anyhow", "assert_cmd", @@ -530,7 +530,7 @@ [[package]] name = "intercept" -version = "4.2.1" +version = "4.2.2" dependencies = [ "compilers-codegen", "env_logger", @@ -544,7 +544,7 @@ [[package]] name = "intercept-preload" -version = "4.2.1" +version = "4.2.2" dependencies = [ "cc", "ctor", @@ -559,7 +559,7 @@ [[package]] name = "intercept-supervisor" -version = "4.2.1" +version = "4.2.2" dependencies = [ "intercept", "libc", @@ -604,9 +604,9 @@ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "memchr" @@ -669,7 +669,7 @@ [[package]] name = "platform-checks" -version = "4.2.1" +version = "4.2.2" dependencies = [ "cc", "tempfile", @@ -878,7 +878,7 @@ [[package]] name = "semantic" -version = "4.2.1" +version = "4.2.2" dependencies = [ "compilers-codegen", "intercept", @@ -903,9 +903,9 @@ [[package]] name = "serde-saphyr" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ec1f5cac0eb96063c64b28705255a7ed6e7d77f95c1d25e9f8b8c928006ce1" +checksum = "3afb591f9cdb6223c88ba39269aff895620c7f0716dc42b705b5733d5c7c0823" dependencies = [ "annotate-snippets", "base64", @@ -935,7 +935,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.5", ] [[package]] @@ -991,9 +991,9 @@ [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" [[package]] name = "strsim" @@ -1014,9 +1014,9 @@ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" dependencies = [ "proc-macro2", "quote", @@ -1059,7 +1059,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.5", ] [[package]] @@ -1110,9 +1110,9 @@ [[package]] name = "which" -version = "8.0.5" +version = "8.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3ef584124b911bcc3875c2f1472e80f24361ceb789bd1c62b3e9a3df9ff43c" +checksum = "bae2f2b2b816647a1cab1acc91f5bd20812d53cb344382635ec2181940c8034f" dependencies = [ "libc", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/Cargo.toml new/Bear-4.2.2/Cargo.toml --- old/Bear-4.2.1/Cargo.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/Cargo.toml 1970-01-01 01:00:00.000000000 +0100 @@ -8,7 +8,7 @@ resolver = "3" [workspace.package] -version = "4.2.1" +version = "4.2.2" authors = ["László Nagy <rizsotto at gmail dot com>"] repository = "https://github.com/rizsotto/Bear" homepage = "https://github.com/rizsotto/Bear" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/crates/bear/src/args.rs new/Bear-4.2.2/crates/bear/src/args.rs --- old/Bear-4.2.1/crates/bear/src/args.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/crates/bear/src/args.rs 1970-01-01 01:00:00.000000000 +0100 @@ -230,6 +230,10 @@ fn try_from(matches: &ArgMatches) -> Result<Self, Self::Error> { let path = matches.get_one::<String>("output").map(std::path::PathBuf::from).expect("output is defaulted"); + // `--overwrite` is deliberately not read here. It names the behaviour + // that is already the default, so today it only has to be accepted and + // to conflict with `--append`. It becomes load-bearing when appending + // turns into the default. let append = *matches.get_one::<bool>("append").unwrap_or(&false); Ok(BuildSemantic { path, append }) } @@ -294,6 +298,9 @@ .default_value(DEFAULT_OUTPUT_FILE) .hide_default_value(false), arg!(-a --append "Append result to an existing output file").action(ArgAction::SetTrue), + arg!(--overwrite "Overwrite an existing output file (the default)") + .action(ArgAction::SetTrue) + .conflicts_with("append"), arg!(--"print-compilers" "Print the compilers Bear recognizes and exit") .action(ArgAction::SetTrue), ]) @@ -315,6 +322,9 @@ .default_value(DEFAULT_OUTPUT_FILE) .hide_default_value(false), arg!(-a --append "Append result to an existing output file").action(ArgAction::SetTrue), + arg!(--overwrite "Overwrite an existing output file (the default)") + .action(ArgAction::SetTrue) + .conflicts_with("append"), arg!(-C --directory <DIR> "Initial working directory for the parsed commands"), ]) .arg_required_else_help(false) @@ -335,6 +345,9 @@ .default_value(DEFAULT_OUTPUT_FILE) .hide_default_value(false), arg!(-a --append "Append result to an existing output file").action(ArgAction::SetTrue), + arg!(--overwrite "Overwrite an existing output file (the default)") + .action(ArgAction::SetTrue) + .conflicts_with("append"), ]) } @@ -582,6 +595,57 @@ ); } + // Requirements: output-append + // + // `--overwrite` names the behaviour that is already the default, so it + // parses everywhere `--append` does and leaves the outcome untouched. + #[test] + fn test_overwrite_is_accepted_in_every_output_mode() { + let executions = vec![ + vec!["bear", "--overwrite", "--", "make", "all"], + vec!["bear", "semantic", "--overwrite"], + vec!["bear", "parse-sh", "--overwrite"], + ]; + + for execution in executions { + let matches = cli().try_get_matches_from(&execution).expect("--overwrite is accepted"); + let arguments = Arguments::try_from(matches).unwrap(); + + let output = match &arguments.mode { + Mode::Combined { output, .. } => output, + Mode::Semantic { output, .. } => output, + Mode::ParseSh { output, .. } => output, + other => panic!("unexpected mode {:?} for {:?}", other, execution), + }; + assert_eq!(output, &BuildSemantic { path: "compile_commands.json".into(), append: false }); + } + } + + // Requirements: output-append + // + // Asking to accumulate and to overwrite in one invocation is a script + // bug, and it is worth reporting now rather than after the default flips. + #[test] + fn test_overwrite_conflicts_with_append() { + // Both orders, because a script that gets this wrong may well pass + // the flags in either one. + let executions = vec![ + vec!["bear", "-a", "--overwrite", "--", "make", "all"], + vec!["bear", "--overwrite", "-a", "--", "make", "all"], + vec!["bear", "semantic", "--append", "--overwrite"], + vec!["bear", "semantic", "--overwrite", "--append"], + vec!["bear", "parse-sh", "--append", "--overwrite"], + vec!["bear", "parse-sh", "--overwrite", "--append"], + ]; + + for execution in executions { + let result = cli().try_get_matches_from(&execution); + + let error = result.expect_err(&format!("case {execution:?} must be rejected")); + assert_eq!(error.kind(), clap::error::ErrorKind::ArgumentConflict, "case {execution:?}"); + } + } + #[test] fn test_all_defaults() { let execution = vec!["bear", "--", "make", "all"]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/docs/rationale/append-default-migration.md new/Bear-4.2.2/docs/rationale/append-default-migration.md --- old/Bear-4.2.1/docs/rationale/append-default-migration.md 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/docs/rationale/append-default-migration.md 1970-01-01 01:00:00.000000000 +0100 @@ -0,0 +1,71 @@ +# Naming the overwrite behaviour before it stops being the default + +## Context + +Bear overwrites `compile_commands.json` by default and accumulates only +when asked. That default has one bad failure mode: a run that produces +no compiler invocations, because the build was already up to date or +because interception failed, replaces a good database with an empty one. +The user loses working data by running the tool successfully. The +intended fix is to make accumulation the default, so a run that captures +nothing leaves the previous database alone. + +Flipping a default is a compatibility break, and the scripts it breaks +are exactly those that never named the behaviour they depend on: a +packaging script or a CI job that runs Bear plainly and expects a fresh +database each time has no flag to point at. Nothing in the current +command line lets such a script say what it means. Until one exists, the +break has no migration path at all - the advice would be "wait for the +new release, then edit your scripts", with a window in which correct +scripts are silently wrong. + +So the flag has to exist before the default moves, which means shipping a +flag that changes nothing. Its whole value is time in the wild: it must +land early enough that a script can adopt it, be released, and reach +users, all before the default flips. + +Three naming options were on the table. `--no-append` pairs with the +existing flag and needs no new concept, but it names the new behaviour as +the absence of the old one, which reads backwards once accumulation is +the default. `--truncate` is the most precise verb, since it describes +what happens to the file rather than to the entries, but no build tool +spells it that way and it suggests a maintenance operation on the +database. `--overwrite` is what `compiledb` and `kubectl` use for the +same idea, so it is the spelling a user is most likely to guess. + +## Decision + +Ship `--overwrite` one release ahead of the default change, accepted +wherever `--append` is accepted and documented as naming the current +default. Reject the two together as a usage error rather than giving one +precedence over the other. + +There is no short form. `-o` is Bear's output path, so the letter +`compiledb` uses is unavailable, and inventing a different letter would +give users a short flag to misremember. + +## Consequences + +A script can become forward-compatible today, and it keeps working +unchanged across the default change. `--append` stays accepted +permanently afterwards, naming the new default, so a script that never +adapts also keeps working. The only invocations whose behaviour changes +are those that relied on the unnamed default. + +Rejecting the combination costs a script that passes both flags an +immediate failure. That is the point: the two flags state opposite +intents, and a precedence rule would let the contradiction survive the +default change, where it would quietly start losing entries or quietly +start keeping stale ones depending on which rule was chosen. + +The cost is a release in which a documented flag does nothing. A reader +of the code will find a parsed argument that is never inspected, which +looks like a bug; the parsing site carries a comment saying otherwise. + +Revisit when the default flips: at that point `--overwrite` becomes +load-bearing, and this entry becomes the record of why it predates the +behaviour it selects. + +## References + +- Requirements: `output-append` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/docs/requirements/output-append.md new/Bear-4.2.2/docs/requirements/output-append.md --- old/Bear-4.2.1/docs/requirements/output-append.md 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/docs/requirements/output-append.md 1970-01-01 01:00:00.000000000 +0100 @@ -18,6 +18,10 @@ the new entries (no error) - Without append mode, the output file is overwritten with only the new entries (the default behavior) +- Overwriting can also be requested explicitly, so a caller can state the + behavior it depends on instead of relying on the default +- Requesting appending and overwriting in the same invocation is a usage + error: Bear reports it and runs no build - When the existing file cannot be opened (e.g. permission denied), Bear returns an error and does not write output - When the existing file opens but contains invalid JSON or invalid entries, @@ -47,6 +51,16 @@ > When the user runs `bear -- <compiler> -c file2.c` (no `--append`), > then `compile_commands.json` contains only the entry for file2.c. +Given an existing `compile_commands.json` with an entry for file1.c: + +> When the user runs `bear --overwrite -- <compiler> -c file2.c`, +> then `compile_commands.json` contains only the entry for file2.c. + +Given any invocation that writes a compilation database: + +> When the user asks for both appending and overwriting at once, +> then Bear reports a usage error and does not run the build. + Given an existing `compile_commands.json` with corrupted JSON content: > When the user runs `bear --append -- <compiler> -c file1.c`, @@ -78,3 +92,4 @@ ## Rationale - [Latest compilation wins for a rebuilt file](../rationale/duplicate-latest-flags-win.md) +- [Naming the overwrite behaviour before it stops being the default](../rationale/append-default-migration.md) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/man/bear.1 new/Bear-4.2.2/man/bear.1 --- old/Bear-4.2.1/man/bear.1 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/man/bear.1 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ .\" Automatically generated by Pandoc 3.7.0.2 .\" -.TH "BEAR" "1" "August 16, 2026" "Bear User Manuals" +.TH "BEAR" "1" "September 5, 2026" "Bear User Manuals" .SH NAME bear \- generate a compilation database for Clang tooling .SH SYNOPSIS @@ -98,6 +98,16 @@ newest invocation survives duplicate filtering and replaces the stale entry (see \f[CR]duplicates\f[R] under CONFIGURATION). .TP +\f[B]\-\-overwrite\f[R] +Replace the output file with only this run\(cqs entries. +This is what Bear already does when neither flag is given; the flag +exists so a script can name the behaviour it depends on rather than rely +on the default. +Giving it together with \f[CR]\-\-append\f[R] is an error. +A future release makes appending the default, and a script that passes +\f[CR]\-\-overwrite\f[R] today keeps its current behaviour across that +change. +.TP \f[B]\-h, \-\-help\f[R] Print help. .TP @@ -138,6 +148,10 @@ \f[B]\-a, \-\-append\f[R] Same as in combined mode: place new entries before the existing ones in the output file. +.TP +\f[B]\-\-overwrite\f[R] +Same as in combined mode: name the current default explicitly. +Not accepted together with \f[CR]\-\-append\f[R]. .SS bear parse\-sh Produces the compilation database from shell command text, without running anything. @@ -165,6 +179,10 @@ Same as in combined mode: place new entries before the existing ones in the output file. .TP +\f[B]\-\-overwrite\f[R] +Same as in combined mode: name the current default explicitly. +Not accepted together with \f[CR]\-\-append\f[R]. +.TP \f[B]\-C, \-\-directory\f[R] \f[I]DIR\f[R] Initial working directory for the parsed commands. Use it for input captured elsewhere (a CI log, a dry run from another diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/man/bear.1.md new/Bear-4.2.2/man/bear.1.md --- old/Bear-4.2.1/man/bear.1.md 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/man/bear.1.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ % BEAR(1) Bear User Manuals % László Nagy -% August 16, 2026 +% September 5, 2026 <!-- to generate the final `bear.1` file, run `pandoc -s -t man bear.1.md -o bear.1` --> # NAME @@ -96,6 +96,14 @@ invocation survives duplicate filtering and replaces the stale entry (see `duplicates` under CONFIGURATION). +**\-\-overwrite** +: Replace the output file with only this run's entries. This is what +Bear already does when neither flag is given; the flag exists so a +script can name the behaviour it depends on rather than rely on the +default. Giving it together with `--append` is an error. A future +release makes appending the default, and a script that passes +`--overwrite` today keeps its current behaviour across that change. + **-h, \-\-help** : Print help. @@ -140,6 +148,10 @@ : Same as in combined mode: place new entries before the existing ones in the output file. +**\-\-overwrite** +: Same as in combined mode: name the current default explicitly. Not +accepted together with `--append`. + ## bear parse-sh Produces the compilation database from shell command text, without @@ -163,6 +175,10 @@ : Same as in combined mode: place new entries before the existing ones in the output file. +**\-\-overwrite** +: Same as in combined mode: name the current default explicitly. Not +accepted together with `--append`. + **-C, \-\-directory** *DIR* : Initial working directory for the parsed commands. Use it for input captured elsewhere (a CI log, a dry run from another checkout). Give an diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/site/src/reference/command-line.md new/Bear-4.2.2/site/src/reference/command-line.md --- old/Bear-4.2.1/site/src/reference/command-line.md 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/site/src/reference/command-line.md 1970-01-01 01:00:00.000000000 +0100 @@ -56,6 +56,7 @@ | `-c, --config <FILE>` | Path of the config file | - | | `-o, --output <FILE>` | Path of the result file | `compile_commands.json` | | `-a, --append` | Append result to an existing output file | - | +| `--overwrite` | Overwrite an existing output file (the default) | - | | `-h, --help` | Print help | - | | `-V, --version` | Print version | - | @@ -95,6 +96,7 @@ | `-i, --input <FILE>` | Path of the event file to read | `-` | | `-o, --output <FILE>` | Path of the result file | `compile_commands.json` | | `-a, --append` | Append result to an existing output file | - | +| `--overwrite` | Overwrite an existing output file (the default) | - | | `--print-compilers` | Print the compilers Bear recognizes and exit | - | | `-h, --help` | Print help | - | @@ -119,6 +121,7 @@ | `-i, --input <FILE>` | Path of the shell text to parse | `-` | | `-o, --output <FILE>` | Path of the result file | `compile_commands.json` | | `-a, --append` | Append result to an existing output file | - | +| `--overwrite` | Overwrite an existing output file (the default) | - | | `-C, --directory <DIR>` | Initial working directory for the parsed commands | - | | `-h, --help` | Print help | - | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Bear-4.2.1/tests/integration/tests/cases/compilation_output.rs new/Bear-4.2.2/tests/integration/tests/cases/compilation_output.rs --- old/Bear-4.2.1/tests/integration/tests/cases/compilation_output.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/Bear-4.2.2/tests/integration/tests/cases/compilation_output.rs 1970-01-01 01:00:00.000000000 +0100 @@ -9,7 +9,7 @@ use crate::fixtures::infrastructure::{ CompilationEntryMatcher, TestEnvironment, compilation_entry, filename_of, }; -use anyhow::Result; +use anyhow::{Context, Result}; #[cfg(target_family = "unix")] use serde_json::Value; @@ -202,53 +202,66 @@ Ok(()) } -/// Test output is overwritten when no append flag +/// Test the second run replaces the database, named or not +/// +/// `--overwrite` selects the behaviour that is already the default, so both +/// rows must end with only the second run's entry. The rows diverge again +/// when appending becomes the default: the bare one starts accumulating. // Requirements: output-append #[test] #[cfg(all(has_executable_compiler_c, has_executable_shell))] -fn without_append_output_is_overwritten() -> Result<()> { - let env = TestEnvironment::new("without_append_output_is_overwritten")?; - - // Create multiple source files - env.create_source_files(&[ - ("test1.c", "int func1() { return 1; }"), - ("test2.c", "int func2() { return 2; }"), - ])?; - - // Create build script that compiles all files - let build_command1 = format!("{} -c -o test1.o test1.c", filename_of(COMPILER_C_PATH)); - let build_script1_path = env.create_shell_script("build1.sh", &build_command1)?; - - let build_command2 = format!("{} -c -o test2.o test2.c", filename_of(COMPILER_C_PATH)); - let build_script2_path = env.create_shell_script("build2.sh", &build_command2)?; - - // Run bear once - env.run_bear_success(&[ - "--output", - "compile_commands.json", - "--", - SHELL_PATH, - build_script1_path.to_str().unwrap(), - ])?; - - // Verify compilation database - assert!(env.file_exists("compile_commands.json")); - let db = env.load_compilation_database("compile_commands.json")?; - db.assert_count(1)?; - - // Run bear again with append - env.run_bear_success(&[ - "--output", - "compile_commands.json", - "--", - SHELL_PATH, - build_script2_path.to_str().unwrap(), - ])?; - - // Verify compilation database - assert!(env.file_exists("compile_commands.json")); - let db = env.load_compilation_database("compile_commands.json")?; - db.assert_count(1)?; +fn second_run_overwrites_output() -> Result<()> { + // The flags the second run adds on top of `--output`. + let cases: [(&str, &[&str]); 2] = [ + ("without_append_output_is_overwritten", &[]), + ("overwrite_flag_overwrites_output", &["--overwrite"]), + ]; + + for (case, extra_flags) in cases { + let env = TestEnvironment::new(case)?; + + // Create multiple source files + env.create_source_files(&[ + ("test1.c", "int func1() { return 1; }"), + ("test2.c", "int func2() { return 2; }"), + ])?; + + // Create build scripts that compile one file each + let build_command1 = format!("{} -c -o test1.o test1.c", filename_of(COMPILER_C_PATH)); + let build_script1_path = env.create_shell_script("build1.sh", &build_command1)?; + + let build_command2 = format!("{} -c -o test2.o test2.c", filename_of(COMPILER_C_PATH)); + let build_script2_path = env.create_shell_script("build2.sh", &build_command2)?; + + // Run bear once + env.run_bear_success(&[ + "--output", + "compile_commands.json", + "--", + SHELL_PATH, + build_script1_path.to_str().unwrap(), + ])?; + + // Verify the first run landed + assert!(env.file_exists("compile_commands.json"), "case {case}"); + let db = env.load_compilation_database("compile_commands.json")?; + db.assert_count(1).with_context(|| format!("case {case} first run"))?; + db.assert_contains(&CompilationEntryMatcher::new().file("test1.c")) + .with_context(|| format!("case {case} first run"))?; + + // Run bear again over the same database + let mut arguments = vec!["--output", "compile_commands.json"]; + arguments.extend_from_slice(extra_flags); + arguments.extend_from_slice(&["--", SHELL_PATH, build_script2_path.to_str().unwrap()]); + env.run_bear_success(&arguments)?; + + // Verify only the second run survives + assert!(env.file_exists("compile_commands.json"), "case {case}"); + let db = env.load_compilation_database("compile_commands.json")?; + db.assert_count(1).with_context(|| format!("case {case} second run"))?; + db.assert_contains(&CompilationEntryMatcher::new().file("test2.c")) + .with_context(|| format!("case {case} second run must replace the first"))?; + } Ok(()) } @@ -971,14 +984,25 @@ // Use command_bear() directly so we can force RUST_LOG=debug without // touching the test process env (which would race with parallel tests). + // + // `CFLAGS` carries a flag that names GCC, to reproduce #716: the debug + // log dumps the intercepted execution's environment, so a build + // environment that merely mentions GCC (as a Gentoo package build does) + // must not read as "the GCC interpreter recognized this command". + // + // It has to be a flags variable rather than `CC`, which is how the + // reported build spelled it. `CC` is a program variable: in wrapper mode + // the runner resolves its value on PATH, so a Gentoo triplet name would + // log a resolution warning on every other distro. `CFLAGS` reaches the + // log through the same env filter (`intercept::environment`) without + // ever being resolved or folded into the recorded arguments, so the + // reproduction costs nothing on hosts that have no such compiler. let mut cmd = env.command_bear(); - cmd.current_dir(env.test_dir()).env("RUST_LOG", "debug").env("RUST_BACKTRACE", "1").args([ - "--output", - "compile_commands.json", - "--", - SHELL_PATH, - script.to_str().unwrap(), - ]); + cmd.current_dir(env.test_dir()) + .env("RUST_LOG", "debug") + .env("RUST_BACKTRACE", "1") + .env("CFLAGS", "-frecord-gcc-switches") + .args(["--output", "compile_commands.json", "--", SHELL_PATH, script.to_str().unwrap()]); let output = cmd.output()?; let stderr = String::from_utf8_lossy(&output.stderr); assert!(output.status.success(), "bear failed:\n{}", stderr); @@ -995,20 +1019,15 @@ // parses the command, and `gcc : Recognized(...)` if the // GCC flag table did. We assert the former is present and the latter is // absent for this run. - // - // Note: we look for "Recognized(" specifically to ignore any unrelated - // log lines that might mention the id in passing (e.g. the probe's - // "clang version" reading of `cc --version`). - let saw_clang_recognized = stderr.lines().any(|l| l.contains("clang") && l.contains("Recognized(")); - let saw_gcc_recognized = stderr.lines().any(|l| l.contains("gcc") && l.contains("Recognized(")); + let recognized = interpreters_that_recognized(&stderr); assert!( - saw_clang_recognized, + recognized.contains(&"clang"), "expected a `clang ... Recognized(` log line proving probe dispatched to Clang.\nstderr:\n{}", stderr ); assert!( - !saw_gcc_recognized, + !recognized.contains(&"gcc"), "did not expect a `gcc ... Recognized(` log line; that would mean the probe was bypassed and the regex fell back to GCC.\nstderr:\n{}", stderr ); @@ -1016,6 +1035,51 @@ Ok(()) } +/// Collect the interpreter ids that reported a `Recognized` verdict in a +/// debug log, as emitted by the `OutputLogger` combinator: +/// +/// ```text +/// [... semantic::interpreters::combinators] clang : Recognized(Command { ... }) +/// ``` +/// +/// The id and the verdict are matched positionally, not by substring: both +/// the `Execution` dump of a `NotRecognized(...)` verdict and the build +/// environment it carries can mention a compiler id in passing (a Gentoo +/// build sets `CC=x86_64-pc-linux-gnu-gcc` and `CFLAGS=-frecord-gcc-switches`, +/// for instance), and `NotRecognized(` itself ends in `Recognized(`. +fn interpreters_that_recognized(stderr: &str) -> Vec<&str> { + stderr + .lines() + .filter_map(|line| line.split_once("combinators] ")) + .filter_map(|(_, entry)| entry.split_once(": ")) + .filter(|(_, verdict)| verdict.starts_with("Recognized(")) + .map(|(id, _)| id.trim_end()) + .collect() +} + +/// Regression guard for #716: the probe test above read the debug log with +/// plain `contains` checks, so a `NotRecognized` line whose environment dump +/// mentioned GCC (the Gentoo package build sets `CC=x86_64-pc-linux-gnu-gcc`) +/// read as "the probe fell back to GCC" and failed the test on a run where +/// the probe had in fact dispatched to Clang. The lines below are taken from +/// that build log. +// Requirements: recognition-ambiguous-name-probe +#[test] +fn recognized_ids_come_from_the_verdict_not_the_execution_dump() { + let log = concat!( + "[21:17:10.137 DEBUG bear[2649] semantic::interpreters::combinators] coreutils_to_ignore : ", + "NotRecognized(Execution { executable: \"/tmp/fake-cc/cc\", arguments: [\"cc\", \"-c\", ", + "\"hello.c\"], environment: {\"CC\": \"x86_64-pc-linux-gnu-gcc\", \"CFLAGS\": ", + "\"-O2 -ggdb3 -frecord-gcc-switches\"} })\n", + "[21:17:10.142 DEBUG bear[2649] semantic::interpreters::combinators] clang : ", + "Recognized(Command { executable: \"/tmp/fake-cc/cc\", source_mode: PerSourceStripped })\n", + ); + + let sut = interpreters_that_recognized(log); + + assert_eq!(sut, vec!["clang"], "only the Recognized verdict's own id counts, got {sut:?}"); +} + /// Regression guard for #532: --append was unusable on large projects in the /// 3.x C++ implementation. The Rust rewrite (output-append.md) made it linear /// but no test enforces the scaling property -- the requirement file cites ++++++ _service ++++++ --- /var/tmp/diff_new_pack.YbdeGX/_old 2026-09-17 15:21:28.842167303 +0200 +++ /var/tmp/diff_new_pack.YbdeGX/_new 2026-09-17 15:21:28.847167513 +0200 @@ -1,7 +1,7 @@ <services> <service name="cargo_vendor" mode="manual"> <param name="src">https://github.com/rizsotto/Bear.git</param> - <param name="revision">4.2.1</param> + <param name="revision">4.2.2</param> <param name="update">true</param> <param name="filter">true</param> </service> ++++++ vendor.tar.zst ++++++ ++++ 1272806 lines of diff (skipped)
