nix-eval-jobs: --apply
Based off of https://github.com/NixOS/nix-eval-jobs/pull/332 and
9f292a402a6edf620b872bedaaad5f0a45c23826
closes https://git.lix.systems/lix-project/lix/issues/1214
Co-authored-by: Mic92 <joerg@thalheim.io>
Co-authored-by: Yannik Sander <yannik@floxdev.com>
Change-Id: Ifba7081b384d18fbdc47437de261d30b65a7930a
(cherry picked from commit 405ff2eb03)
This commit is contained in:
@@ -315,5 +315,8 @@ yorickvp:
|
||||
yshui:
|
||||
github: yshui
|
||||
|
||||
ysndr:
|
||||
github: ysndr
|
||||
|
||||
zimbatm:
|
||||
github: zimbatm
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
synopsis: "nix-eval-jobs support `--apply` flag"
|
||||
cls: [5748]
|
||||
category: "Features"
|
||||
credits: [isabelroses,mic92,ysndr]
|
||||
issues: [fj#1214]
|
||||
---
|
||||
|
||||
`nix-eval-jobs` now supports the `--apply` flag. With this you can apply the
|
||||
provided function to the each derivation, the result of this function will then
|
||||
be serialized as a JSON value and stored inside `"extraValue"` key of the json
|
||||
line output.
|
||||
@@ -46,6 +46,7 @@ executable.
|
||||
$ nix-eval-jobs --help
|
||||
USAGE: nix-eval-jobs [options] expr
|
||||
|
||||
--apply Apply provided Nix function to each derivation. The result of this function will be serialized as a JSON value and stored inside `"extraValue"` key of the json line output.
|
||||
--arg Pass the value *expr* as the argument *name* to Nix functions.
|
||||
--argstr Pass the string *string* as the argument *name* to Nix functions.
|
||||
--check-cache-status Check if the derivations are present locally or in any configured substituters (i.e. binary cache). The information will be exposed in the `isCached` field of the JSON output.
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
#include "eval-args.hh"
|
||||
|
||||
MyArgs::MyArgs(nix::AsyncIoRoot & aio) : MixCommonArgs("nix-eval-jobs"), aio_(aio) {
|
||||
MyArgs::MyArgs(nix::AsyncIoRoot &aio)
|
||||
: MixCommonArgs("nix-eval-jobs"), aio_(aio) {
|
||||
addFlag({
|
||||
.longName = "help",
|
||||
.description = "show usage information",
|
||||
@@ -22,7 +23,8 @@ MyArgs::MyArgs(nix::AsyncIoRoot & aio) : MixCommonArgs("nix-eval-jobs"), aio_(ai
|
||||
if (flag->hidden || hiddenCategories.count(flag->category)) {
|
||||
continue;
|
||||
}
|
||||
std::cout << nix::fmt(" --%-20s %s\n", name, flag->description);
|
||||
std::cout << nix::fmt(" --%-20s %s\n", name,
|
||||
flag->description);
|
||||
}
|
||||
::exit(0);
|
||||
}},
|
||||
@@ -105,6 +107,14 @@ MyArgs::MyArgs(nix::AsyncIoRoot & aio) : MixCommonArgs("nix-eval-jobs"), aio_(ai
|
||||
.description = "treat the argument as a Nix expression",
|
||||
.handler = {&fromArgs, true}});
|
||||
|
||||
addFlag({.longName = "apply",
|
||||
.description =
|
||||
"Apply provided Nix function to each derivation. The result "
|
||||
"of this function will be serialized as a JSON value and "
|
||||
"stored inside `\"extraValue\"` key of the json line output.",
|
||||
.labels = {"expr"},
|
||||
.handler = {&applyExpr}});
|
||||
|
||||
// usually in MixFlakeOptions
|
||||
addFlag({
|
||||
.longName = "override-input",
|
||||
|
||||
@@ -22,6 +22,7 @@ struct MyArgs : virtual public nix::MixEvalArgs,
|
||||
|
||||
bool worker = false;
|
||||
std::string releaseExpr;
|
||||
std::string applyExpr;
|
||||
nix::Path gcRootsDir;
|
||||
bool flake = false;
|
||||
bool fromArgs = false;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <lix/libexpr/symbol-table.hh>
|
||||
#include <lix/libutil/types.hh>
|
||||
#include <lix/libexpr/value.hh>
|
||||
#include <lix/libexpr/value-to-json.hh>
|
||||
#include <lix/libutil/terminal.hh>
|
||||
#include <exception>
|
||||
#include <numeric>
|
||||
@@ -201,6 +202,21 @@ try {
|
||||
maybeConstituents =
|
||||
readConstituents(&v, state, evaluator);
|
||||
}
|
||||
if (args.applyExpr != "") {
|
||||
nix::Expr &applyExpr = state->ctx.parseExprFromString(
|
||||
args.applyExpr, nix::CanonPath::fromCwd());
|
||||
|
||||
nix::Value vApply = state->eval(applyExpr);
|
||||
nix::Value vRes =
|
||||
state->callFunction(vApply, v, nix::noPos);
|
||||
state->forceAttrs(
|
||||
vRes, nix::noPos,
|
||||
"apply needs to evaluate to an attrset");
|
||||
|
||||
nix::NixStringContext context;
|
||||
reply["extraValue"] = nix::printValueAsJSON(
|
||||
*state, true, vRes, nix::noPos, context);
|
||||
}
|
||||
auto drv = Drv(attrPathS, *state, *drvInfo, args,
|
||||
maybeConstituents);
|
||||
reply.update(drv);
|
||||
|
||||
@@ -124,6 +124,45 @@ def test_eval_error() -> None:
|
||||
assert "this is an evaluation error" in attr["error"]
|
||||
|
||||
|
||||
def test_apply() -> None:
|
||||
with TemporaryDirectory() as tempdir:
|
||||
applyExpr = """drv: {
|
||||
the-name = drv.name;
|
||||
version = drv.version or null;
|
||||
}"""
|
||||
|
||||
results, _ = evaluate(
|
||||
tempdir,
|
||||
0,
|
||||
["--workers", "1", "--apply", applyExpr, "--flake", ".#hydraJobs"],
|
||||
)
|
||||
|
||||
assert len(results) == 4 # sanity check that we assert against all jobs
|
||||
|
||||
# Check that nix-eval-jobs applied the expression correctly,
|
||||
# exposing the result under the `extraValue` key, and extracted
|
||||
# 'version' as 'version' and 'name' as 'the-name'
|
||||
dotted_job = results[0]
|
||||
assert dotted_job["attr"] == '"dotted.attr"'
|
||||
assert dotted_job["extraValue"]["the-name"].startswith("hello-")
|
||||
assert dotted_job["extraValue"]["version"] is not None
|
||||
|
||||
built_job = results[1]
|
||||
assert built_job["attr"] == "builtJob"
|
||||
assert built_job["extraValue"]["the-name"] == "job1"
|
||||
assert built_job["extraValue"]["version"] is None
|
||||
|
||||
recurse_drv = results[2]
|
||||
assert recurse_drv["attr"] == "recurse.drvB"
|
||||
assert recurse_drv["extraValue"]["the-name"] == "drvB"
|
||||
assert recurse_drv["extraValue"]["version"] is None
|
||||
|
||||
substituted_job = results[3]
|
||||
assert substituted_job["attr"] == "substitutedJob"
|
||||
assert substituted_job["extraValue"]["the-name"].startswith("hello-")
|
||||
assert substituted_job["extraValue"]["version"] is not None
|
||||
|
||||
|
||||
@pytest.mark.infiniterecursion
|
||||
def test_recursion_error() -> None:
|
||||
with TemporaryDirectory() as tempdir:
|
||||
|
||||
Reference in New Issue
Block a user