From b7d263b79a6e99431284e92901d279112916ed39 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 3 Sep 2020 13:11:22 +0200 Subject: [PATCH] Support modules in toDerivation() and toApp() --- src/nix/app.cc | 25 ++++++++++++++++++------- src/nix/installables.cc | 36 ++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/nix/app.cc b/src/nix/app.cc index 80acbf658..23801f39a 100644 --- a/src/nix/app.cc +++ b/src/nix/app.cc @@ -28,19 +28,30 @@ App Installable::toApp(EvalState & state) }; } - else if (type == "derivation") { - auto drvPath = cursor->forceDerivation(); - auto outPath = cursor->getAttr(state.sOutPath)->getString(); - auto outputName = cursor->getAttr(state.sOutputName)->getString(); - auto name = cursor->getAttr(state.sName)->getString(); + auto getDerivation = [&](std::shared_ptr attr) + { + auto drvPath = attr->forceDerivation(); + auto outPath = attr->getAttr(state.sOutPath)->getString(); + auto outputName = attr->getAttr(state.sOutputName)->getString(); + auto name = attr->getAttr(state.sName)->getString(); return App { .context = { { drvPath, {outputName} } }, .program = outPath + "/bin/" + DrvName(name).name, }; + }; + + if (type == "derivation") + return getDerivation(cursor); + + if (type == "module") { + // FIXME: define an 'app' option. + auto aDerivation = cursor->findAlongAttrPath( + {state.symbols.create("final"), state.symbols.create("derivation")}); + if (aDerivation) + return getDerivation(aDerivation); } - else - throw Error("attribute '%s' has unsupported type '%s'", attrPath, type); + throw Error("attribute '%s' has unsupported type '%s'", attrPath, type); } } diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 1f1ed680f..5f4d53fcf 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -149,7 +149,8 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes() "packages." + settings.thisSystem.get() + ".", // As a temporary hack until Nixpkgs is properly converted // to provide a clean 'packages' set, look in 'legacyPackages'. - "legacyPackages." + settings.thisSystem.get() + "." + "legacyPackages." + settings.thisSystem.get() + ".", + "modules.", }; } @@ -464,21 +465,36 @@ std::tuple InstallableF auto root = cache->getRoot(); for (auto & attrPath : getActualAttrPaths()) { + + auto getDerivation = [&](std::shared_ptr attr) -> std::tuple + { + auto drvPath = attr->forceDerivation(); + + auto drvInfo = DerivationInfo{ + std::move(drvPath), + state->store->parseStorePath(attr->getAttr(state->sOutPath)->getString()), + attr->getAttr(state->sOutputName)->getString() + }; + + return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)}; + }; + auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath)); if (!attr) continue; - if (!attr->isDerivation()) - throw Error("flake output attribute '%s' is not a derivation", attrPath); + auto aType = attr->maybeGetAttr(state->sType); - auto drvPath = attr->forceDerivation(); + if (aType && aType->getString() == "derivation") + return getDerivation(attr); - auto drvInfo = DerivationInfo{ - std::move(drvPath), - state->store->parseStorePath(attr->getAttr(state->sOutPath)->getString()), - attr->getAttr(state->sOutputName)->getString() - }; + else if (aType && aType->getString() == "module") { + if (auto aDerivation = attr->findAlongAttrPath( + {state->symbols.create("final"), state->symbols.create("derivation")})) + if (aDerivation) + return getDerivation(aDerivation); + } - return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)}; + throw Error("flake output attribute '%s' is not a derivation", attrPath); } throw Error("flake '%s' does not provide attribute %s",