Turning a simple non-nix python script into something nix-friendly can be pretty easy:
# flake.nix
{
description = "A very basic python script";
outputs = {
self,
nixpkgs,
}: let
pkgs = import nixpkgs {system = "aarch64-darwin";};
in {
packages.aarch64-darwin.default = pkgs.writers.writePython3Bin "say_hello" {} ./hello.py;
apps.aarch64-darwin.default = {
type = "app";
program = "${self.outputs.packages.aarch64-darwin.default}/bin/say_hello";
};
};
}
# hello.py
print("hello, world")
Result:
$ nix run
hello world
However, I’m having trouble making the simplest substitution – without changing hello.py
, what’s the best way to have it output hello there n8henrie
?
At first, I thought something like this should work:
packages.aarch64-darwin.default =
(
pkgs.writers.writePython3Bin "say_hello" {} ./hello.py
)
.overrideAttrs (old: {
patchPhase = "sed -i 's/world/there n8henrie/g' $out" + (old.patchPhase or "");
});
I had anticipated an error (perhaps I need to use $src
instead of $out
) but I get no error, and no change in output. I guess this is because phases is undefined? Adding phases = ["patchPhase"];
changes nothing. So I guess this writer doesn’t come from mkDerivation
? No, looks like it comes from runCommandLocal
which comes from runCommandWith
which uses mkDerivation
.
So then I thought perhaps I could use pkgs.substitute
; but then I ran into build-support/substitute does not allow spaces in arguments · Issue #178438 · NixOS/nixpkgs · GitHub , which I initially thought I could make a PR to fix and eventually gave up.
So then I gave up and just used runCommandLocal
to give me access to the substitute
function, which then required a builtins.readFile
:
pkgs.writers.writePython3Bin "say_hello" { }
(builtins.readFile (pkgs.runCommandLocal "script-text" {}
''
substitute ${./hello.py} $out \
--replace 'world' 'there n8henrie'
''));
Am I missing something here? If you had a perfectly dandy python script whose content you did not want to change, is there a better way to make a simple subtitution and still enjoy the simplicity of pkgs.writers
?
I really was hoping that the overrideAttrs
approach was going to work!