Add eval-system option

`eval-system` option overrides just the value of `builtins.currentSystem`.
This is more useful than overriding `system` since you can build these
derivations on remote builders which can work on the given system.

Co-authored-by: John Ericson <John.Ericson@Obsidian.Systems>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
This commit is contained in:
Matthew Bauer 2020-09-29 15:33:47 -04:00 committed by John Ericson
parent fc0accf3dc
commit bcbdb09ccf
5 changed files with 40 additions and 6 deletions

View File

@ -89,6 +89,12 @@ std::string EvalSettings::resolvePseudoUrl(std::string_view url)
return std::string(url);
}
const std::string & EvalSettings::getCurrentSystem()
{
const auto & evalSystem = currentSystem.get();
return evalSystem != "" ? evalSystem : settings.thisSystem.get();
}
EvalSettings evalSettings;
static GlobalConfig::Register rEvalSettings(&evalSettings);

View File

@ -27,6 +27,26 @@ struct EvalSettings : Config
[`builtins.nixPath`](@docroot@/language/builtin-constants.md#builtins-nixPath).
)"};
Setting<std::string> currentSystem{
this, "", "eval-system",
R"(
This option defines
[`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem)
in the Nix language if it is set as a non-empty string.
Otherwise, if it is defined as the empty string (the default), the value of the
[`system` ](#conf-system)
configuration setting is used instead.
Unlike `system`, this setting does not change what kind of derivations can be built locally.
This is useful for evaluating Nix code on one system to produce derivations to be built on another type of system.
)"};
/**
* Implements the `eval-system` vs `system` defaulting logic
* described for `eval-system`.
*/
const std::string & getCurrentSystem();
Setting<bool> restrictEval{
this, false, "restrict-eval",
R"(

View File

@ -4383,13 +4383,16 @@ void EvalState::createBaseEnv()
.impureOnly = true,
});
if (!evalSettings.pureEval) {
v.mkString(settings.thisSystem.get());
}
if (!evalSettings.pureEval)
v.mkString(evalSettings.getCurrentSystem());
addConstant("__currentSystem", v, {
.type = nString,
.doc = R"(
The value of the [`system` configuration option](@docroot@/command-ref/conf-file.md#conf-system).
The value of the
[`eval-system`](@docroot@/command-ref/conf-file.md#conf-eval-system)
or else
[`system`](@docroot@/command-ref/conf-file.md#conf-system)
configuration option.
It can be used to set the `system` attribute for [`builtins.derivation`](@docroot@/language/derivations.md) such that the resulting derivation can be built on the same system that evaluates the Nix expression:

View File

@ -214,7 +214,11 @@ public:
In general, you do not have to modify this setting.
While you can force Nix to run a Darwin-specific `builder` executable on a Linux machine, the result would obviously be wrong.
This value is available in the Nix language as [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem).
This value is available in the Nix language as
[`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem)
if the
[`eval-system`](#conf-eval-system)
configuration option is set as the empty string.
)"};
Setting<time_t> maxSilentTime{

View File

@ -1,6 +1,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "eval-settings.hh"
#include "memory-input-accessor.hh"
#include "tests/libexpr.hh"
@ -631,7 +632,7 @@ namespace nix {
TEST_F(PrimOpTest, currentSystem) {
auto v = eval("builtins.currentSystem");
ASSERT_THAT(v, IsStringEq(settings.thisSystem.get()));
ASSERT_THAT(v, IsStringEq(evalSettings.getCurrentSystem()));
}
TEST_F(PrimOpTest, derivation) {