Merge pull request #4093 from matthewbauer/eval-system
Add eval-system option
(cherry picked from commit 071dbbee33af9f27338c3e53e4ea067dbfa14010)
Change-Id: Ia81358c8cfb60241da07a4d0e84b9ee62a18a53f
This commit is contained in:
parent
64a269ef73
commit
7614aa9797
12
doc/manual/rl-next/eval-system.md
Normal file
12
doc/manual/rl-next/eval-system.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
synopsis: Add new `eval-system` setting
|
||||||
|
prs: 4093
|
||||||
|
---
|
||||||
|
|
||||||
|
Add a new `eval-system` option.
|
||||||
|
Unlike `system`, it just overrides the value of `builtins.currentSystem`.
|
||||||
|
This is more useful than overriding `system`, because you can build these derivations on remote builders which can work on the given system.
|
||||||
|
In contrast, `system` also effects scheduling which will cause Nix to build those derivations locally even if that doesn't make sense.
|
||||||
|
|
||||||
|
`eval-system` only takes effect if it is non-empty.
|
||||||
|
If empty (the default) `system` is used as before, so there is no breakage.
|
|
@ -88,6 +88,12 @@ std::string EvalSettings::resolvePseudoUrl(std::string_view url)
|
||||||
return std::string(url);
|
return std::string(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string & EvalSettings::getCurrentSystem()
|
||||||
|
{
|
||||||
|
const auto & evalSystem = currentSystem.get();
|
||||||
|
return evalSystem != "" ? evalSystem : settings.thisSystem.get();
|
||||||
|
}
|
||||||
|
|
||||||
EvalSettings evalSettings;
|
EvalSettings evalSettings;
|
||||||
|
|
||||||
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
||||||
|
|
|
@ -25,6 +25,26 @@ struct EvalSettings : Config
|
||||||
[`builtins.nixPath`](@docroot@/language/builtin-constants.md#builtins-nixPath).
|
[`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{
|
Setting<bool> restrictEval{
|
||||||
this, false, "restrict-eval",
|
this, false, "restrict-eval",
|
||||||
R"(
|
R"(
|
||||||
|
|
|
@ -4288,13 +4288,16 @@ void EvalState::createBaseEnv()
|
||||||
.impureOnly = true,
|
.impureOnly = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!evalSettings.pureEval) {
|
if (!evalSettings.pureEval)
|
||||||
v.mkString(settings.thisSystem.get());
|
v.mkString(evalSettings.getCurrentSystem());
|
||||||
}
|
|
||||||
addConstant("__currentSystem", v, {
|
addConstant("__currentSystem", v, {
|
||||||
.type = nString,
|
.type = nString,
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
The value of the [`system` configuration option](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
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:
|
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:
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,11 @@ public:
|
||||||
In general, you do not have to modify this setting.
|
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.
|
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{
|
Setting<time_t> maxSilentTime{
|
||||||
|
|
35
tests/functional/impure-eval.sh
Normal file
35
tests/functional/impure-eval.sh
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
export REMOTE_STORE="dummy://"
|
||||||
|
|
||||||
|
simpleTest () {
|
||||||
|
local expr=$1; shift
|
||||||
|
local result=$1; shift
|
||||||
|
# rest, extra args
|
||||||
|
|
||||||
|
[[ "$(nix eval --impure --raw "$@" --expr "$expr")" == "$result" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# `builtins.storeDir`
|
||||||
|
|
||||||
|
## Store dir follows `store` store setting
|
||||||
|
simpleTest 'builtins.storeDir' '/foo' --store "$REMOTE_STORE?store=/foo"
|
||||||
|
simpleTest 'builtins.storeDir' '/bar' --store "$REMOTE_STORE?store=/bar"
|
||||||
|
|
||||||
|
# `builtins.currentSystem`
|
||||||
|
|
||||||
|
## `system` alone affects by default
|
||||||
|
simpleTest 'builtins.currentSystem' 'foo' --system 'foo'
|
||||||
|
simpleTest 'builtins.currentSystem' 'bar' --system 'bar'
|
||||||
|
|
||||||
|
## `system` affects if `eval-system` is an empty string
|
||||||
|
simpleTest 'builtins.currentSystem' 'foo' --system 'foo' --eval-system ''
|
||||||
|
simpleTest 'builtins.currentSystem' 'bar' --system 'bar' --eval-system ''
|
||||||
|
|
||||||
|
## `eval-system` alone affects
|
||||||
|
simpleTest 'builtins.currentSystem' 'foo' --eval-system 'foo'
|
||||||
|
simpleTest 'builtins.currentSystem' 'bar' --eval-system 'bar'
|
||||||
|
|
||||||
|
## `eval-system` overrides `system`
|
||||||
|
simpleTest 'builtins.currentSystem' 'bar' --system 'foo' --eval-system 'bar'
|
||||||
|
simpleTest 'builtins.currentSystem' 'baz' --system 'foo' --eval-system 'baz'
|
|
@ -68,6 +68,7 @@ nix_tests = \
|
||||||
build-remote-trustless-should-pass-3.sh \
|
build-remote-trustless-should-pass-3.sh \
|
||||||
build-remote-trustless-should-fail-0.sh \
|
build-remote-trustless-should-fail-0.sh \
|
||||||
nar-access.sh \
|
nar-access.sh \
|
||||||
|
impure-eval.sh \
|
||||||
pure-eval.sh \
|
pure-eval.sh \
|
||||||
eval.sh \
|
eval.sh \
|
||||||
repl.sh \
|
repl.sh \
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "eval-settings.hh"
|
||||||
|
|
||||||
#include "tests/libexpr.hh"
|
#include "tests/libexpr.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -614,7 +616,7 @@ namespace nix {
|
||||||
|
|
||||||
TEST_F(PrimOpTest, currentSystem) {
|
TEST_F(PrimOpTest, currentSystem) {
|
||||||
auto v = eval("builtins.currentSystem");
|
auto v = eval("builtins.currentSystem");
|
||||||
ASSERT_THAT(v, IsStringEq(settings.thisSystem.get()));
|
ASSERT_THAT(v, IsStringEq(evalSettings.getCurrentSystem()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PrimOpTest, derivation) {
|
TEST_F(PrimOpTest, derivation) {
|
||||||
|
|
Loading…
Reference in a new issue