Skip to content

fix patchShebangs in the presence of readonly scripts#462319

Open
bmillwood wants to merge 4 commits intoNixOS:stagingfrom
bmillwood:bmillwood/fix-patch-shebangs-chmod-w
Open

fix patchShebangs in the presence of readonly scripts#462319
bmillwood wants to merge 4 commits intoNixOS:stagingfrom
bmillwood:bmillwood/fix-patch-shebangs-chmod-w

Conversation

@bmillwood
Copy link
Contributor

@bmillwood bmillwood commented Nov 16, 2025

  • Fixes patchShebangs: fails with "chmod: [script]: new permissions are [...], not [...]" #462298
  • Replaces chmod -w with chmod u-w (and likewise +w) in patch-shebangs.sh, so that the only permission we touch is the one that we tested (and the one that we need). Restoring the mode just wasn't working correctly before, because -w isn't an inverse of +w (except in special cases). As documented in the issue, this is necessary to fix working on scripts with mode 575 (though who uses those?)
    • Added a test case that catches this.
  • Fixes restoreReadOnly stale value by resetting it to an empty string on every loop iteration. This was a much more serious problem, leading the hook to break on scripts with mode 777 as long as you'd already seen a readonly script earlier this invocation.
    • Testing this requires a single invocation of patchShebangs that visits a readonly file before a read-write one. In general the order of patchShebangs is the order of the embedded find operation, which is nondeterministic, but I think find processes its command line arguments in order, so you could do something like patchShebangs test-555 test-777 and I think that would do it. This would feel very specific to this one bug, though, and unlikely to be useful in future.

Testing this comprehensively is made more tricky by the fact that modifying this script forces a rebuild of everything. I worked around this by copying the fixed script to another location and replacing the line in the test that sources the real script with one that sources my fixed script (and cherry-picking all my test changes). The test passes in this setup (and fails on the original script).

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@bmillwood bmillwood changed the title update patch-shebangs read-only-script test to catch #462298 fix patchShebangs on scripts with mode 575 Nov 16, 2025
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. labels Nov 16, 2025
@bmillwood bmillwood changed the base branch from master to staging November 16, 2025 19:45
@nixpkgs-ci nixpkgs-ci bot closed this Nov 16, 2025
@nixpkgs-ci nixpkgs-ci bot reopened this Nov 16, 2025
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 78288a2 to 38ed43c Compare November 16, 2025 19:46
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. and removed 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. labels Nov 16, 2025
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 93afe11 to b871d5c Compare November 16, 2025 19:57
@bmillwood bmillwood marked this pull request as ready for review November 16, 2025 22:26
@nixpkgs-ci nixpkgs-ci bot requested a review from Ericson2314 November 16, 2025 22:28
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from b871d5c to 92fc366 Compare November 16, 2025 22:41
@bmillwood bmillwood changed the title fix patchShebangs on scripts with mode 575 fix patchShebangs in the presence of readonly scripts Nov 16, 2025
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from ba73e35 to 2a65f52 Compare November 16, 2025 23:39
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch 3 times, most recently from ed192a1 to d1220da Compare November 22, 2025 23:57
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from d1220da to 4febaeb Compare November 29, 2025 16:16
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/6107

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can actually prevent the problem of too many rebuilds on each change by using bootstrapTools for the builder, as I did here: https://github.com/NixOS/nixpkgs/pull/411981/files#diff-d762697454f1be50b0e3ba17fe71962baef159923f79b79e2471b0060408fa08

@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 9eef219 to d61930c Compare January 4, 2026 12:47
Copy link
Contributor

@doronbehar doronbehar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me in general, though I haven't tested or verified the modified test is fixed by the latter commits.

@doronbehar
Copy link
Contributor

Hmm maybe GitHub is fooling me?

@doronbehar
Copy link
Contributor

It is not. Checked out locally the commits and saw the same issue.

@bmillwood
Copy link
Contributor Author

oh, but you are reviewing the individual commits, not just the PR diff? I'm not sure what the convention is here but I've been assuming that only the final state is important (e.g. if someone doesn't like something about my PR, it is sufficient to add a new commit addressing their comment, rather than rewriting old commits to do so)

@doronbehar
Copy link
Contributor

oh, but you are reviewing the individual commits, not just the PR diff?

Correct.

I'm not sure what the convention is here

This is under debate:

And I should admit that I'm reviewing according to my own conventions which are a pretty similar to what's suggested there :).

but I've been assuming that only the final state is important (e.g. if someone doesn't like something about my PR, it is sufficient to add a new commit addressing their comment, rather than rewriting old commits to do so)

I think that there is value to multiple commits in a PR, because often some commits are justified no matter what are the other commits. However sometimes the latter commits are the main goal of the PR.

In this PR, the separation makes sense too because your are fixing multiple issues that are related. I just think that when doing that there's value in minimizing diff noise such as noted above.

@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Feb 1, 2026
@doronbehar doronbehar force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from d61930c to a0d35ac Compare February 2, 2026 13:08
@doronbehar
Copy link
Contributor

@bmillwood I fixed the merge conflicts and fixed the comments I had before.

@doronbehar doronbehar requested a review from qweered February 2, 2026 13:08
@nixpkgs-ci nixpkgs-ci bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Feb 2, 2026
@doronbehar doronbehar force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from a0d35ac to 5a02951 Compare February 2, 2026 15:05
Comment on lines +136 to +140
if [[ ! -w "$f" ]]; then
chmod u+w "$f"
restoreReadOnly=true
else
restoreReadOnly=false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This style fits the style used for other variables, that are not necessarily declared as local.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This style fits the style used for other variables, that are not necessarily declared as local.

@bmillwood what do you think about using explicit true & false strings for restoreReadOnly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose the fix that involved a smaller diff to the code I was modifying. The thing you propose would work too, but I don't see a strong enough reason to prefer it.

@philiptaron philiptaron self-requested a review February 2, 2026 15:25
@bmillwood
Copy link
Contributor Author

@bmillwood I fixed the merge conflicts and fixed the comments I had before.

I didn't realise you were even able to push commits to my fork!

Anyway, I appreciate you trying to be helpful but:

  • the previous state of the PR had already been approved by someone else, so I don't know if I want to change it to match your desired style,
  • your new push contains changes that you wrote, but attributed to me; if you do this please attribute them to yourself instead.

@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 5a02951 to d61930c Compare February 2, 2026 15:37
@bmillwood
Copy link
Contributor Author

(I pushed back my own changes in the meantime, but possibly once I've seen yours I'll restore them)

@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch 2 times, most recently from a8901c7 to 4cb4aed Compare February 2, 2026 15:50
@bmillwood
Copy link
Contributor Author

bmillwood commented Feb 2, 2026

I rebased my changes and applied one of your comments. The other one I don't think is an improvement. [edit: and you rightly pointed out you'd proposed a third one that I'd forgotten about; commented on that one as well.]

(To be honest, I think the other one was also probably too minor to be spending either of our time on, but I did it anyway to avoid spending any more time on it.)

Resolves NixOS#462298. chmod -w can report exit status 1 if it removes user
write but not group write permissions (as it does if the umask contains
group write). Specifically targeting user write avoids this issue and is
what we want anyway.
Also the test now uses a single patchShebangs invocation for all the
files, since I just found a bug that only arises when processing
multiple files.
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 4cb4aed to 4097204 Compare February 17, 2026 18:00
`local` means function-local, not loop-local, so
`restoreReadOnly` was staying true forever after being set true the
first time.
@bmillwood bmillwood force-pushed the bmillwood/fix-patch-shebangs-chmod-w branch from 4097204 to 560f431 Compare February 17, 2026 18:18
echo "Permissions changed from $original_perms to $new_perms"
exit 1
fi
modes=(555 575 755 775 777)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bmillwood Reading this again, I was thinking maybe the test should be renamed to preserve-permissions to reflect it doesn't only test read-only scripts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch. 12.approvals: 1 This PR was reviewed and approved by one person.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants