Compare commits
7
Commits
2.95.2
...
release-2.95
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bc4807e64 | ||
|
|
c5f394c729 | ||
|
|
753944a172 | ||
|
|
23c66f4df0 | ||
|
|
1898a6e05a | ||
|
|
247436669d | ||
|
|
fe0953923f |
@@ -315,5 +315,8 @@ yorickvp:
|
|||||||
yshui:
|
yshui:
|
||||||
github: yshui
|
github: yshui
|
||||||
|
|
||||||
|
ysndr:
|
||||||
|
github: ysndr
|
||||||
|
|
||||||
zimbatm:
|
zimbatm:
|
||||||
github: 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.
|
||||||
@@ -1,4 +1,16 @@
|
|||||||
# Lix 2.95 "Kakigōri" (2026-03-13)
|
# Lix 2.95 "Kakigōri" (2026-03-13)
|
||||||
|
# Lix 2.95.3 (2026-05-08)
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Fix upgrade-nix breaking its own access to the daemon [lix#1189](https://git.lix.systems/lix-project/lix/issues/1189) [lix#1207](https://git.lix.systems/lix-project/lix/issues/1207) [cl/5504](https://gerrit.lix.systems/c/lix/+/5504) [cl/5567](https://gerrit.lix.systems/c/lix/+/5567)
|
||||||
|
|
||||||
|
`nix upgrade-nix`, and the helper script `misc/upgrade-lix.sh` now pass `--store local` to all Nix commands, so the upgrade process can make changes to the daemon without breaking further steps in the upgrade.
|
||||||
|
|
||||||
|
Many thanks to [Qyriad](https://git.lix.systems/Qyriad) for this.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Lix 2.95.2 (2026-05-04)
|
# Lix 2.95.2 (2026-05-04)
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ struct CmdUpgradeNix : MixDryRun, EvalCommand
|
|||||||
// install the new one, in case the new and old versions aren't considered
|
// install the new one, in case the new and old versions aren't considered
|
||||||
// to be "the same package" by nix-env's logic (e.g., if their pnames differ).
|
// to be "the same package" by nix-env's logic (e.g., if their pnames differ).
|
||||||
Strings removeArgs = {
|
Strings removeArgs = {
|
||||||
|
"--store",
|
||||||
|
"local",
|
||||||
"--uninstall",
|
"--uninstall",
|
||||||
oldNixEnv,
|
oldNixEnv,
|
||||||
"--profile",
|
"--profile",
|
||||||
@@ -150,6 +152,8 @@ struct CmdUpgradeNix : MixDryRun, EvalCommand
|
|||||||
aio().blockOn(runProgram(newNixEnv, false, removeArgs));
|
aio().blockOn(runProgram(newNixEnv, false, removeArgs));
|
||||||
|
|
||||||
Strings upgradeArgs = {
|
Strings upgradeArgs = {
|
||||||
|
"--store",
|
||||||
|
"local",
|
||||||
"--profile",
|
"--profile",
|
||||||
this->profileDir,
|
this->profileDir,
|
||||||
"--install",
|
"--install",
|
||||||
|
|||||||
@@ -124,9 +124,12 @@ checkSystemdService
|
|||||||
|
|
||||||
set -x
|
set -x
|
||||||
exec "$NIX" run \
|
exec "$NIX" run \
|
||||||
|
--store local \
|
||||||
--extra-experimental-features "nix-command flakes" \
|
--extra-experimental-features "nix-command flakes" \
|
||||||
"${SUBSTITUTER_ARGS[@]}" \
|
"${SUBSTITUTER_ARGS[@]}" \
|
||||||
"${LIX_BASE}?ref=${LIX_REF}" \
|
"${LIX_BASE}?ref=${LIX_REF}" \
|
||||||
|
-- \
|
||||||
|
--store local \
|
||||||
--extra-experimental-features "nix-command flakes" \
|
--extra-experimental-features "nix-command flakes" \
|
||||||
upgrade-nix \
|
upgrade-nix \
|
||||||
"${SUBSTITUTER_ARGS[@]}"
|
"${SUBSTITUTER_ARGS[@]}"
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ executable.
|
|||||||
$ nix-eval-jobs --help
|
$ nix-eval-jobs --help
|
||||||
USAGE: nix-eval-jobs [options] expr
|
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.
|
--arg Pass the value *expr* as the argument *name* to Nix functions.
|
||||||
--argstr Pass the string *string* 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.
|
--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"
|
#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({
|
addFlag({
|
||||||
.longName = "help",
|
.longName = "help",
|
||||||
.description = "show usage information",
|
.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)) {
|
if (flag->hidden || hiddenCategories.count(flag->category)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::cout << nix::fmt(" --%-20s %s\n", name, flag->description);
|
std::cout << nix::fmt(" --%-20s %s\n", name,
|
||||||
|
flag->description);
|
||||||
}
|
}
|
||||||
::exit(0);
|
::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",
|
.description = "treat the argument as a Nix expression",
|
||||||
.handler = {&fromArgs, true}});
|
.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
|
// usually in MixFlakeOptions
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "override-input",
|
.longName = "override-input",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ struct MyArgs : virtual public nix::MixEvalArgs,
|
|||||||
|
|
||||||
bool worker = false;
|
bool worker = false;
|
||||||
std::string releaseExpr;
|
std::string releaseExpr;
|
||||||
|
std::string applyExpr;
|
||||||
nix::Path gcRootsDir;
|
nix::Path gcRootsDir;
|
||||||
bool flake = false;
|
bool flake = false;
|
||||||
bool fromArgs = false;
|
bool fromArgs = false;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <lix/libexpr/symbol-table.hh>
|
#include <lix/libexpr/symbol-table.hh>
|
||||||
#include <lix/libutil/types.hh>
|
#include <lix/libutil/types.hh>
|
||||||
#include <lix/libexpr/value.hh>
|
#include <lix/libexpr/value.hh>
|
||||||
|
#include <lix/libexpr/value-to-json.hh>
|
||||||
#include <lix/libutil/terminal.hh>
|
#include <lix/libutil/terminal.hh>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -201,6 +202,21 @@ try {
|
|||||||
maybeConstituents =
|
maybeConstituents =
|
||||||
readConstituents(&v, state, evaluator);
|
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,
|
auto drv = Drv(attrPathS, *state, *drvInfo, args,
|
||||||
maybeConstituents);
|
maybeConstituents);
|
||||||
reply.update(drv);
|
reply.update(drv);
|
||||||
|
|||||||
@@ -124,6 +124,45 @@ def test_eval_error() -> None:
|
|||||||
assert "this is an evaluation error" in attr["error"]
|
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
|
@pytest.mark.infiniterecursion
|
||||||
def test_recursion_error() -> None:
|
def test_recursion_error() -> None:
|
||||||
with TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "2.95.2",
|
"version": "2.95.3",
|
||||||
"official_release": true,
|
"official_release": false,
|
||||||
"release_name": "Kakigōri"
|
"release_name": "Kakigōri"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user