add pkgs support to static-nix-shell and use it for gpodder

This commit is contained in:
Colin 2023-04-27 08:00:38 +00:00
parent 2f375b7778
commit 1e6e41a9cb
4 changed files with 57 additions and 25 deletions

View File

@ -2,6 +2,7 @@
with next; with next;
let let
sane = rec { sane = rec {
sane-lib = import ../modules/lib next;
#### my own, non-upstreamable packages: #### my own, non-upstreamable packages:
static-nix-shell = callPackages ../pkgs/static-nix-shell { }; static-nix-shell = callPackages ../pkgs/static-nix-shell { };
sane-scripts = callPackage ../pkgs/sane-scripts { }; sane-scripts = callPackage ../pkgs/sane-scripts { };

View File

@ -3,26 +3,20 @@
, gpodder , gpodder
, makeWrapper , makeWrapper
, python3 , python3
, static-nix-shell
, symlinkJoin , symlinkJoin
}: }:
let let
pyEnv = python3.withPackages (_ps: [ gnome-feeds.listparser ]); remove-extra = static-nix-shell.mkPython3Bin {
remove-extra = stdenv.mkDerivation {
pname = "gpodder-remove-extra"; pname = "gpodder-remove-extra";
version = "0.1.0";
src = ./.; src = ./.;
pyPkgs = _ps: {
patchPhase = '' "gnome-feeds.listparser" = gnome-feeds.listparser;
substituteInPlace ./remove_extra.py \ };
--replace "#!/usr/bin/env nix-shell" "#!${pyEnv.interpreter}" pkgs = {
''; inherit gpodder;
};
installPhase = ''
mkdir -p $out/bin
mv remove_extra.py $out/bin/gpodder-remove-extra
'';
}; };
in in
# we use a symlinkJoin so that we can inherit the .desktop and icon files from the original gPodder # we use a symlinkJoin so that we can inherit the .desktop and icon files from the original gPodder

View File

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [gnome-feeds.listparser])" -p gpodder #!nix-shell -i python3 -p "python3.withPackages (ps: [ gnome-feeds.listparser ])" -p gpodder
from dataclasses import dataclass, field from dataclasses import dataclass, field
import listparser import listparser

View File

@ -1,30 +1,67 @@
{ stdenv { pkgs
, lib
, python3 , python3
, sane-lib
, stdenv
}: }:
{ let
inherit (builtins) attrNames attrValues concatStringsSep map typeOf;
inherit (lib) concatMapAttrs;
inherit (sane-lib) mapToAttrs;
pkgs' = pkgs;
in {
# transform a file which uses `#!/usr/bin/env nix-shell` shebang with a `python3` interpreter # transform a file which uses `#!/usr/bin/env nix-shell` shebang with a `python3` interpreter
# into a derivation that can be built statically # into a derivation that can be built statically.
mkPython3Bin = { pname, pyPkgs ? [], srcPath ? pname, ... }@attrs: stdenv.mkDerivation ( #
# pkgs and pyPkgs may take the following form:
# - [ "pkgNameA" "pkgNameB" ... ]
# - { pkgNameA = pkgValueA; pkgNameB = pkgValueB; ... }
# - ps: <evaluate to one of the above exprs>
#
# for pyPkgs, names are assumed to be relative to `"ps"` if specified in list form.
mkPython3Bin = { pname, pkgs ? {}, pyPkgs ? {}, srcPath ? pname, ... }@attrs:
let let
evalPyPkgs = ps: builtins.map (name: ps."${name}") pyPkgs; # create an attrset of
pyEnv = python3.withPackages evalPyPkgs; # <name> = expected string in the nix-shell invocation
pyPkgsStr = builtins.concatStringsSep " " (builtins.map (p: "ps.${p}") pyPkgs); # <value> = package to provide
in { pkgsToAttrs = prefix: pkgSet: expr: ({
"lambda" = expr: pkgsToAttrs prefix pkgSet (expr pkgSet);
"list" = expr: mapToAttrs (pname: {
name = prefix + pname;
value = pkgSet."${pname}";
}) expr;
"set" = expr: expr;
})."${typeOf expr}" expr;
pyEnv = python3.withPackages (ps: attrValues (
pkgsToAttrs "ps." ps pyPkgs
));
pyPkgsStr = concatStringsSep " " (attrNames (
pkgsToAttrs "ps." {} pyPkgs
));
pkgsAsAttrs = pkgsToAttrs "" pkgs' pkgs;
pkgsEnv = attrValues pkgsAsAttrs;
pkgsStr = concatStringsSep "" (map
(pname: " -p ${pname}")
(attrNames pkgsAsAttrs)
);
in stdenv.mkDerivation ({
version = "0.1.0"; # default version version = "0.1.0"; # default version
patchPhase = '' patchPhase = ''
substituteInPlace ${srcPath} \ substituteInPlace ${srcPath} \
--replace '#!/usr/bin/env nix-shell' '#!${pyEnv.interpreter}' \ --replace '#!/usr/bin/env nix-shell' '#!${pyEnv.interpreter}' \
--replace \ --replace \
'#!nix-shell -i python3 -p "python3.withPackages (ps: [ ${pyPkgsStr} ])"' \ '#!nix-shell -i python3 -p "python3.withPackages (ps: [ ${pyPkgsStr} ])"${pkgsStr}' \
'# nix deps evaluated statically' '# nix deps evaluated statically'
''; '';
runtimeDependencies = pkgsEnv;
installPhase = '' installPhase = ''
mkdir -p $out/bin mkdir -p $out/bin
mv ${srcPath} $out/bin/${srcPath} mv ${srcPath} $out/bin/${srcPath}
# ensure that all nix-shell references were substituted # ensure that all nix-shell references were substituted
! grep nix-shell $out/bin/${srcPath} ! grep nix-shell $out/bin/${srcPath}
''; '';
} // attrs } // (removeAttrs attrs [ "pkgs" "pyPkgs" "srcPath" ])
); );
} }