Skip to content

Instantly share code, notes, and snippets.

@timbertson
Created March 3, 2019 10:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timbertson/3f06034b4a5341b65a1379dadffb4c06 to your computer and use it in GitHub Desktop.
Save timbertson/3f06034b4a5341b65a1379dadffb4c06 to your computer and use it in GitHub Desktop.
{ nix, runCommand, lib }:
# Takes a nix derivation path (must be in the store), and
# converts it to a derivation expression.
# Note that the result is not a `stdenv.mkDerivation` with
# all the helpers that entails (like overrideAttrs), but
# is a low-level call to `derivation`
#
# TODO: this likely doesn't suppot multi-output drvs, we'd
# need more smarts around `outputs`.
drvPath:
with builtins; with lib;
let
# TODO: this introduces import-from-derivation, is there some
# way to shift this to eval time?
jsonFile =
assert (isStorePath drvPath);
runCommand "drv.json" {} ''
${nix}/bin/nix show-derivation ${toString drvPath} > "$out"
'';
drvJson = importJSON jsonFile;
# The JSON has a single toplevel key of the .drv path
rawDrv = getAttr (toString drvPath) drvJson;
outputs = attrNames rawDrv.outputs;
filteredEnv = filterAttrs (k: v:
!(elem k outputs)
) rawDrv.env;
# We need to produce a derivation with the same inputSrcs and inputDrvs,
# which we don't get just by copying the attributes.
# We know there's always a `builder` attribute, so we manually build
# a string with all the original context of the derivation:
builderWithCtx = with lib;
let
getAllAttrs = src: attrs: map (name: getAttr name src) attrs;
importInputs = attrs:
concatLists (
mapAttrsToList
# each attr is an attrset with key = path-to-drv and value = list of outputs (attributes)
(name: outputs: getAllAttrs (import name) outputs)
attrs
);
addContextFrom = orig: dest:
warn ("Adding context from: ${orig}")
(lib.addContextFrom orig dest);
in
foldr addContextFrom filteredEnv.builder ((importInputs rawDrv.inputDrvs) ++ (map storePath rawDrv.inputSrcs));
drvAttrs = filteredEnv // {
inherit outputs;
inherit (rawDrv) args;
builder = builderWithCtx;
};
in
derivation drvAttrs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment