Two pre-existing behaviours found by an adversarial review during the Rust-migration wrap-up. Both inherited from the Go implementation, both untested, filed rather than changed inline because each alters observable semantics.
1. -o does not preserve the input's mode
src/cli.rs::write_output uses std::fs::write, which creates the output with the default mode. Verified: input -rwxr-xr-x, -o out.sh produces -rw-r--r--. So macbash -o ./fixed/ scripts/*.sh yields a directory of non-executable scripts.
-w in place DOES preserve the mode (it writes through the existing inode), so the two output modes disagree.
Fix: read the input's permissions and apply them to the output after writing.
2. One unreadable file discards every other file's results
src/scanner.rs::scan_files returns Err on the first failure, so a single non-UTF-8, unreadable, or directory argument aborts the whole run and exits 1 -- indistinguishable from "found errors".
Verified: macbash <latin1-file> tests/fixtures/sample-linux.sh reports Error: scanning files: reading ...: stream did not contain valid UTF-8 and says nothing about the good file.
Fix: collect per-file errors, report them to stderr, scan the rest, and reserve the abort for the case where nothing could be read. Whichever way it lands, it wants a test pinning the choice.
Also worth a decision
-w follows a symlink and rewrites the target (verified: link preserved, target rewritten). Defensible for an in-place editor, but macbash -w **/*.sh in a tree containing a symlink writes outside that tree. There is no --no-follow.
Two pre-existing behaviours found by an adversarial review during the Rust-migration wrap-up. Both inherited from the Go implementation, both untested, filed rather than changed inline because each alters observable semantics.
1.
-odoes not preserve the input's modesrc/cli.rs::write_outputusesstd::fs::write, which creates the output with the default mode. Verified: input-rwxr-xr-x,-o out.shproduces-rw-r--r--. Somacbash -o ./fixed/ scripts/*.shyields a directory of non-executable scripts.-win place DOES preserve the mode (it writes through the existing inode), so the two output modes disagree.Fix: read the input's permissions and apply them to the output after writing.
2. One unreadable file discards every other file's results
src/scanner.rs::scan_filesreturnsErron the first failure, so a single non-UTF-8, unreadable, or directory argument aborts the whole run and exits 1 -- indistinguishable from "found errors".Verified:
macbash <latin1-file> tests/fixtures/sample-linux.shreportsError: scanning files: reading ...: stream did not contain valid UTF-8and says nothing about the good file.Fix: collect per-file errors, report them to stderr, scan the rest, and reserve the abort for the case where nothing could be read. Whichever way it lands, it wants a test pinning the choice.
Also worth a decision
-wfollows a symlink and rewrites the target (verified: link preserved, target rewritten). Defensible for an in-place editor, butmacbash -w **/*.shin a tree containing a symlink writes outside that tree. There is no--no-follow.