From 7331da99abead2b59efcfdaf729cb1034642b630 Mon Sep 17 00:00:00 2001 From: regnat Date: Fri, 5 Feb 2021 13:35:31 +0100 Subject: Make NIX_SHOW_STATS work with new-style commands --- src/libcmd/command.hh | 2 ++ src/libcmd/installables.cc | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'src/libcmd') diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index c02193924..e66c697eb 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -48,6 +48,8 @@ struct EvalCommand : virtual StoreCommand, MixEvalArgs ref getEvalState(); std::shared_ptr evalState; + + ~EvalCommand(); }; struct MixFlakeOptions : virtual Args, EvalCommand diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 4739dc974..7102f5a1a 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -280,6 +280,12 @@ ref EvalCommand::getEvalState() return ref(evalState); } +EvalCommand::~EvalCommand() +{ + if (evalState) + evalState->printStats(); +} + void completeFlakeRef(ref store, std::string_view prefix) { if (prefix == "") -- cgit v1.2.3 From 77f5d171e17294ebb017a386d4408bf4613dfed7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Mar 2021 16:53:39 +0100 Subject: --override-input: Imply --no-write-lock-file Fixes #3779. --- src/libcmd/installables.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 7102f5a1a..898e642a5 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -111,10 +111,11 @@ MixFlakeOptions::MixFlakeOptions() addFlag({ .longName = "override-input", - .description = "Override a specific flake input (e.g. `dwarffs/nixpkgs`).", + .description = "Override a specific flake input (e.g. `dwarffs/nixpkgs`). This implies `--no-write-lock-file`.", .category = category, .labels = {"input-path", "flake-url"}, .handler = {[&](std::string inputPath, std::string flakeRef) { + lockFlags.writeLockFile = false; lockFlags.inputOverrides.insert_or_assign( flake::parseInputPath(inputPath), parseFlakeRef(flakeRef, absPath("."))); -- cgit v1.2.3 From f7d9f7c3381acef38e4db2bb2f9e0287c289be54 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 1 Mar 2021 05:48:01 +0000 Subject: Pull out Buildable into its own file/header in libnixstore --- src/libcmd/installables.cc | 25 ------------------------- src/libcmd/installables.hh | 22 +--------------------- 2 files changed, 1 insertion(+), 46 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 898e642a5..ca416b9ee 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -20,31 +20,6 @@ namespace nix { -nlohmann::json BuildableOpaque::toJSON(ref store) const { - nlohmann::json res; - res["path"] = store->printStorePath(path); - return res; -} - -nlohmann::json BuildableFromDrv::toJSON(ref store) const { - nlohmann::json res; - res["drvPath"] = store->printStorePath(drvPath); - for (const auto& [output, path] : outputs) { - res["outputs"][output] = path ? store->printStorePath(*path) : ""; - } - return res; -} - -nlohmann::json buildablesToJSON(const Buildables & buildables, ref store) { - auto res = nlohmann::json::array(); - for (const Buildable & buildable : buildables) { - std::visit([&res, store](const auto & buildable) { - res.push_back(buildable.toJSON(store)); - }, buildable); - } - return res; -} - void completeFlakeInputPath( ref evalState, const FlakeRef & flakeRef, diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index b714f097b..d31afd3d5 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -2,13 +2,12 @@ #include "util.hh" #include "path.hh" +#include "buildable.hh" #include "eval.hh" #include "flake/flake.hh" #include -#include - namespace nix { struct DrvInfo; @@ -16,25 +15,6 @@ struct SourceExprCommand; namespace eval_cache { class EvalCache; class AttrCursor; } -struct BuildableOpaque { - StorePath path; - nlohmann::json toJSON(ref store) const; -}; - -struct BuildableFromDrv { - StorePath drvPath; - std::map> outputs; - nlohmann::json toJSON(ref store) const; -}; - -typedef std::variant< - BuildableOpaque, - BuildableFromDrv -> Buildable; - -typedef std::vector Buildables; -nlohmann::json buildablesToJSON(const Buildables & buildables, ref store); - struct App { std::vector context; -- cgit v1.2.3 From 7a2b566dc8f0f94fdd6acbce90e47cd967f9f134 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 2 Mar 2021 00:47:00 +0000 Subject: Move `StorePathWithOutputs` into its own header/file In the following commits it will become less prevalent. --- src/libcmd/installables.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index d31afd3d5..e5c6fe208 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -2,6 +2,7 @@ #include "util.hh" #include "path.hh" +#include "path-with-outputs.hh" #include "buildable.hh" #include "eval.hh" #include "flake/flake.hh" -- cgit v1.2.3 From 255d145ba7ac907d1cba8d088da556b591627756 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 2 Mar 2021 03:50:41 +0000 Subject: Use `BuildableReq` for `buildPaths` and `ensurePath` This avoids an ambiguity where the `StorePathWithOutputs { drvPath, {} }` could mean "build `brvPath`" or "substitute `drvPath`" depending on context. It also brings the internals closer in line to the new CLI, by generalizing the `Buildable` type is used there and makes that distinction already. In doing so, relegate `StorePathWithOutputs` to being a type just for backwards compatibility (CLI and RPC). --- src/libcmd/installables.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index ca416b9ee..b68c5f6a7 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -679,19 +679,20 @@ Buildables build(ref store, Realise mode, Buildables buildables; - std::vector pathsToBuild; + std::vector pathsToBuild; for (auto & i : installables) { for (auto & b : i->toBuildables()) { std::visit(overloaded { [&](BuildableOpaque bo) { - pathsToBuild.push_back({bo.path}); + pathsToBuild.push_back(bo); }, [&](BuildableFromDrv bfd) { StringSet outputNames; for (auto & output : bfd.outputs) outputNames.insert(output.first); - pathsToBuild.push_back({bfd.drvPath, outputNames}); + pathsToBuild.push_back( + BuildableReqFromDrv{bfd.drvPath, outputNames}); }, }, b); buildables.push_back(std::move(b)); -- cgit v1.2.3 From 9b805d36ac70545fc4c0d863e21e0c2e5f2518a1 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 5 Apr 2021 09:48:18 -0400 Subject: Rename Buildable --- src/libcmd/command.cc | 6 +++--- src/libcmd/command.hh | 4 ++-- src/libcmd/installables.cc | 44 ++++++++++++++++++++++---------------------- src/libcmd/installables.hh | 6 +++--- 4 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index d29954f67..dc1fbc43f 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -162,7 +162,7 @@ void MixProfile::updateProfile(const StorePath & storePath) profile2, storePath)); } -void MixProfile::updateProfile(const Buildables & buildables) +void MixProfile::updateProfile(const DerivedPathsWithHints & buildables) { if (!profile) return; @@ -170,10 +170,10 @@ void MixProfile::updateProfile(const Buildables & buildables) for (auto & buildable : buildables) { std::visit(overloaded { - [&](BuildableOpaque bo) { + [&](DerivedPathOpaque bo) { result.push_back(bo.path); }, - [&](BuildableFromDrv bfd) { + [&](DerivedPathWithHintsBuilt bfd) { for (auto & output : bfd.outputs) { /* Output path should be known because we just tried to build it. */ diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index e66c697eb..9e18c6e51 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -216,7 +216,7 @@ static RegisterCommand registerCommand2(std::vector && name) return RegisterCommand(std::move(name), [](){ return make_ref(); }); } -Buildables build(ref store, Realise mode, +DerivedPathsWithHints build(ref store, Realise mode, std::vector> installables, BuildMode bMode = bmNormal); std::set toStorePaths(ref store, @@ -252,7 +252,7 @@ struct MixProfile : virtual StoreCommand /* If 'profile' is set, make it point at the store path produced by 'buildables'. */ - void updateProfile(const Buildables & buildables); + void updateProfile(const DerivedPathsWithHints & buildables); }; struct MixDefaultProfile : MixProfile diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index b68c5f6a7..f091ac186 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -285,9 +285,9 @@ void completeFlakeRef(ref store, std::string_view prefix) } } -Buildable Installable::toBuildable() +DerivedPathWithHints Installable::toDerivedPathWithHints() { - auto buildables = toBuildables(); + auto buildables = toDerivedPathsWithHints(); if (buildables.size() != 1) throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size()); return std::move(buildables[0]); @@ -321,7 +321,7 @@ struct InstallableStorePath : Installable std::string what() override { return store->printStorePath(storePath); } - Buildables toBuildables() override + DerivedPathsWithHints toDerivedPathsWithHints() override { if (storePath.isDerivation()) { std::map> outputs; @@ -329,14 +329,14 @@ struct InstallableStorePath : Installable for (auto & [name, output] : drv.outputsAndOptPaths(*store)) outputs.emplace(name, output.second); return { - BuildableFromDrv { + DerivedPathWithHintsBuilt { .drvPath = storePath, .outputs = std::move(outputs) } }; } else { return { - BuildableOpaque { + DerivedPathOpaque { .path = storePath, } }; @@ -349,9 +349,9 @@ struct InstallableStorePath : Installable } }; -Buildables InstallableValue::toBuildables() +DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() { - Buildables res; + DerivedPathsWithHints res; std::map>> drvsToOutputs; @@ -364,7 +364,7 @@ Buildables InstallableValue::toBuildables() } for (auto & i : drvsToOutputs) - res.push_back(BuildableFromDrv { i.first, i.second }); + res.push_back(DerivedPathWithHintsBuilt { i.first, i.second }); return res; } @@ -671,28 +671,28 @@ std::shared_ptr SourceExprCommand::parseInstallable( return installables.front(); } -Buildables build(ref store, Realise mode, +DerivedPathsWithHints build(ref store, Realise mode, std::vector> installables, BuildMode bMode) { if (mode == Realise::Nothing) settings.readOnlyMode = true; - Buildables buildables; + DerivedPathsWithHints buildables; - std::vector pathsToBuild; + std::vector pathsToBuild; for (auto & i : installables) { - for (auto & b : i->toBuildables()) { + for (auto & b : i->toDerivedPathsWithHints()) { std::visit(overloaded { - [&](BuildableOpaque bo) { + [&](DerivedPathOpaque bo) { pathsToBuild.push_back(bo); }, - [&](BuildableFromDrv bfd) { + [&](DerivedPathWithHintsBuilt bfd) { StringSet outputNames; for (auto & output : bfd.outputs) outputNames.insert(output.first); pathsToBuild.push_back( - BuildableReqFromDrv{bfd.drvPath, outputNames}); + DerivedPath::Built{bfd.drvPath, outputNames}); }, }, b); buildables.push_back(std::move(b)); @@ -717,10 +717,10 @@ std::set toRealisedPaths( if (operateOn == OperateOn::Output) { for (auto & b : build(store, mode, installables)) std::visit(overloaded { - [&](BuildableOpaque bo) { + [&](DerivedPathOpaque bo) { res.insert(bo.path); }, - [&](BuildableFromDrv bfd) { + [&](DerivedPathWithHintsBuilt bfd) { auto drv = store->readDerivation(bfd.drvPath); auto outputHashes = staticOutputHashes(*store, drv); for (auto & output : bfd.outputs) { @@ -751,8 +751,8 @@ std::set toRealisedPaths( settings.readOnlyMode = true; for (auto & i : installables) - for (auto & b : i->toBuildables()) - if (auto bfd = std::get_if(&b)) + for (auto & b : i->toDerivedPathsWithHints()) + if (auto bfd = std::get_if(&b)) res.insert(bfd->drvPath); } @@ -787,9 +787,9 @@ StorePathSet toDerivations(ref store, StorePathSet drvPaths; for (auto & i : installables) - for (auto & b : i->toBuildables()) + for (auto & b : i->toDerivedPathsWithHints()) std::visit(overloaded { - [&](BuildableOpaque bo) { + [&](DerivedPathOpaque bo) { if (!useDeriver) throw Error("argument '%s' did not evaluate to a derivation", i->what()); auto derivers = store->queryValidDerivers(bo.path); @@ -798,7 +798,7 @@ StorePathSet toDerivations(ref store, // FIXME: use all derivers? drvPaths.insert(*derivers.begin()); }, - [&](BuildableFromDrv bfd) { + [&](DerivedPathWithHintsBuilt bfd) { drvPaths.insert(bfd.drvPath); }, }, b); diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index e5c6fe208..0bc932b52 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -29,9 +29,9 @@ struct Installable virtual std::string what() = 0; - virtual Buildables toBuildables() = 0; + virtual DerivedPathsWithHints toDerivedPathsWithHints() = 0; - Buildable toBuildable(); + DerivedPathWithHints toDerivedPathWithHints(); App toApp(EvalState & state); @@ -74,7 +74,7 @@ struct InstallableValue : Installable virtual std::vector toDerivations() = 0; - Buildables toBuildables() override; + DerivedPathsWithHints toDerivedPathsWithHints() override; }; struct InstallableFlake : InstallableValue -- cgit v1.2.3 From 179582872de60863fcabcf471f98930a25fd6df3 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 5 Apr 2021 10:05:21 -0400 Subject: Make `DerivedPathWithHints` a newtype This allows us to namespace its constructors under it. --- src/libcmd/command.cc | 6 +++--- src/libcmd/installables.cc | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index dc1fbc43f..9da470c15 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -170,10 +170,10 @@ void MixProfile::updateProfile(const DerivedPathsWithHints & buildables) for (auto & buildable : buildables) { std::visit(overloaded { - [&](DerivedPathOpaque bo) { + [&](DerivedPathWithHints::Opaque bo) { result.push_back(bo.path); }, - [&](DerivedPathWithHintsBuilt bfd) { + [&](DerivedPathWithHints::Built bfd) { for (auto & output : bfd.outputs) { /* Output path should be known because we just tried to build it. */ @@ -181,7 +181,7 @@ void MixProfile::updateProfile(const DerivedPathsWithHints & buildables) result.push_back(*output.second); } }, - }, buildable); + }, buildable.raw()); } if (result.size() != 1) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index f091ac186..5d3026c1a 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -329,14 +329,14 @@ struct InstallableStorePath : Installable for (auto & [name, output] : drv.outputsAndOptPaths(*store)) outputs.emplace(name, output.second); return { - DerivedPathWithHintsBuilt { + DerivedPathWithHints::Built { .drvPath = storePath, .outputs = std::move(outputs) } }; } else { return { - DerivedPathOpaque { + DerivedPathWithHints::Opaque { .path = storePath, } }; @@ -364,7 +364,7 @@ DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() } for (auto & i : drvsToOutputs) - res.push_back(DerivedPathWithHintsBuilt { i.first, i.second }); + res.push_back(DerivedPathWithHints::Built { i.first, i.second }); return res; } @@ -684,17 +684,17 @@ DerivedPathsWithHints build(ref store, Realise mode, for (auto & i : installables) { for (auto & b : i->toDerivedPathsWithHints()) { std::visit(overloaded { - [&](DerivedPathOpaque bo) { + [&](DerivedPathWithHints::Opaque bo) { pathsToBuild.push_back(bo); }, - [&](DerivedPathWithHintsBuilt bfd) { + [&](DerivedPathWithHints::Built bfd) { StringSet outputNames; for (auto & output : bfd.outputs) outputNames.insert(output.first); pathsToBuild.push_back( DerivedPath::Built{bfd.drvPath, outputNames}); }, - }, b); + }, b.raw()); buildables.push_back(std::move(b)); } } @@ -717,10 +717,10 @@ std::set toRealisedPaths( if (operateOn == OperateOn::Output) { for (auto & b : build(store, mode, installables)) std::visit(overloaded { - [&](DerivedPathOpaque bo) { + [&](DerivedPathWithHints::Opaque bo) { res.insert(bo.path); }, - [&](DerivedPathWithHintsBuilt bfd) { + [&](DerivedPathWithHints::Built bfd) { auto drv = store->readDerivation(bfd.drvPath); auto outputHashes = staticOutputHashes(*store, drv); for (auto & output : bfd.outputs) { @@ -745,14 +745,14 @@ std::set toRealisedPaths( } } }, - }, b); + }, b.raw()); } else { if (mode == Realise::Nothing) settings.readOnlyMode = true; for (auto & i : installables) for (auto & b : i->toDerivedPathsWithHints()) - if (auto bfd = std::get_if(&b)) + if (auto bfd = std::get_if(&b)) res.insert(bfd->drvPath); } @@ -789,7 +789,7 @@ StorePathSet toDerivations(ref store, for (auto & i : installables) for (auto & b : i->toDerivedPathsWithHints()) std::visit(overloaded { - [&](DerivedPathOpaque bo) { + [&](DerivedPathWithHints::Opaque bo) { if (!useDeriver) throw Error("argument '%s' did not evaluate to a derivation", i->what()); auto derivers = store->queryValidDerivers(bo.path); @@ -798,10 +798,10 @@ StorePathSet toDerivations(ref store, // FIXME: use all derivers? drvPaths.insert(*derivers.begin()); }, - [&](DerivedPathWithHintsBuilt bfd) { + [&](DerivedPathWithHints::Built bfd) { drvPaths.insert(bfd.drvPath); }, - }, b); + }, b.raw()); return drvPaths; } -- cgit v1.2.3 From d8fa7517fad4272e20ff9b9b740c91158bc685e2 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 5 Apr 2021 10:33:28 -0400 Subject: buildable.{cc,hh} -> derived-path.{cc,hh} --- src/libcmd/installables.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 0bc932b52..403403c07 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -3,7 +3,7 @@ #include "util.hh" #include "path.hh" #include "path-with-outputs.hh" -#include "buildable.hh" +#include "derived-path.hh" #include "eval.hh" #include "flake/flake.hh" -- cgit v1.2.3 From 6905291dafba44ed414f4bc800ac0e09db5cbf9b Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 3 Apr 2021 12:04:57 +0200 Subject: libcmd/installables: force re-evaluation of cached failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think that it's not very helpful to get "cached failures" in a wrong `flake.nix`. This can be very confusing when debugging a Nix expression. See for instance NixOS/nixpkgs#118115. In fact, the eval cache allows a forced reevaluation which is used for e.g. `nix eval`. This change makes sure that this is the case for `nix build` as well. So rather than λ ma27 [~/Projects/exp] → ../nix/outputs/out/bin/nix build -L --rebuild --experimental-features 'nix-command flakes' error: cached failure of attribute 'defaultPackage.x86_64-linux' the evaluation of already-evaluated (and failed) attributes looks like this now: λ ma27 [~/Projects/exp] → ../nix/outputs/out/bin/nix build -L --rebuild --experimental-features 'nix-command flakes' error: attribute 'hell' missing at /nix/store/mrnvi9ss8zn5wj6gpn4bcd68vbh42mfh-source/flake.nix:6:35: 5| 6| packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hell; | ^ 7| (use '--show-trace' to show detailed location information) --- src/libcmd/installables.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 5d3026c1a..e15addfae 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -503,7 +503,11 @@ std::tuple InstallableF auto root = cache->getRoot(); for (auto & attrPath : getActualAttrPaths()) { - auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath)); + auto attr = root->findAlongAttrPath( + parseAttrPath(*state, attrPath), + true + ); + if (!attr) continue; if (!attr->isDerivation()) -- cgit v1.2.3 From 8d66f5f1107fe87f70ea24ade045720235cc31fa Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 21 Apr 2021 17:33:21 +0200 Subject: Make `nix shell` fallback to static outputs when needed In case of pure input-addressed derivations, the build loop doesn't guaranty that the realisations are stored in the db (if the output paths are already there or can be substituted, the realisations won't be registered). This caused `nix shell` to fail in some cases because it was assuming that the realisations were always existing. A better (but more involved) fix would probably to ensure that we always register the realisations, but in the meantime this patches the surface issue. Fix #4721 --- src/libcmd/installables.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e15addfae..39162a662 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -736,9 +736,18 @@ std::set toRealisedPaths( output.first); auto outputId = DrvOutput{outputHashes.at(output.first), output.first}; auto realisation = store->queryRealisation(outputId); - if (!realisation) - throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); - res.insert(RealisedPath{*realisation}); + if (!realisation) { + // TODO: remove this check once #4725 is fixed + // as we’ll have the guaranty that if + // `output.second` exists, then the realisation + // will be there too + if (output.second) + res.insert(*output.second); + else + throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); + } else { + res.insert(RealisedPath{*realisation}); + } } else { // If ca-derivations isn't enabled, behave as if -- cgit v1.2.3 From 428062e578243336abeacb664bf3dba2674a546f Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Wed, 21 Apr 2021 15:26:14 -0500 Subject: Get deriver when passing --derivation This makes Nix look up paths derivations when they are passed as a store paths. So: $ nix path-info --derivation /nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10 now gives /nix/store/qp724w90516n4bk5r9gfb37vzmqdh3z7-hello-2.10.drv instead of "". If no deriver is available, Nix now errors instead of silently ignoring that argument. --- src/libcmd/installables.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e15addfae..06ef4c669 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -754,10 +754,8 @@ std::set toRealisedPaths( if (mode == Realise::Nothing) settings.readOnlyMode = true; - for (auto & i : installables) - for (auto & b : i->toDerivedPathsWithHints()) - if (auto bfd = std::get_if(&b)) - res.insert(bfd->drvPath); + auto drvPaths = toDerivations(store, installables, true); + res.insert(drvPaths.begin(), drvPaths.end()); } return res; -- cgit v1.2.3 From d3df747cb6813fc5f9d0fcc63d6fd16292c92e04 Mon Sep 17 00:00:00 2001 From: regnat Date: Fri, 23 Apr 2021 09:34:43 +0200 Subject: Revert "Make `nix shell` fallback to static outputs when needed" This reverts commit 8d66f5f1107fe87f70ea24ade045720235cc31fa. This fix isn't needed anymore now that the realisations are always properly registered --- src/libcmd/installables.cc | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 10855688c..06ef4c669 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -736,18 +736,9 @@ std::set toRealisedPaths( output.first); auto outputId = DrvOutput{outputHashes.at(output.first), output.first}; auto realisation = store->queryRealisation(outputId); - if (!realisation) { - // TODO: remove this check once #4725 is fixed - // as we’ll have the guaranty that if - // `output.second` exists, then the realisation - // will be there too - if (output.second) - res.insert(*output.second); - else - throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); - } else { - res.insert(RealisedPath{*realisation}); - } + if (!realisation) + throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); + res.insert(RealisedPath{*realisation}); } else { // If ca-derivations isn't enabled, behave as if -- cgit v1.2.3 From ec613603ba324bf12f8f554d74fb1a02c6e9b472 Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 12 May 2021 16:19:51 +0200 Subject: DerivedPathWithHints -> BuiltPath Just a renaming for now --- src/libcmd/command.cc | 6 +++--- src/libcmd/command.hh | 4 ++-- src/libcmd/installables.cc | 36 ++++++++++++++++++------------------ src/libcmd/installables.hh | 6 +++--- 4 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 9da470c15..25e4873e8 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -162,7 +162,7 @@ void MixProfile::updateProfile(const StorePath & storePath) profile2, storePath)); } -void MixProfile::updateProfile(const DerivedPathsWithHints & buildables) +void MixProfile::updateProfile(const BuiltPaths & buildables) { if (!profile) return; @@ -170,10 +170,10 @@ void MixProfile::updateProfile(const DerivedPathsWithHints & buildables) for (auto & buildable : buildables) { std::visit(overloaded { - [&](DerivedPathWithHints::Opaque bo) { + [&](BuiltPath::Opaque bo) { result.push_back(bo.path); }, - [&](DerivedPathWithHints::Built bfd) { + [&](BuiltPath::Built bfd) { for (auto & output : bfd.outputs) { /* Output path should be known because we just tried to build it. */ diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 9e18c6e51..952279f7b 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -216,7 +216,7 @@ static RegisterCommand registerCommand2(std::vector && name) return RegisterCommand(std::move(name), [](){ return make_ref(); }); } -DerivedPathsWithHints build(ref store, Realise mode, +BuiltPaths build(ref store, Realise mode, std::vector> installables, BuildMode bMode = bmNormal); std::set toStorePaths(ref store, @@ -252,7 +252,7 @@ struct MixProfile : virtual StoreCommand /* If 'profile' is set, make it point at the store path produced by 'buildables'. */ - void updateProfile(const DerivedPathsWithHints & buildables); + void updateProfile(const BuiltPaths & buildables); }; struct MixDefaultProfile : MixProfile diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 06ef4c669..36d7ecc39 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -285,9 +285,9 @@ void completeFlakeRef(ref store, std::string_view prefix) } } -DerivedPathWithHints Installable::toDerivedPathWithHints() +BuiltPath Installable::toBuiltPath() { - auto buildables = toDerivedPathsWithHints(); + auto buildables = toBuiltPaths(); if (buildables.size() != 1) throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size()); return std::move(buildables[0]); @@ -321,7 +321,7 @@ struct InstallableStorePath : Installable std::string what() override { return store->printStorePath(storePath); } - DerivedPathsWithHints toDerivedPathsWithHints() override + BuiltPaths toBuiltPaths() override { if (storePath.isDerivation()) { std::map> outputs; @@ -329,14 +329,14 @@ struct InstallableStorePath : Installable for (auto & [name, output] : drv.outputsAndOptPaths(*store)) outputs.emplace(name, output.second); return { - DerivedPathWithHints::Built { + BuiltPath::Built { .drvPath = storePath, .outputs = std::move(outputs) } }; } else { return { - DerivedPathWithHints::Opaque { + BuiltPath::Opaque { .path = storePath, } }; @@ -349,9 +349,9 @@ struct InstallableStorePath : Installable } }; -DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() +BuiltPaths InstallableValue::toBuiltPaths() { - DerivedPathsWithHints res; + BuiltPaths res; std::map>> drvsToOutputs; @@ -364,7 +364,7 @@ DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() } for (auto & i : drvsToOutputs) - res.push_back(DerivedPathWithHints::Built { i.first, i.second }); + res.push_back(BuiltPath::Built { i.first, i.second }); return res; } @@ -675,23 +675,23 @@ std::shared_ptr SourceExprCommand::parseInstallable( return installables.front(); } -DerivedPathsWithHints build(ref store, Realise mode, +BuiltPaths build(ref store, Realise mode, std::vector> installables, BuildMode bMode) { if (mode == Realise::Nothing) settings.readOnlyMode = true; - DerivedPathsWithHints buildables; + BuiltPaths buildables; std::vector pathsToBuild; for (auto & i : installables) { - for (auto & b : i->toDerivedPathsWithHints()) { + for (auto & b : i->toBuiltPaths()) { std::visit(overloaded { - [&](DerivedPathWithHints::Opaque bo) { + [&](BuiltPath::Opaque bo) { pathsToBuild.push_back(bo); }, - [&](DerivedPathWithHints::Built bfd) { + [&](BuiltPath::Built bfd) { StringSet outputNames; for (auto & output : bfd.outputs) outputNames.insert(output.first); @@ -721,10 +721,10 @@ std::set toRealisedPaths( if (operateOn == OperateOn::Output) { for (auto & b : build(store, mode, installables)) std::visit(overloaded { - [&](DerivedPathWithHints::Opaque bo) { + [&](BuiltPath::Opaque bo) { res.insert(bo.path); }, - [&](DerivedPathWithHints::Built bfd) { + [&](BuiltPath::Built bfd) { auto drv = store->readDerivation(bfd.drvPath); auto outputHashes = staticOutputHashes(*store, drv); for (auto & output : bfd.outputs) { @@ -789,9 +789,9 @@ StorePathSet toDerivations(ref store, StorePathSet drvPaths; for (auto & i : installables) - for (auto & b : i->toDerivedPathsWithHints()) + for (auto & b : i->toBuiltPaths()) std::visit(overloaded { - [&](DerivedPathWithHints::Opaque bo) { + [&](BuiltPath::Opaque bo) { if (!useDeriver) throw Error("argument '%s' did not evaluate to a derivation", i->what()); auto derivers = store->queryValidDerivers(bo.path); @@ -800,7 +800,7 @@ StorePathSet toDerivations(ref store, // FIXME: use all derivers? drvPaths.insert(*derivers.begin()); }, - [&](DerivedPathWithHints::Built bfd) { + [&](BuiltPath::Built bfd) { drvPaths.insert(bfd.drvPath); }, }, b.raw()); diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 403403c07..7d79efaad 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -29,9 +29,9 @@ struct Installable virtual std::string what() = 0; - virtual DerivedPathsWithHints toDerivedPathsWithHints() = 0; + virtual BuiltPaths toBuiltPaths() = 0; - DerivedPathWithHints toDerivedPathWithHints(); + BuiltPath toBuiltPath(); App toApp(EvalState & state); @@ -74,7 +74,7 @@ struct InstallableValue : Installable virtual std::vector toDerivations() = 0; - DerivedPathsWithHints toDerivedPathsWithHints() override; + BuiltPaths toBuiltPaths() override; }; struct InstallableFlake : InstallableValue -- cgit v1.2.3 From 21050846457f356346204dd52fb7a6d49f710688 Mon Sep 17 00:00:00 2001 From: regnat Date: Mon, 17 May 2021 08:45:08 +0200 Subject: Enfore the use of properly built paths in libcmd Replace `DerivedPathWithHints` by a new `BuiltPath` type that serves as a proof that the corresponding path has been built. --- src/libcmd/command.cc | 39 ++++++------ src/libcmd/command.hh | 14 ++--- src/libcmd/installables.cc | 151 +++++++++++++++++++++++---------------------- src/libcmd/installables.hh | 6 +- 4 files changed, 108 insertions(+), 102 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 25e4873e8..569c4b9e4 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -54,7 +54,7 @@ void StoreCommand::run() run(getStore()); } -RealisedPathsCommand::RealisedPathsCommand(bool recursive) +BuiltPathsCommand::BuiltPathsCommand(bool recursive) : recursive(recursive) { if (recursive) @@ -81,39 +81,45 @@ RealisedPathsCommand::RealisedPathsCommand(bool recursive) }); } -void RealisedPathsCommand::run(ref store) +void BuiltPathsCommand::run(ref store) { - std::vector paths; + BuiltPaths paths; if (all) { if (installables.size()) throw UsageError("'--all' does not expect arguments"); // XXX: Only uses opaque paths, ignores all the realisations for (auto & p : store->queryAllValidPaths()) - paths.push_back(p); + paths.push_back(BuiltPath::Opaque{p}); } else { - auto pathSet = toRealisedPaths(store, realiseMode, operateOn, installables); + paths = toBuiltPaths(store, realiseMode, operateOn, installables); if (recursive) { - auto roots = std::move(pathSet); - pathSet = {}; - RealisedPath::closure(*store, roots, pathSet); + // XXX: This only computes the store path closure, ignoring + // intermediate realisations + StorePathSet pathsRoots, pathsClosure; + for (auto & root: paths) { + auto rootFromThis = root.outPaths(); + pathsRoots.insert(rootFromThis.begin(), rootFromThis.end()); + } + store->computeFSClosure(pathsRoots, pathsClosure); + for (auto & path : pathsClosure) + paths.push_back(BuiltPath::Opaque{path}); } - for (auto & path : pathSet) - paths.push_back(path); } run(store, std::move(paths)); } StorePathsCommand::StorePathsCommand(bool recursive) - : RealisedPathsCommand(recursive) + : BuiltPathsCommand(recursive) { } -void StorePathsCommand::run(ref store, std::vector paths) +void StorePathsCommand::run(ref store, BuiltPaths paths) { StorePaths storePaths; - for (auto & p : paths) - storePaths.push_back(p.path()); + for (auto& builtPath : paths) + for (auto& p : builtPath.outPaths()) + storePaths.push_back(p); run(store, std::move(storePaths)); } @@ -175,10 +181,7 @@ void MixProfile::updateProfile(const BuiltPaths & buildables) }, [&](BuiltPath::Built bfd) { for (auto & output : bfd.outputs) { - /* Output path should be known because we just tried to - build it. */ - assert(output.second); - result.push_back(*output.second); + result.push_back(output.second); } }, }, buildable.raw()); diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 952279f7b..35b3a384b 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -143,7 +143,7 @@ private: }; /* A command that operates on zero or more store paths. */ -struct RealisedPathsCommand : public InstallablesCommand +struct BuiltPathsCommand : public InstallablesCommand { private: @@ -156,26 +156,26 @@ protected: public: - RealisedPathsCommand(bool recursive = false); + BuiltPathsCommand(bool recursive = false); using StoreCommand::run; - virtual void run(ref store, std::vector paths) = 0; + virtual void run(ref store, BuiltPaths paths) = 0; void run(ref store) override; bool useDefaultInstallables() override { return !all; } }; -struct StorePathsCommand : public RealisedPathsCommand +struct StorePathsCommand : public BuiltPathsCommand { StorePathsCommand(bool recursive = false); - using RealisedPathsCommand::run; + using BuiltPathsCommand::run; virtual void run(ref store, std::vector storePaths) = 0; - void run(ref store, std::vector paths) override; + void run(ref store, BuiltPaths paths) override; }; /* A command that operates on exactly one store path. */ @@ -231,7 +231,7 @@ std::set toDerivations(ref store, std::vector> installables, bool useDeriver = false); -std::set toRealisedPaths( +BuiltPaths toBuiltPaths( ref store, Realise mode, OperateOn operateOn, diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 36d7ecc39..fe52912cf 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -285,9 +285,9 @@ void completeFlakeRef(ref store, std::string_view prefix) } } -BuiltPath Installable::toBuiltPath() +DerivedPath Installable::toDerivedPath() { - auto buildables = toBuiltPaths(); + auto buildables = toDerivedPaths(); if (buildables.size() != 1) throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size()); return std::move(buildables[0]); @@ -321,22 +321,19 @@ struct InstallableStorePath : Installable std::string what() override { return store->printStorePath(storePath); } - BuiltPaths toBuiltPaths() override + DerivedPaths toDerivedPaths() override { if (storePath.isDerivation()) { - std::map> outputs; auto drv = store->readDerivation(storePath); - for (auto & [name, output] : drv.outputsAndOptPaths(*store)) - outputs.emplace(name, output.second); return { - BuiltPath::Built { + DerivedPath::Built { .drvPath = storePath, - .outputs = std::move(outputs) + .outputs = drv.outputNames(), } }; } else { return { - BuiltPath::Opaque { + DerivedPath::Opaque { .path = storePath, } }; @@ -349,22 +346,22 @@ struct InstallableStorePath : Installable } }; -BuiltPaths InstallableValue::toBuiltPaths() +DerivedPaths InstallableValue::toDerivedPaths() { - BuiltPaths res; + DerivedPaths res; - std::map>> drvsToOutputs; + std::map> drvsToOutputs; // Group by derivation, helps with .all in particular for (auto & drv : toDerivations()) { auto outputName = drv.outputName; if (outputName == "") throw Error("derivation '%s' lacks an 'outputName' attribute", state->store->printStorePath(drv.drvPath)); - drvsToOutputs[drv.drvPath].insert_or_assign(outputName, drv.outPath); + drvsToOutputs[drv.drvPath].insert(outputName); } for (auto & i : drvsToOutputs) - res.push_back(BuiltPath::Built { i.first, i.second }); + res.push_back(DerivedPath::Built { i.first, i.second }); return res; } @@ -675,32 +672,67 @@ std::shared_ptr SourceExprCommand::parseInstallable( return installables.front(); } +BuiltPaths getBuiltPaths(ref store, DerivedPaths hopefullyBuiltPaths) +{ + BuiltPaths res; + for (auto& b : hopefullyBuiltPaths) + std::visit( + overloaded{ + [&](DerivedPath::Opaque bo) { + res.push_back(BuiltPath::Opaque{bo.path}); + }, + [&](DerivedPath::Built bfd) { + OutputPathMap outputs; + auto drv = store->readDerivation(bfd.drvPath); + auto outputHashes = staticOutputHashes(*store, drv); + auto drvOutputs = drv.outputsAndOptPaths(*store); + for (auto& output : bfd.outputs) { + if (!outputHashes.count(output)) + throw Error( + "the derivation '%s' doesn't have an output " + "named '%s'", + store->printStorePath(bfd.drvPath), output); + if (settings.isExperimentalFeatureEnabled( + "ca-derivations")) { + auto outputId = + DrvOutput{outputHashes.at(output), output}; + auto realisation = + store->queryRealisation(outputId); + if (!realisation) + throw Error( + "cannot operate on an output of unbuilt " + "content-addresed derivation '%s'", + outputId.to_string()); + outputs.insert_or_assign( + output, realisation->outPath); + } else { + // If ca-derivations isn't enabled, assume that + // the output path is statically known. + assert(drvOutputs.count(output)); + assert(drvOutputs.at(output).second); + outputs.insert_or_assign( + output, *drvOutputs.at(output).second); + } + } + res.push_back(BuiltPath::Built{bfd.drvPath, outputs}); + }, + }, + b.raw()); + + return res; +} + BuiltPaths build(ref store, Realise mode, std::vector> installables, BuildMode bMode) { if (mode == Realise::Nothing) settings.readOnlyMode = true; - BuiltPaths buildables; - std::vector pathsToBuild; for (auto & i : installables) { - for (auto & b : i->toBuiltPaths()) { - std::visit(overloaded { - [&](BuiltPath::Opaque bo) { - pathsToBuild.push_back(bo); - }, - [&](BuiltPath::Built bfd) { - StringSet outputNames; - for (auto & output : bfd.outputs) - outputNames.insert(output.first); - pathsToBuild.push_back( - DerivedPath::Built{bfd.drvPath, outputNames}); - }, - }, b.raw()); - buildables.push_back(std::move(b)); - } + auto b = i->toDerivedPaths(); + pathsToBuild.insert(pathsToBuild.end(), b.begin(), b.end()); } if (mode == Realise::Nothing) @@ -708,57 +740,26 @@ BuiltPaths build(ref store, Realise mode, else if (mode == Realise::Outputs) store->buildPaths(pathsToBuild, bMode); - return buildables; + return getBuiltPaths(store, pathsToBuild); } -std::set toRealisedPaths( +BuiltPaths toBuiltPaths( ref store, Realise mode, OperateOn operateOn, std::vector> installables) { - std::set res; if (operateOn == OperateOn::Output) { - for (auto & b : build(store, mode, installables)) - std::visit(overloaded { - [&](BuiltPath::Opaque bo) { - res.insert(bo.path); - }, - [&](BuiltPath::Built bfd) { - auto drv = store->readDerivation(bfd.drvPath); - auto outputHashes = staticOutputHashes(*store, drv); - for (auto & output : bfd.outputs) { - if (settings.isExperimentalFeatureEnabled("ca-derivations")) { - if (!outputHashes.count(output.first)) - throw Error( - "the derivation '%s' doesn't have an output named '%s'", - store->printStorePath(bfd.drvPath), - output.first); - auto outputId = DrvOutput{outputHashes.at(output.first), output.first}; - auto realisation = store->queryRealisation(outputId); - if (!realisation) - throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); - res.insert(RealisedPath{*realisation}); - } - else { - // If ca-derivations isn't enabled, behave as if - // all the paths are opaque to keep the default - // behavior - assert(output.second); - res.insert(*output.second); - } - } - }, - }, b.raw()); + return build(store, mode, installables); } else { if (mode == Realise::Nothing) settings.readOnlyMode = true; - auto drvPaths = toDerivations(store, installables, true); - res.insert(drvPaths.begin(), drvPaths.end()); + BuiltPaths res; + for (auto & drvPath : toDerivations(store, installables, true)) + res.push_back(BuiltPath::Opaque{drvPath}); + return res; } - - return res; } StorePathSet toStorePaths(ref store, @@ -766,8 +767,10 @@ StorePathSet toStorePaths(ref store, std::vector> installables) { StorePathSet outPaths; - for (auto & path : toRealisedPaths(store, mode, operateOn, installables)) - outPaths.insert(path.path()); + for (auto & path : toBuiltPaths(store, mode, operateOn, installables)) { + auto thisOutPaths = path.outPaths(); + outPaths.insert(thisOutPaths.begin(), thisOutPaths.end()); + } return outPaths; } @@ -789,9 +792,9 @@ StorePathSet toDerivations(ref store, StorePathSet drvPaths; for (auto & i : installables) - for (auto & b : i->toBuiltPaths()) + for (auto & b : i->toDerivedPaths()) std::visit(overloaded { - [&](BuiltPath::Opaque bo) { + [&](DerivedPath::Opaque bo) { if (!useDeriver) throw Error("argument '%s' did not evaluate to a derivation", i->what()); auto derivers = store->queryValidDerivers(bo.path); @@ -800,7 +803,7 @@ StorePathSet toDerivations(ref store, // FIXME: use all derivers? drvPaths.insert(*derivers.begin()); }, - [&](BuiltPath::Built bfd) { + [&](DerivedPath::Built bfd) { drvPaths.insert(bfd.drvPath); }, }, b.raw()); diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 7d79efaad..16bc4ae68 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -29,9 +29,9 @@ struct Installable virtual std::string what() = 0; - virtual BuiltPaths toBuiltPaths() = 0; + virtual DerivedPaths toDerivedPaths() = 0; - BuiltPath toBuiltPath(); + DerivedPath toDerivedPath(); App toApp(EvalState & state); @@ -74,7 +74,7 @@ struct InstallableValue : Installable virtual std::vector toDerivations() = 0; - BuiltPaths toBuiltPaths() override; + DerivedPaths toDerivedPaths() override; }; struct InstallableFlake : InstallableValue -- cgit v1.2.3 From ca96f5219489c1002499bfe2c580fdd458219144 Mon Sep 17 00:00:00 2001 From: regnat Date: Mon, 17 May 2021 17:49:20 +0200 Subject: Split the parsing of an `App` and its resolving That way things (like `nix flake check`) can evaluate the `app` outputs without having to build anything --- src/libcmd/installables.hh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 16bc4ae68..298fd48f8 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -23,6 +23,12 @@ struct App // FIXME: add args, sandbox settings, metadata, ... }; +struct UnresolvedApp +{ + App unresolved; + App resolve(ref); +}; + struct Installable { virtual ~Installable() { } @@ -33,7 +39,7 @@ struct Installable DerivedPath toDerivedPath(); - App toApp(EvalState & state); + UnresolvedApp toApp(EvalState & state); virtual std::pair toValue(EvalState & state) { -- cgit v1.2.3 From ef1e7ab840eaa50da29ddde7bf990a1ff6a8b185 Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Thu, 1 Jul 2021 00:23:47 +0300 Subject: flake.nixConfig: fix flake-registry config settings Before this commit, nixConfig.flake-registry didn't have any real effect on the evaluation, since config was applied after inputs were evaluated. Change this behavior: apply the config in the beginning of flake::lockFile. --- src/libcmd/installables.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index fe52912cf..540e53eee 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -575,8 +575,6 @@ std::shared_ptr InstallableFlake::getLockedFlake() const { if (!_lockedFlake) { _lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlags)); - _lockedFlake->flake.config.apply(); - // FIXME: send new config to the daemon. } return _lockedFlake; } -- cgit v1.2.3 From e756a59c72e3e793ed01dec04749fa356f263315 Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Thu, 1 Jul 2021 17:54:22 +0300 Subject: fixup! flake.nixConfig: fix flake-registry config settings --- src/libcmd/installables.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 540e53eee..269be11a2 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -573,8 +573,10 @@ InstallableFlake::getCursors(EvalState & state) std::shared_ptr InstallableFlake::getLockedFlake() const { + flake::LockFlags lockFlagsApplyConfig = lockFlags; + lockFlagsApplyConfig.applyNixConfig = true; if (!_lockedFlake) { - _lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlags)); + _lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlagsApplyConfig)); } return _lockedFlake; } -- cgit v1.2.3 From 4a7a8b87cd0dd383f1059fe7903c4b001314f58d Mon Sep 17 00:00:00 2001 From: Pamplemousse Date: Tue, 29 Jun 2021 14:28:43 -0700 Subject: Prefer to throw specific errors Signed-off-by: Pamplemousse --- src/libcmd/command.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 569c4b9e4..6777b23be 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -188,7 +188,7 @@ void MixProfile::updateProfile(const BuiltPaths & buildables) } if (result.size() != 1) - throw Error("'--profile' requires that the arguments produce a single store path, but there are %d", result.size()); + throw UsageError("'--profile' requires that the arguments produce a single store path, but there are %d", result.size()); updateProfile(result[0]); } -- cgit v1.2.3 From 70cb2ffaccb91eff6f4afe2552d0784e279f1fe9 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 3 Jul 2021 14:19:10 +0200 Subject: libcmd/installables: implement completion for Nix expressions passed via `-f` --- src/libcmd/installables.cc | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index fe52912cf..49f063334 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -171,14 +171,44 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes() void SourceExprCommand::completeInstallable(std::string_view prefix) { - if (file) return; // FIXME - - completeFlakeRefWithFragment( - getEvalState(), - lockFlags, - getDefaultFlakeAttrPathPrefixes(), - getDefaultFlakeAttrPaths(), - prefix); + if (file) { + evalSettings.pureEval = false; + auto state = getEvalState(); + Expr *e = state->parseExprFromFile( + resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file))) + ); + + Value root; + state->eval(e, root); + + auto autoArgs = getAutoArgs(*state); + + std::string prefix_ = std::string(prefix); + auto sep = prefix_.rfind('.'); + if (sep != std::string::npos) { + prefix_.erase(sep); + } else { + prefix_ = ""; + } + + Value &v1(*findAlongAttrPath(*state, prefix_, *autoArgs, root).first); + state->forceValue(v1); + Value v2; + state->autoCallFunction(*autoArgs, v1, v2); + + if (v2.type() == nAttrs) { + for (auto & i : *v2.attrs) { + completions->add(i.name); + } + } + } else { + completeFlakeRefWithFragment( + getEvalState(), + lockFlags, + getDefaultFlakeAttrPathPrefixes(), + getDefaultFlakeAttrPaths(), + prefix); + } } void completeFlakeRefWithFragment( -- cgit v1.2.3 From 3c5f69bb60f858f471121adaf172edb47628188e Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 5 Jul 2021 21:37:33 +0200 Subject: completeInstallable: also match for already typed prefixes --- src/libcmd/installables.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 49f063334..5f263061b 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -185,9 +185,12 @@ void SourceExprCommand::completeInstallable(std::string_view prefix) std::string prefix_ = std::string(prefix); auto sep = prefix_.rfind('.'); + std::string searchWord; if (sep != std::string::npos) { - prefix_.erase(sep); + searchWord = prefix_.substr(sep, std::string::npos); + prefix_ = prefix_.substr(0, sep); } else { + searchWord = prefix_; prefix_ = ""; } @@ -198,7 +201,10 @@ void SourceExprCommand::completeInstallable(std::string_view prefix) if (v2.type() == nAttrs) { for (auto & i : *v2.attrs) { - completions->add(i.name); + std::string name = i.name; + if (name.find(searchWord) == 0) { + completions->add(i.name); + } } } } else { -- cgit v1.2.3 From 3e57e3480b372ed9c5dffc1025eae5773b8691e7 Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Fri, 2 Jul 2021 15:36:14 +0300 Subject: Add use-registries config option (and deprecate --no-registries flag) Some people want to avoid using registries at all on their system; Instead of having to add --no-registries to every command, this commit allows to set use-registries = false in the config. --no-registries is still allowed everywhere it was allowed previously, but is now deprecated. Co-authored-by: Eelco Dolstra --- src/libcmd/installables.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 658b415f3..0ffb97a5e 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -60,7 +60,10 @@ MixFlakeOptions::MixFlakeOptions() .longName = "no-registries", .description = "Don't allow lookups in the flake registries.", .category = category, - .handler = {&lockFlags.useRegistries, false} + .handler = {[&]() { + lockFlags.useRegistries = false; + warn("--no-registries is deprecated; use --no-use-registries (a.k.a --option use-registries false)"); + }} }); addFlag({ -- cgit v1.2.3 From 3bb8667a1758ad10b5f8621f7e187c38c9c860c0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 21 Jul 2021 14:27:37 +0200 Subject: Tweak --no/use-registries doc strings --- src/libcmd/installables.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 0ffb97a5e..95327f958 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -58,11 +58,12 @@ MixFlakeOptions::MixFlakeOptions() addFlag({ .longName = "no-registries", - .description = "Don't allow lookups in the flake registries.", + .description = + "Don't allow lookups in the flake registries. This option is deprecated; use `--no-use-registries`.", .category = category, .handler = {[&]() { lockFlags.useRegistries = false; - warn("--no-registries is deprecated; use --no-use-registries (a.k.a --option use-registries false)"); + warn("'--no-registries' is deprecated; use '--no-use-registries'"); }} }); -- cgit v1.2.3 From bef40c29491ba9b31c85b9b89a5342979344f583 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 29 Jun 2021 21:09:48 +0200 Subject: Add --eval-store option --- src/libcmd/command.cc | 32 ++++++++++++++++++++++++++++++++ src/libcmd/command.hh | 13 +++++++++++-- src/libcmd/installables.cc | 13 ------------- 3 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 6777b23be..93f20a8c3 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -54,6 +54,38 @@ void StoreCommand::run() run(getStore()); } +EvalCommand::EvalCommand() +{ + // FIXME: move to MixEvalArgs? + addFlag({ + .longName = "eval-store", + .description = "The Nix store to use for evaluations.", + .labels = {"store-url"}, + //.category = ..., + .handler = {&evalStoreUrl}, + }); +} + +EvalCommand::~EvalCommand() +{ + if (evalState) + evalState->printStats(); +} + +ref EvalCommand::getEvalStore() +{ + if (!evalStore) + evalStore = evalStoreUrl ? openStore(*evalStoreUrl) : getStore(); + return ref(evalStore); +} + +ref EvalCommand::getEvalState() +{ + if (!evalState) + evalState = std::make_shared(searchPath, getEvalStore(), getStore()); + return ref(evalState); +} + BuiltPathsCommand::BuiltPathsCommand(bool recursive) : recursive(recursive) { diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 35b3a384b..3aba8f25f 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -45,11 +45,20 @@ private: struct EvalCommand : virtual StoreCommand, MixEvalArgs { + EvalCommand(); + + ~EvalCommand(); + + ref getEvalStore(); + ref getEvalState(); - std::shared_ptr evalState; +private: + std::optional evalStoreUrl; - ~EvalCommand(); + std::shared_ptr evalStore; + + std::shared_ptr evalState; }; struct MixFlakeOptions : virtual Args, EvalCommand diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 95327f958..66ec63da2 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -289,19 +289,6 @@ void completeFlakeRefWithFragment( completeFlakeRef(evalState->store, prefix); } -ref EvalCommand::getEvalState() -{ - if (!evalState) - evalState = std::make_shared(searchPath, getStore()); - return ref(evalState); -} - -EvalCommand::~EvalCommand() -{ - if (evalState) - evalState->printStats(); -} - void completeFlakeRef(ref store, std::string_view prefix) { if (prefix == "") -- cgit v1.2.3 From 3d9de41a5b86520ff0c994dc7ac1023d2a441083 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 29 Jun 2021 21:17:48 +0200 Subject: Hacky fast closure copying mechanism --- src/libcmd/installables.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 66ec63da2..ca4d509c2 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -12,6 +12,7 @@ #include "eval-cache.hh" #include "url.hh" #include "registry.hh" +#include "remote-store.hh" #include #include @@ -378,6 +379,7 @@ DerivedPaths InstallableValue::toDerivedPaths() DerivedPaths res; std::map> drvsToOutputs; + RealisedPath::Set drvsToCopy; // Group by derivation, helps with .all in particular for (auto & drv : toDerivations()) { @@ -385,11 +387,38 @@ DerivedPaths InstallableValue::toDerivedPaths() if (outputName == "") throw Error("derivation '%s' lacks an 'outputName' attribute", state->store->printStorePath(drv.drvPath)); drvsToOutputs[drv.drvPath].insert(outputName); + drvsToCopy.insert(drv.drvPath); } for (auto & i : drvsToOutputs) res.push_back(DerivedPath::Built { i.first, i.second }); + // FIXME: Temporary hack + if (state->store != state->buildStore) { + RealisedPath::Set closure; + RealisedPath::closure(*state->store, drvsToCopy, closure); + + if (dynamic_cast(&*state->buildStore)) { + StorePathSet closure2; + for (auto & p : closure) + closure2.insert(p.path()); + + auto valid = state->buildStore->queryValidPaths(closure2); + StorePathSet missing; + for (auto & p : closure2) + if (!valid.count(p)) missing.insert(p); + + if (!missing.empty()) { + auto source = sinkToSource([&](Sink & sink) { + state->store->exportPaths(missing, sink); + }); + state->buildStore->importPaths(*source, NoCheckSigs); + } + + } else + copyPaths(state->store, state->buildStore, closure); + } + return res; } -- cgit v1.2.3 From 2ff3035cf4d5167d180878d69cb47b31890a24c4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Jul 2021 14:28:33 +0200 Subject: Support --eval-store in nix-instantiate and nix-build --- src/libcmd/command.cc | 8 -------- src/libcmd/command.hh | 2 -- 2 files changed, 10 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 93f20a8c3..4add710ed 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -56,14 +56,6 @@ void StoreCommand::run() EvalCommand::EvalCommand() { - // FIXME: move to MixEvalArgs? - addFlag({ - .longName = "eval-store", - .description = "The Nix store to use for evaluations.", - .labels = {"store-url"}, - //.category = ..., - .handler = {&evalStoreUrl}, - }); } EvalCommand::~EvalCommand() diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 3aba8f25f..659b13559 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -54,8 +54,6 @@ struct EvalCommand : virtual StoreCommand, MixEvalArgs ref getEvalState(); private: - std::optional evalStoreUrl; - std::shared_ptr evalStore; std::shared_ptr evalState; -- cgit v1.2.3 From e9848beca704d27a13e28b4403251725bd485bb2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 16 Jul 2021 09:37:33 +0200 Subject: nix-build: Copy drv closure between eval store and build store --- src/libcmd/installables.cc | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index ca4d509c2..124df34ea 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -12,7 +12,6 @@ #include "eval-cache.hh" #include "url.hh" #include "registry.hh" -#include "remote-store.hh" #include #include @@ -393,31 +392,7 @@ DerivedPaths InstallableValue::toDerivedPaths() for (auto & i : drvsToOutputs) res.push_back(DerivedPath::Built { i.first, i.second }); - // FIXME: Temporary hack - if (state->store != state->buildStore) { - RealisedPath::Set closure; - RealisedPath::closure(*state->store, drvsToCopy, closure); - - if (dynamic_cast(&*state->buildStore)) { - StorePathSet closure2; - for (auto & p : closure) - closure2.insert(p.path()); - - auto valid = state->buildStore->queryValidPaths(closure2); - StorePathSet missing; - for (auto & p : closure2) - if (!valid.count(p)) missing.insert(p); - - if (!missing.empty()) { - auto source = sinkToSource([&](Sink & sink) { - state->store->exportPaths(missing, sink); - }); - state->buildStore->importPaths(*source, NoCheckSigs); - } - - } else - copyPaths(state->store, state->buildStore, closure); - } + copyClosure(state->store, state->buildStore, drvsToCopy); return res; } -- cgit v1.2.3 From 8d9f7048cd3b09fb58f6bad0328f644b0ddaaa16 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 16 Jul 2021 16:04:47 +0200 Subject: Use eval-store in more places In particular, this now works: $ nix path-info --eval-store auto --store https://cache.nixos.org nixpkgs#hello Previously this would fail as it would try to upload the hello .drv to cache.nixos.org. Now the .drv is instantiated in the local store, and then we check for the existence of the outputs in cache.nixos.org. --- src/libcmd/command.cc | 2 +- src/libcmd/command.hh | 17 ++++++++++++----- src/libcmd/installables.cc | 38 ++++++++++++++++++++------------------ src/libcmd/installables.hh | 2 +- 4 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 4add710ed..2daf43aa7 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -115,7 +115,7 @@ void BuiltPathsCommand::run(ref store) for (auto & p : store->queryAllValidPaths()) paths.push_back(BuiltPath::Opaque{p}); } else { - paths = toBuiltPaths(store, realiseMode, operateOn, installables); + paths = toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables); if (recursive) { // XXX: This only computes the store path closure, ignoring // intermediate realisations diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 659b13559..f3625ed0d 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -223,15 +223,21 @@ static RegisterCommand registerCommand2(std::vector && name) return RegisterCommand(std::move(name), [](){ return make_ref(); }); } -BuiltPaths build(ref store, Realise mode, +BuiltPaths build(ref evalStore, ref store, Realise mode, std::vector> installables, BuildMode bMode = bmNormal); -std::set toStorePaths(ref store, - Realise mode, OperateOn operateOn, +std::set toStorePaths( + ref evalStore, + ref store, + Realise mode, + OperateOn operateOn, std::vector> installables); -StorePath toStorePath(ref store, - Realise mode, OperateOn operateOn, +StorePath toStorePath( + ref evalStore, + ref store, + Realise mode, + OperateOn operateOn, std::shared_ptr installable); std::set toDerivations(ref store, @@ -239,6 +245,7 @@ std::set toDerivations(ref store, bool useDeriver = false); BuiltPaths toBuiltPaths( + ref evalStore, ref store, Realise mode, OperateOn operateOn, diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 124df34ea..00f8105ae 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -392,8 +392,6 @@ DerivedPaths InstallableValue::toDerivedPaths() for (auto & i : drvsToOutputs) res.push_back(DerivedPath::Built { i.first, i.second }); - copyClosure(state->store, state->buildStore, drvsToCopy); - return res; } @@ -703,10 +701,10 @@ std::shared_ptr SourceExprCommand::parseInstallable( return installables.front(); } -BuiltPaths getBuiltPaths(ref store, DerivedPaths hopefullyBuiltPaths) +BuiltPaths getBuiltPaths(ref evalStore, ref store, const DerivedPaths & hopefullyBuiltPaths) { BuiltPaths res; - for (auto& b : hopefullyBuiltPaths) + for (auto & b : hopefullyBuiltPaths) std::visit( overloaded{ [&](DerivedPath::Opaque bo) { @@ -714,14 +712,13 @@ BuiltPaths getBuiltPaths(ref store, DerivedPaths hopefullyBuiltPaths) }, [&](DerivedPath::Built bfd) { OutputPathMap outputs; - auto drv = store->readDerivation(bfd.drvPath); - auto outputHashes = staticOutputHashes(*store, drv); + auto drv = evalStore->readDerivation(bfd.drvPath); + auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive auto drvOutputs = drv.outputsAndOptPaths(*store); - for (auto& output : bfd.outputs) { + for (auto & output : bfd.outputs) { if (!outputHashes.count(output)) throw Error( - "the derivation '%s' doesn't have an output " - "named '%s'", + "the derivation '%s' doesn't have an output named '%s'", store->printStorePath(bfd.drvPath), output); if (settings.isExperimentalFeatureEnabled( "ca-derivations")) { @@ -753,7 +750,7 @@ BuiltPaths getBuiltPaths(ref store, DerivedPaths hopefullyBuiltPaths) return res; } -BuiltPaths build(ref store, Realise mode, +BuiltPaths build(ref evalStore, ref store, Realise mode, std::vector> installables, BuildMode bMode) { if (mode == Realise::Nothing) @@ -771,18 +768,19 @@ BuiltPaths build(ref store, Realise mode, else if (mode == Realise::Outputs) store->buildPaths(pathsToBuild, bMode); - return getBuiltPaths(store, pathsToBuild); + return getBuiltPaths(evalStore, store, pathsToBuild); } BuiltPaths toBuiltPaths( + ref evalStore, ref store, Realise mode, OperateOn operateOn, std::vector> installables) { - if (operateOn == OperateOn::Output) { - return build(store, mode, installables); - } else { + if (operateOn == OperateOn::Output) + return build(evalStore, store, mode, installables); + else { if (mode == Realise::Nothing) settings.readOnlyMode = true; @@ -793,23 +791,27 @@ BuiltPaths toBuiltPaths( } } -StorePathSet toStorePaths(ref store, +StorePathSet toStorePaths( + ref evalStore, + ref store, Realise mode, OperateOn operateOn, std::vector> installables) { StorePathSet outPaths; - for (auto & path : toBuiltPaths(store, mode, operateOn, installables)) { + for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) { auto thisOutPaths = path.outPaths(); outPaths.insert(thisOutPaths.begin(), thisOutPaths.end()); } return outPaths; } -StorePath toStorePath(ref store, +StorePath toStorePath( + ref evalStore, + ref store, Realise mode, OperateOn operateOn, std::shared_ptr installable) { - auto paths = toStorePaths(store, mode, operateOn, {installable}); + auto paths = toStorePaths(evalStore, store, mode, operateOn, {installable}); if (paths.size() != 1) throw Error("argument '%s' should evaluate to one store path", installable->what()); diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 298fd48f8..79931ad3e 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -26,7 +26,7 @@ struct App struct UnresolvedApp { App unresolved; - App resolve(ref); + App resolve(ref evalStore, ref store); }; struct Installable -- cgit v1.2.3 From eb6db4fd384f34ca426116cd353c02af7d0f9214 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 19 Jul 2021 15:43:08 +0200 Subject: buildPaths(): Add an evalStore argument With this, we don't have to copy the entire .drv closure to the destination store ahead of time (or at all). Instead, buildPaths() reads .drv files from the eval store and copies inputSrcs to the destination store if it needs to build a derivation. Issue #5025. --- src/libcmd/installables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 00f8105ae..e3ce564b0 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -766,7 +766,7 @@ BuiltPaths build(ref evalStore, ref store, Realise mode, if (mode == Realise::Nothing) printMissing(store, pathsToBuild, lvlError); else if (mode == Realise::Outputs) - store->buildPaths(pathsToBuild, bMode); + store->buildPaths(pathsToBuild, bMode, evalStore); return getBuiltPaths(evalStore, store, pathsToBuild); } -- cgit v1.2.3 From ae0c026fe9f5532e95e3d2e4dc87c0665b1c59f8 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 24 Jul 2021 09:15:01 +0000 Subject: Enable pthreads for new libraries Otherwise the lack of pthread causes linking to fail for NetBSD. --- src/libcmd/local.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/local.mk b/src/libcmd/local.mk index ab0e0e43d..431d8ec06 100644 --- a/src/libcmd/local.mk +++ b/src/libcmd/local.mk @@ -8,7 +8,7 @@ libcmd_SOURCES := $(wildcard $(d)/*.cc) libcmd_CXXFLAGS += -I src/libutil -I src/libstore -I src/libexpr -I src/libmain -I src/libfetchers -libcmd_LDFLAGS = -llowdown +libcmd_LDFLAGS = -llowdown -pthread libcmd_LIBS = libstore libutil libexpr libmain libfetchers -- cgit v1.2.3 From 9f13cb31e82c0c2872eabe02d25c797fefc42f55 Mon Sep 17 00:00:00 2001 From: Piotr Szubiakowski Date: Fri, 13 Aug 2021 21:07:31 +0000 Subject: Install pkg-config files in the correct location Use `$(libdir)` while installing .pc files looks like a more generic solution. For example, it will work for distributions like RHEL or Fedora where .pc files are installed in `/usr/lib64/pkgconfig`. --- src/libcmd/local.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/local.mk b/src/libcmd/local.mk index 431d8ec06..0a684468e 100644 --- a/src/libcmd/local.mk +++ b/src/libcmd/local.mk @@ -12,4 +12,4 @@ libcmd_LDFLAGS = -llowdown -pthread libcmd_LIBS = libstore libutil libexpr libmain libfetchers -$(eval $(call install-file-in, $(d)/nix-cmd.pc, $(prefix)/lib/pkgconfig, 0644)) +$(eval $(call install-file-in, $(d)/nix-cmd.pc, $(libdir)/pkgconfig, 0644)) -- cgit v1.2.3 From 21d0334e490465f764685fb4b00b31644655ec99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 14 Aug 2021 00:17:16 +0200 Subject: fix typo in ca-error message --- src/libcmd/installables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e3ce564b0..68e0469c3 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -729,7 +729,7 @@ BuiltPaths getBuiltPaths(ref evalStore, ref store, const DerivedPa if (!realisation) throw Error( "cannot operate on an output of unbuilt " - "content-addresed derivation '%s'", + "content-addressed derivation '%s'", outputId.to_string()); outputs.insert_or_assign( output, realisation->outPath); -- cgit v1.2.3 From a4c6d319a869ba5d90183ec7730d7a2c97f85e0b Mon Sep 17 00:00:00 2001 From: Pamplemousse Date: Wed, 25 Aug 2021 08:58:33 -0700 Subject: Don't overwrite user provided `lib*_LDFLAGS` Signed-off-by: Pamplemousse --- src/libcmd/local.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/local.mk b/src/libcmd/local.mk index 431d8ec06..31aee2511 100644 --- a/src/libcmd/local.mk +++ b/src/libcmd/local.mk @@ -8,7 +8,7 @@ libcmd_SOURCES := $(wildcard $(d)/*.cc) libcmd_CXXFLAGS += -I src/libutil -I src/libstore -I src/libexpr -I src/libmain -I src/libfetchers -libcmd_LDFLAGS = -llowdown -pthread +libcmd_LDFLAGS += -llowdown -pthread libcmd_LIBS = libstore libutil libexpr libmain libfetchers -- cgit v1.2.3 From b2e8120d25de5303bfb6a99c14d3ecad21f55a05 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Sep 2021 14:01:07 +0200 Subject: parseInstallables(): Parse store paths as store paths If the store path contains a flake, this means that a command like "nix path-info /path" will show info about /path, not about the default output of the flake in /path. If you want the latter, you can explicitly ask for it by doing "nix path-info path:/path". Fixes #4568. --- src/libcmd/installables.cc | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 68e0469c3..0091a938a 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -654,6 +654,17 @@ std::vector> SourceExprCommand::parseInstallables( for (auto & s : ss) { std::exception_ptr ex; + if (s.find('/') != std::string::npos) { + try { + result.push_back(std::make_shared(store, store->followLinksToStorePath(s))); + continue; + } catch (BadStorePath &) { + } catch (...) { + if (!ex) + ex = std::current_exception(); + } + } + try { auto [flakeRef, fragment] = parseFlakeRefWithFragment(s, absPath(".")); result.push_back(std::make_shared( @@ -668,25 +679,7 @@ std::vector> SourceExprCommand::parseInstallables( ex = std::current_exception(); } - if (s.find('/') != std::string::npos) { - try { - result.push_back(std::make_shared(store, store->followLinksToStorePath(s))); - continue; - } catch (BadStorePath &) { - } catch (...) { - if (!ex) - ex = std::current_exception(); - } - } - std::rethrow_exception(ex); - - /* - throw Error( - pathExists(s) - ? "path '%s' is not a flake or a store path" - : "don't know how to handle argument '%s'", s); - */ } } -- cgit v1.2.3 From bc6e7ca046952bd773558a3c4984e4f1c2717234 Mon Sep 17 00:00:00 2001 From: Georges Dubus Date: Fri, 3 Jul 2020 14:21:31 +0200 Subject: Don't use read-only mode for nix build --dry-run In dry run mode, new derivations can't be create, so running the command on anything that has not been evaluated before results in an error message of the form `don't know how to build these paths (may be caused by read-only store access)`. For comparison, the classical `nix-build --dry-run` doesn't use read-only mode. Closes #1795 (cherry picked from commit 54525682df707742e58311c32e9c9cb18de1e31f) --- src/libcmd/installables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 0091a938a..86080f53a 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -756,7 +756,7 @@ BuiltPaths build(ref evalStore, ref store, Realise mode, pathsToBuild.insert(pathsToBuild.end(), b.begin(), b.end()); } - if (mode == Realise::Nothing) + if (mode == Realise::Nothing || mode == Realise::Derivation) printMissing(store, pathsToBuild, lvlError); else if (mode == Realise::Outputs) store->buildPaths(pathsToBuild, bMode, evalStore); -- cgit v1.2.3 From 90b2dd570cbd8313a8cf45b3cf66ddef2bb06e07 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Sep 2021 15:00:52 +0200 Subject: Add FIXME --- src/libcmd/command.hh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libcmd') diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index f3625ed0d..c7af8bb7c 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -108,6 +108,8 @@ enum class Realise { exists. */ Derivation, /* Evaluate in dry-run mode. Postcondition: nothing. */ + // FIXME: currently unused, but could be revived if we can + // evaluate derivations in-memory. Nothing }; -- cgit v1.2.3 From 02ece164bea52b5dddb98a745f71996b326ee0d1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Sep 2021 10:39:39 +0200 Subject: Make installables const --- src/libcmd/command.hh | 16 ++++++++++------ src/libcmd/installables.cc | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index c7af8bb7c..dac146d24 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -225,15 +225,18 @@ static RegisterCommand registerCommand2(std::vector && name) return RegisterCommand(std::move(name), [](){ return make_ref(); }); } -BuiltPaths build(ref evalStore, ref store, Realise mode, - std::vector> installables, BuildMode bMode = bmNormal); +BuiltPaths build( + ref evalStore, + ref store, Realise mode, + const std::vector> & installables, + BuildMode bMode = bmNormal); std::set toStorePaths( ref evalStore, ref store, Realise mode, OperateOn operateOn, - std::vector> installables); + const std::vector> & installables); StorePath toStorePath( ref evalStore, @@ -242,8 +245,9 @@ StorePath toStorePath( OperateOn operateOn, std::shared_ptr installable); -std::set toDerivations(ref store, - std::vector> installables, +std::set toDerivations( + ref store, + const std::vector> & installables, bool useDeriver = false); BuiltPaths toBuiltPaths( @@ -251,7 +255,7 @@ BuiltPaths toBuiltPaths( ref store, Realise mode, OperateOn operateOn, - std::vector> installables); + const std::vector> & installables); /* Helper function to generate args that invoke $EDITOR on filename:lineno. */ diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 86080f53a..8015cff4d 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -743,8 +743,12 @@ BuiltPaths getBuiltPaths(ref evalStore, ref store, const DerivedPa return res; } -BuiltPaths build(ref evalStore, ref store, Realise mode, - std::vector> installables, BuildMode bMode) +BuiltPaths build( + ref evalStore, + ref store, + Realise mode, + const std::vector> & installables, + BuildMode bMode) { if (mode == Realise::Nothing) settings.readOnlyMode = true; @@ -769,7 +773,7 @@ BuiltPaths toBuiltPaths( ref store, Realise mode, OperateOn operateOn, - std::vector> installables) + const std::vector> & installables) { if (operateOn == OperateOn::Output) return build(evalStore, store, mode, installables); @@ -788,7 +792,7 @@ StorePathSet toStorePaths( ref evalStore, ref store, Realise mode, OperateOn operateOn, - std::vector> installables) + const std::vector> & installables) { StorePathSet outPaths; for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) { @@ -812,8 +816,10 @@ StorePath toStorePath( return *paths.begin(); } -StorePathSet toDerivations(ref store, - std::vector> installables, bool useDeriver) +StorePathSet toDerivations( + ref store, + const std::vector> & installables, + bool useDeriver) { StorePathSet drvPaths; -- cgit v1.2.3 From a73be287172239f2e2ac7ba9bc90d90b65028a3f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Sep 2021 13:52:14 +0200 Subject: renderMarkdownToTerminal(): Fix terminal width computation --- src/libcmd/markdown.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/markdown.cc b/src/libcmd/markdown.cc index d25113d93..8a2f155d6 100644 --- a/src/libcmd/markdown.cc +++ b/src/libcmd/markdown.cc @@ -12,7 +12,7 @@ std::string renderMarkdownToTerminal(std::string_view markdown) struct lowdown_opts opts { .type = LOWDOWN_TERM, .maxdepth = 20, - .cols = std::min(getWindowSize().second, (unsigned short) 80), + .cols = std::max(getWindowSize().second, (unsigned short) 80), .hmargin = 0, .vmargin = 0, .feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES, -- cgit v1.2.3 From 75837bb5953653a184eda92ef9727c96f41a4512 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Sep 2021 14:57:58 +0200 Subject: Respect NO_COLOR in Markdown output --- src/libcmd/markdown.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd') diff --git a/src/libcmd/markdown.cc b/src/libcmd/markdown.cc index 8a2f155d6..737356284 100644 --- a/src/libcmd/markdown.cc +++ b/src/libcmd/markdown.cc @@ -44,7 +44,7 @@ std::string renderMarkdownToTerminal(std::string_view markdown) if (!rndr_res) throw Error("allocation error while rendering Markdown"); - return std::string(buf->data, buf->size); + return filterANSIEscapes(std::string(buf->data, buf->size), !shouldANSI()); } } -- cgit v1.2.3 From aedbc7b683c3110bb9627cbea376953b766eaf3d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 24 Sep 2021 15:21:41 +0200 Subject: Use latest lowdown This improves list rendering (https://github.com/kristapsdz/lowdown/issues/73). --- src/libcmd/markdown.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/markdown.cc b/src/libcmd/markdown.cc index 737356284..29bb4d31e 100644 --- a/src/libcmd/markdown.cc +++ b/src/libcmd/markdown.cc @@ -25,7 +25,7 @@ std::string renderMarkdownToTerminal(std::string_view markdown) Finally freeDoc([&]() { lowdown_doc_free(doc); }); size_t maxn = 0; - auto node = lowdown_doc_parse(doc, &maxn, markdown.data(), markdown.size()); + auto node = lowdown_doc_parse(doc, &maxn, markdown.data(), markdown.size(), nullptr); if (!node) throw Error("cannot parse Markdown document"); Finally freeNode([&]() { lowdown_node_free(node); }); @@ -40,7 +40,7 @@ std::string renderMarkdownToTerminal(std::string_view markdown) throw Error("cannot allocate Markdown output buffer"); Finally freeBuffer([&]() { lowdown_buf_free(buf); }); - int rndr_res = lowdown_term_rndr(buf, nullptr, renderer, node); + int rndr_res = lowdown_term_rndr(buf, renderer, node); if (!rndr_res) throw Error("allocation error while rendering Markdown"); -- cgit v1.2.3 From a15e65eef0443a4d41b1a9e9b1504234dc5f5947 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 27 Sep 2021 10:53:09 +0200 Subject: run(): Move --- src/libcmd/command.cc | 4 ++-- src/libcmd/command.hh | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 2daf43aa7..2b9902677 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -138,7 +138,7 @@ StorePathsCommand::StorePathsCommand(bool recursive) { } -void StorePathsCommand::run(ref store, BuiltPaths paths) +void StorePathsCommand::run(ref store, BuiltPaths && paths) { StorePaths storePaths; for (auto& builtPath : paths) @@ -148,7 +148,7 @@ void StorePathsCommand::run(ref store, BuiltPaths paths) run(store, std::move(storePaths)); } -void StorePathCommand::run(ref store, std::vector storePaths) +void StorePathCommand::run(ref store, std::vector && storePaths) { if (storePaths.size() != 1) throw UsageError("this command requires exactly one store path"); diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index dac146d24..07f398468 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -169,7 +169,7 @@ public: using StoreCommand::run; - virtual void run(ref store, BuiltPaths paths) = 0; + virtual void run(ref store, BuiltPaths && paths) = 0; void run(ref store) override; @@ -182,9 +182,9 @@ struct StorePathsCommand : public BuiltPathsCommand using BuiltPathsCommand::run; - virtual void run(ref store, std::vector storePaths) = 0; + virtual void run(ref store, std::vector && storePaths) = 0; - void run(ref store, BuiltPaths paths) override; + void run(ref store, BuiltPaths && paths) override; }; /* A command that operates on exactly one store path. */ @@ -194,7 +194,7 @@ struct StorePathCommand : public StorePathsCommand virtual void run(ref store, const StorePath & storePath) = 0; - void run(ref store, std::vector storePaths) override; + void run(ref store, std::vector && storePaths) override; }; /* A helper class for registering commands globally. */ -- cgit v1.2.3 From 4b2b15113196e403bc32ce0d7b4338971d7954a8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 27 Sep 2021 10:57:11 +0200 Subject: nix path-info -r: Don't duplicate the root paths This fixes $ nix path-info -r $(type -P ls) /nix/store/vfilzcp8a467w3p0mp54ybq6bdzb8w49-coreutils-8.32 /nix/store/5d821pjgzb90lw4zbg6xwxs7llm335wr-libunistring-0.9.10 ... /nix/store/mrv4y369nw6hg4pw8d9p9bfdxj9pjw0x-acl-2.3.0 /nix/store/vfilzcp8a467w3p0mp54ybq6bdzb8w49-coreutils-8.32 Also, output the paths in topologically sorted order like we used to. --- src/libcmd/command.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 2b9902677..0d61e12d0 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -120,7 +120,7 @@ void BuiltPathsCommand::run(ref store) // XXX: This only computes the store path closure, ignoring // intermediate realisations StorePathSet pathsRoots, pathsClosure; - for (auto & root: paths) { + for (auto & root : paths) { auto rootFromThis = root.outPaths(); pathsRoots.insert(rootFromThis.begin(), rootFromThis.end()); } @@ -140,12 +140,15 @@ StorePathsCommand::StorePathsCommand(bool recursive) void StorePathsCommand::run(ref store, BuiltPaths && paths) { - StorePaths storePaths; - for (auto& builtPath : paths) - for (auto& p : builtPath.outPaths()) - storePaths.push_back(p); + StorePathSet storePaths; + for (auto & builtPath : paths) + for (auto & p : builtPath.outPaths()) + storePaths.insert(p); - run(store, std::move(storePaths)); + auto sorted = store->topoSortPaths(storePaths); + std::reverse(sorted.begin(), sorted.end()); + + run(store, std::move(sorted)); } void StorePathCommand::run(ref store, std::vector && storePaths) -- cgit v1.2.3 From 242f9bf3dc04170502020fb0338b78ea76b9ebac Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 30 Sep 2021 21:31:21 +0000 Subject: `std::visit` by reference I had started the trend of doing `std::visit` by value (because a type error once mislead me into thinking that was the only form that existed). While the optomizer in principle should be able to deal with extra coppying or extra indirection once the lambdas inlined, sticking with by reference is the conventional default. I hope this might even improve performance. --- src/libcmd/command.cc | 4 ++-- src/libcmd/installables.cc | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/libcmd') diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 0d61e12d0..fd3edfc46 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -203,10 +203,10 @@ void MixProfile::updateProfile(const BuiltPaths & buildables) for (auto & buildable : buildables) { std::visit(overloaded { - [&](BuiltPath::Opaque bo) { + [&](const BuiltPath::Opaque & bo) { result.push_back(bo.path); }, - [&](BuiltPath::Built bfd) { + [&](const BuiltPath::Built & bfd) { for (auto & output : bfd.outputs) { result.push_back(output.second); } diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 8015cff4d..0f0fcf39e 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -697,13 +697,13 @@ std::shared_ptr SourceExprCommand::parseInstallable( BuiltPaths getBuiltPaths(ref evalStore, ref store, const DerivedPaths & hopefullyBuiltPaths) { BuiltPaths res; - for (auto & b : hopefullyBuiltPaths) + for (const auto & b : hopefullyBuiltPaths) std::visit( overloaded{ - [&](DerivedPath::Opaque bo) { + [&](const DerivedPath::Opaque & bo) { res.push_back(BuiltPath::Opaque{bo.path}); }, - [&](DerivedPath::Built bfd) { + [&](const DerivedPath::Built & bfd) { OutputPathMap outputs; auto drv = evalStore->readDerivation(bfd.drvPath); auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive @@ -823,10 +823,10 @@ StorePathSet toDerivations( { StorePathSet drvPaths; - for (auto & i : installables) - for (auto & b : i->toDerivedPaths()) + for (const auto & i : installables) + for (const auto & b : i->toDerivedPaths()) std::visit(overloaded { - [&](DerivedPath::Opaque bo) { + [&](const DerivedPath::Opaque & bo) { if (!useDeriver) throw Error("argument '%s' did not evaluate to a derivation", i->what()); auto derivers = store->queryValidDerivers(bo.path); @@ -835,7 +835,7 @@ StorePathSet toDerivations( // FIXME: use all derivers? drvPaths.insert(*derivers.begin()); }, - [&](DerivedPath::Built bfd) { + [&](const DerivedPath::Built & bfd) { drvPaths.insert(bfd.drvPath); }, }, b.raw()); -- cgit v1.2.3