55 lines
1.6 KiB
Nix
55 lines
1.6 KiB
Nix
{ lib }:
|
|
|
|
with builtins;
|
|
|
|
rec {
|
|
|
|
# Derive a file by substituting
|
|
# "${pkgs.foo}/bin/foo" for each {-pkg-}"foo", and
|
|
# "${pkgs.bar}/bin/foo" for each {-pkg:bar-}"foo".
|
|
# If a package doesn't exist, a warning gets printed.
|
|
substitutePkgs = name: { callsite ? null, pkgs, path }:
|
|
let
|
|
sourceDescription =
|
|
if callsite != null then
|
|
"${name} in ${toString callsite}"
|
|
else
|
|
"${name} from ${toString path}";
|
|
|
|
f = dependencies: s:
|
|
let
|
|
parse = match "(.*)([{]-pkg(:([^}]+))?-[}]\"([^\"]+)\")(.*)" s;
|
|
prefix = elemAt parse 0;
|
|
pname = if elemAt parse 3 != null then elemAt parse 3 else exename;
|
|
exename = elemAt parse 4;
|
|
suffix = elemAt parse 5;
|
|
pkg = pkgs.${pname} or null;
|
|
|
|
substitute =
|
|
if pkg != null then
|
|
"${pkg}/bin/${exename}"
|
|
else
|
|
trace (toString [
|
|
"lib.haskell.substitutePkgs:"
|
|
"warning:"
|
|
"while deriving ${sourceDescription}:"
|
|
"no substitute found for ${elemAt parse 1}"
|
|
])
|
|
exename;
|
|
in
|
|
if parse == null then
|
|
(pkgs.writeText name s).overrideAttrs (old: {
|
|
dependencies =
|
|
lib.uniq
|
|
(lib.sort (lib.on lib.lessThan (lib.getAttr "name"))
|
|
(filter
|
|
(lib.ne null)
|
|
(old.dependencies or [] ++ dependencies)));
|
|
})
|
|
|
|
else
|
|
f (dependencies ++ [pkg]) (prefix + toJSON substitute + suffix);
|
|
in
|
|
f [] (readFile path);
|
|
}
|