diff options
| -rw-r--r-- | pkgs/populate/default.nix | 42 | ||||
| -rw-r--r-- | tests/scenarios.nix | 39 |
2 files changed, 65 insertions, 16 deletions
diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix index ce17305..c707b7c 100644 --- a/pkgs/populate/default.nix +++ b/pkgs/populate/default.nix @@ -236,12 +236,34 @@ let throw "krops: source ${name} draws inputs from missing source ${source}" else source; + # Where the input at path, a list of input names, of the flake in the + # source named name is in the flake that the source's inputs get drawn + # into: the flake itself, or its generated flake. On the way, inputs + # that get drawn from sources are the flakes of those sources, where + # drawing went on, so the path continues there. A generated flake has + # its source and the sources that one draws from as inputs, and nothing + # else, so the path names them there. + drawnPath = name: path: let + follows = flakeFollows sources.${name}; + parents = filter + (prefix: any (x: x.path == prefix) follows) + (map (n: take n path) (range 1 (length path - 1))); + parent = last parents; + from = (findFirst (x: x.path == parent) null follows).source; + rest = drawnPath from (drop (length parent) path); + in + if generated ? ${name} then + if parents == [] then [ (inputName name) ] ++ path + else [ (inputName from) ] ++ rest + else + if parents == [] then path + else parent ++ rest; # Sets the positional parameters to nix flake lock's arguments for # drawing the inputs of the flake in source name from other sources. overrideArgs = name: /* sh */ '' set -- ${concatMapStrings (x: /* sh */ '' - set -- "$@" --override-input ${quote (concatStringsSep "/" x.path)} ${url (check name x.source)} + set -- "$@" --override-input ${quote (concatStringsSep "/" (drawnPath name x.path))} ${url (check name x.source)} '') (flakeFollows sources.${name})} ''; # Rewrites the lock file of the flake in a file or git source in place. @@ -381,21 +403,9 @@ let # Nix ignores overrides below an input that follows another input, so # an input of an input drawn from a source gets overridden at that # source. - override = x: let - drawnParents = filter - (path: any (y: y.path == path) follows) - (map (n: take n x.path) (range 1 (length x.path - 1))); - parent = if drawnParents == [] then null else last drawnParents; - base = - if parent == null then name - else (findFirst (y: y.path == parent) null follows).source; - rest = if parent == null then x.path else drop (length parent) x.path; - in - "inputs.${toJSON (inputName base)}" + - # A source with a generated flake has itself as input therein. - optionalString (parent != null && generated ? ${base}) - ".inputs.${toJSON (inputName base)}" + - concatMapStrings (name: ".inputs.${toJSON name}") rest + + override = x: + "inputs." + + concatMapStringsSep ".inputs." toJSON (drawnPath name x.path) + ".follows = ${toJSON (inputName x.source)};"; in /* sh */ '' ( diff --git a/tests/scenarios.nix b/tests/scenarios.nix index a7dff66..d4df931 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -1385,6 +1385,45 @@ assert !(krops.isLocalTarget (targets.remote "/")); ''; }; })) + # The same one level deeper: the input gets drawn from a source below + # an input that the source in between draws from a source itself. + (modes "override-deep" ({ draw, flake, ... }: { + phases = twice { + sources = { + x.flake = { + url = "/fixtures/top"; inherit fetchOnTarget; + } // draw { dep = { follows = "b"; inputs.p.inputs.z.follows = "c2"; }; }; + b.file = { path = "/fixtures/two"; } // draw { p.follows = "c3"; }; + c2.file = "/fixtures/c2"; + c3.file = "/fixtures/c3"; + }; + check = '' + expect_eq msg "$(nix_eval_online ${flake "x"}#msg)" 'top:two:c3(c2)+inner,sub' + ''; + }; + })) + # A source with a rewritten lock file draws an input from a source with + # a generated flake, and an input below it from another source. + (s "override-mixed" { + phases = twice { + sources = { + x.flake = { + url = "/fixtures/top"; inherit fetchOnTarget; + inputs.dep = { follows = "b"; inputs.q.follows = "c2"; }; + }; + b.file = { + path = "/fixtures/two"; + rewriteLock = false; + inputs.p.follows = "c1"; + }; + c1.file = "/fixtures/c1"; + c2.file = "/fixtures/c2"; + }; + check = '' + expect_eq msg "$(nix_eval_online "$T"/x#msg)" top:two:c1+c2,sub + ''; + }; + }) (modes "nonflake-input" ({ draw, flake, ... }: { phases = twice { sources = { |
