feat: add --must-match to exit non-zero when nothing matched - #347
Open
vlasky wants to merge 1 commit into
Open
Conversation
sd exits 0 whether or not the pattern matched, mirroring sed. That makes a typo in the pattern indistinguishable from a file that needed no changes, which is a problem for scripts and CI where a vacuous edit passes silently. Add an opt-in -m/--must-match flag that exits 2 when the pattern matched none of the input. The default is unchanged, per the discussion in chmln#157. Errors keep status 1 so a caller can tell "found nothing" apart from "could not run", and the status covers the run as a whole, so one matching input out of several is enough to succeed. process_sources and its helpers now return whether anything matched, taken from the Cow variant that replace already returns, so no extra scan is needed. The exit-status policy stays in the CLI. Closes chmln#157
This was referenced Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #157.
Problem
sdexits 0 whether or not the pattern matched, mirroringsed. That makes a typo in the pattern indistinguishable from a file that genuinely needed no changes:In a script or CI job, a vacuous edit passes silently. As noted on #157, this is troublesome enough that people fall back to
sedto detect whether anything was replaced.Change
An opt-in
-m/--must-matchflag that exits 2 when the pattern matched none of the input:The default is deliberately unchanged. On #157 @CosmicHorrorDev wrote:
and
so this is that flag rather than a change of default.
Design points:
sd -m ... *.rsinvocation wants.Replacer::replacealready returnsCow::Borrowedwhen the pattern did not match andCow::Ownedotherwise, so the variant answers the question without a second scan. That contract is now documented onreplace.process_sourcesand its helpers returnResult<bool>reporting whether anything matched, leaving the exit-status policy in the CLI.Testing
11 new tests, taking the workspace from 48 to 60. Three at the library level for the returned
bool, and eight CLI tests covering: default unchanged (exit 0 for both a matching and a non-matching run, file and stdin),--must-matchwith and without a match, stdin,-p,-A, a multi-file run where only one file matches, and that an error still exits 1 rather than 2. Each behavioural case is exercised through both the line-by-line and whole-file paths.cargo fmt --checkandcargo clippy --workspace --all-targets -- -D warningsare clean.gen/completions and the man page are regenerated viacargo run -p xtask -- gen.Notes
CHANGELOG.mdalone, since its history looks like maintainer-written release prep. Happy to add an entry if you would prefer it in the PR.