Skip to content

-o drops the executable bit; one unreadable file aborts the whole run #9

Description

@catinspace-au

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions