patch-shebangs: add a flag to update shebangs with store paths

This change adds a flag to update shebang paths that point to the Nix
store. This is particularly useful when a cross-compiled package uses
same script at compile-time and run-time, but the interpreter must be
changed since hostPlatform != buildPlatform.
This commit is contained in:
Ivan Trubach 2023-06-19 08:56:21 +03:00
parent c1bca7fe84
commit ebd4619053
2 changed files with 49 additions and 10 deletions

View file

@ -11,11 +11,12 @@ fixupOutputHooks+=(patchShebangsAuto)
# Run patch shebangs on a directory or file.
# Can take multiple paths as arguments.
# patchShebangs [--build | --host] PATH...
# patchShebangs [--build | --host | --update] [--] PATH...
# Flags:
# --build : Lookup commands available at build-time
# --host : Lookup commands available at runtime
# --update : Update shebang paths that are in Nix store
# Example use cases,
# $ patchShebangs --host /nix/store/...-hello-1.0/bin
@ -23,14 +24,35 @@ fixupOutputHooks+=(patchShebangsAuto)
patchShebangs() {
local pathName
local update
if [[ "$1" == "--host" ]]; then
pathName=HOST_PATH
shift
elif [[ "$1" == "--build" ]]; then
pathName=PATH
shift
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--host)
pathName=HOST_PATH
shift
;;
--build)
pathName=PATH
shift
;;
--update)
update=true
shift
;;
--)
shift
break
;;
-*|--*)
echo "Unknown option $1 supplied to patchShebangs" >&2
return 1
;;
*)
break
;;
esac
done
echo "patching script interpreter paths in $@"
local f
@ -93,7 +115,7 @@ patchShebangs() {
newInterpreterLine="$newPath $args"
newInterpreterLine=${newInterpreterLine%${newInterpreterLine##*[![:space:]]}}
if [[ -n "$oldPath" && "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ]]; then
if [[ -n "$oldPath" && ( "$update" == true || "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ) ]]; then
if [[ -n "$newPath" && "$newPath" != "$oldPath" ]]; then
echo "$f: interpreter directive changed from \"$oldInterpreterLine\" to \"$newInterpreterLine\""
# escape the escape chars so that sed doesn't interpret them

View file

@ -39,6 +39,23 @@ let
};
};
updates-nix-store = stdenv.mkDerivation {
name = "updates-nix-store";
strictDeps = false;
dontUnpack = true;
installPhase = ''
mkdir -p $out/bin
echo "#!$NIX_STORE/path/to/bash" > $out/bin/test
echo "echo -n hello" >> $out/bin/test
chmod +x $out/bin/test
patchShebangs --update $out/bin/test
dontPatchShebangs=1
'';
passthru = {
assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null";
};
};
split-string = stdenv.mkDerivation {
name = "split-string";
strictDeps = false;
@ -59,7 +76,7 @@ let
in
stdenv.mkDerivation {
name = "test-patch-shebangs";
passthru = { inherit (tests) bad-shebang ignores-nix-store split-string; };
passthru = { inherit (tests) bad-shebang ignores-nix-store updates-nix-store split-string; };
buildCommand = ''
validate() {
local name=$1