From ff28fffce26bba37685f7e230d1285e7d034f748 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Sep 2021 14:00:56 +0200 Subject: [PATCH 1/4] Don't cache realiseContext() errors Errors that depend on the configuration (such as whether allow-import-from-derivation is set) should not be cached. --- src/libexpr/primops.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 8a087a781..c98a30177 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -52,7 +52,8 @@ void EvalState::realiseContext(const PathSet & context) if (drvs.empty()) return; if (!evalSettings.enableImportFromDerivation) - throw EvalError("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false", + throw Error( + "cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled", store->printStorePath(drvs.begin()->drvPath)); /* For performance, prefetch all substitute info. */ From 8fdb1d057ac72d07b9e8c6e522d4d7f0a8bdf352 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Sep 2021 14:12:31 +0200 Subject: [PATCH 2/4] Quiet --- doc/manual/local.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/local.mk b/doc/manual/local.mk index 5e61b2671..a8c52f841 100644 --- a/doc/manual/local.mk +++ b/doc/manual/local.mk @@ -92,7 +92,7 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli lowdown -sT man -M section=1 $$tmpFile -o $(DESTDIR)$$(dirname $@)/$$name.1; \ rm $$tmpFile; \ done - touch $@ + @touch $@ $(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/command-ref/new-cli $(d)/src/command-ref/conf-file.md $(d)/src/expressions/builtins.md $(call rwildcard, $(d)/src, *.md) $(trace-gen) RUST_LOG=warn mdbook build doc/manual -d $(DESTDIR)$(docdir)/manual From d8c10028d96d49b2c783fe279daa91402e8a91da Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Sep 2021 14:15:35 +0200 Subject: [PATCH 3/4] Make setDefault() typed --- src/libstore/binary-cache-store.cc | 4 ++-- src/libstore/http-binary-cache-store.cc | 4 ++-- src/libstore/s3-binary-cache-store.cc | 4 ++-- src/libutil/config.cc | 5 ----- src/libutil/config.hh | 3 +-- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 74eb0a9ab..3a6be541f 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -52,9 +52,9 @@ void BinaryCacheStore::init() throw Error("binary cache '%s' is for Nix stores with prefix '%s', not '%s'", getUri(), value, storeDir); } else if (name == "WantMassQuery") { - wantMassQuery.setDefault(value == "1" ? "true" : "false"); + wantMassQuery.setDefault(value == "1"); } else if (name == "Priority") { - priority.setDefault(fmt("%d", std::stoi(value))); + priority.setDefault(std::stoi(value)); } } } diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 0a3afcd51..605ec4b28 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -57,8 +57,8 @@ public: { // FIXME: do this lazily? if (auto cacheInfo = diskCache->cacheExists(cacheUri)) { - wantMassQuery.setDefault(cacheInfo->wantMassQuery ? "true" : "false"); - priority.setDefault(fmt("%d", cacheInfo->priority)); + wantMassQuery.setDefault(cacheInfo->wantMassQuery); + priority.setDefault(cacheInfo->priority); } else { try { BinaryCacheStore::init(); diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 51d86c4e6..7accad7f4 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -232,8 +232,8 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual void init() override { if (auto cacheInfo = diskCache->cacheExists(getUri())) { - wantMassQuery.setDefault(cacheInfo->wantMassQuery ? "true" : "false"); - priority.setDefault(fmt("%d", cacheInfo->priority)); + wantMassQuery.setDefault(cacheInfo->wantMassQuery); + priority.setDefault(cacheInfo->priority); } else { BinaryCacheStore::init(); diskCache->createCache(getUri(), storeDir, wantMassQuery, priority); diff --git a/src/libutil/config.cc b/src/libutil/config.cc index 2a5f913e6..c247c7dae 100644 --- a/src/libutil/config.cc +++ b/src/libutil/config.cc @@ -177,11 +177,6 @@ AbstractSetting::AbstractSetting( { } -void AbstractSetting::setDefault(const std::string & str) -{ - if (!overridden) set(str); -} - nlohmann::json AbstractSetting::toJSON() { return nlohmann::json(toJSONObject()); diff --git a/src/libutil/config.hh b/src/libutil/config.hh index df5c2226f..736810bf3 100644 --- a/src/libutil/config.hh +++ b/src/libutil/config.hh @@ -194,8 +194,6 @@ public: bool overridden = false; - void setDefault(const std::string & str); - protected: AbstractSetting( @@ -253,6 +251,7 @@ public: bool operator !=(const T & v2) const { return value != v2; } void operator =(const T & v) { assign(v); } virtual void assign(const T & v) { value = v; } + void setDefault(const T & v) { if (!overridden) value = v; } void set(const std::string & str, bool append = false) override; From 8623a5b595af57c57e569d3b1e792aa640ceb980 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Sep 2021 17:15:07 +0200 Subject: [PATCH 4/4] Disable IFD selectively It's now disabled by default for the following: * 'nix search' (this was already implied by read-only mode) * 'nix flake show' * 'nix flake check', but only on the hydraJobs output --- src/nix/flake.cc | 39 ++++++++++++++++++++++++++++++--------- src/nix/search.cc | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index a127c3ac0..7d7ada707 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -131,8 +131,18 @@ static void enumerateOutputs(EvalState & state, Value & vFlake, state.forceAttrs(*aOutputs->value); - for (auto & attr : *aOutputs->value->attrs) - callback(attr.name, *attr.value, *attr.pos); + auto sHydraJobs = state.symbols.create("hydraJobs"); + + /* Hack: ensure that hydraJobs is evaluated before anything + else. This way we can disable IFD for hydraJobs and then enable + it for other outputs. */ + if (auto attr = aOutputs->value->attrs->get(sHydraJobs)) + callback(attr->name, *attr->value, *attr->pos); + + for (auto & attr : *aOutputs->value->attrs) { + if (attr.name != sHydraJobs) + callback(attr.name, *attr.value, *attr.pos); + } } struct CmdFlakeMetadata : FlakeCommand, MixJSON @@ -269,7 +279,10 @@ struct CmdFlakeCheck : FlakeCommand void run(nix::ref store) override { - settings.readOnlyMode = !build; + if (!build) { + settings.readOnlyMode = true; + evalSettings.enableImportFromDerivation.setDefault(false); + } auto state = getEvalState(); @@ -381,9 +394,13 @@ struct CmdFlakeCheck : FlakeCommand for (auto & attr : *v.attrs) { state->forceAttrs(*attr.value, *attr.pos); - if (!state->isDerivation(*attr.value)) - checkHydraJobs(attrPath + "." + (std::string) attr.name, - *attr.value, *attr.pos); + auto attrPath2 = attrPath + "." + (std::string) attr.name; + if (state->isDerivation(*attr.value)) { + Activity act(*logger, lvlChatty, actUnknown, + fmt("checking Hydra job '%s'", attrPath2)); + checkDerivation(attrPath2, *attr.value, *attr.pos); + } else + checkHydraJobs(attrPath2, *attr.value, *attr.pos); } } catch (Error & e) { @@ -447,8 +464,8 @@ struct CmdFlakeCheck : FlakeCommand if (!v.isLambda()) throw Error("bundler must be a function"); if (!v.lambda.fun->formals || - v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end() || - v.lambda.fun->formals->argNames.find(state->symbols.create("system")) == v.lambda.fun->formals->argNames.end()) + !v.lambda.fun->formals->argNames.count(state->symbols.create("program")) || + !v.lambda.fun->formals->argNames.count(state->symbols.create("system"))) throw Error("bundler must take formal arguments 'program' and 'system'"); } catch (Error & e) { e.addTrace(pos, hintfmt("while checking the template '%s'", attrPath)); @@ -469,6 +486,8 @@ struct CmdFlakeCheck : FlakeCommand fmt("checking flake output '%s'", name)); try { + evalSettings.enableImportFromDerivation.setDefault(name != "hydraJobs"); + state->forceValue(vOutput, pos); if (name == "checks") { @@ -603,7 +622,7 @@ struct CmdFlakeCheck : FlakeCommand store->buildPaths(drvPaths); } if (hasErrors) - throw Error("Some errors were encountered during the evaluation"); + throw Error("some errors were encountered during the evaluation"); } }; @@ -873,6 +892,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON void run(nix::ref store) override { + evalSettings.enableImportFromDerivation.setDefault(false); + auto state = getEvalState(); auto flake = std::make_shared(lockFlake()); diff --git a/src/nix/search.cc b/src/nix/search.cc index c52a48d4e..0d8fdd5c2 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -62,6 +62,7 @@ struct CmdSearch : InstallableCommand, MixJSON void run(ref store) override { settings.readOnlyMode = true; + evalSettings.enableImportFromDerivation.setDefault(false); // Empty search string should match all packages // Use "^" here instead of ".*" due to differences in resulting highlighting