Skip to content

Commit 26bbafc

Browse files
Record subset of meta in provenance
1 parent c9f71f3 commit 26bbafc

File tree

8 files changed

+121
-19
lines changed

8 files changed

+121
-19
lines changed

src/libexpr/include/nix/expr/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ headers = [ config_pub_h ] + files(
3030
'print-ambiguous.hh',
3131
'print-options.hh',
3232
'print.hh',
33+
'provenance.hh',
3334
'repl-exit-status.hh',
3435
'search-path.hh',
3536
'static-string-data.hh',
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "nix/util/provenance.hh"
4+
5+
namespace nix {
6+
7+
/**
8+
* Provenance indicating that this store path was instantiated by the `derivation` builtin function. Its main purpose is
9+
* to record `meta` fields.
10+
*/
11+
struct MetaProvenance : Provenance
12+
{
13+
std::shared_ptr<const Provenance> next;
14+
ref<nlohmann::json> meta;
15+
16+
MetaProvenance(std::shared_ptr<const Provenance> next, ref<nlohmann::json> meta)
17+
: next(std::move(next))
18+
, meta(std::move(meta)) {};
19+
20+
nlohmann::json to_json() const override;
21+
};
22+
23+
} // namespace nix

src/libexpr/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ sources = files(
181181
'primops.cc',
182182
'print-ambiguous.cc',
183183
'print.cc',
184+
'provenance.cc',
184185
'search-path.cc',
185186
'symbol-table.cc',
186187
'value-to-json.cc',

src/libexpr/primops.cc

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "nix/fetchers/fetch-to-store.hh"
1919
#include "nix/util/sort.hh"
2020
#include "nix/util/mounted-source-accessor.hh"
21+
#include "nix/expr/provenance.hh"
2122

2223
#include <boost/container/small_vector.hpp>
2324
#include <boost/unordered/concurrent_flat_map.hpp>
@@ -1504,6 +1505,8 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
15041505
StringSet outputs;
15051506
outputs.insert("out");
15061507

1508+
auto provenance = state.evalContext.provenance;
1509+
15071510
for (auto & i : attrs->lexicographicOrder(state.symbols)) {
15081511
if (i->name == state.s.ignoreNulls)
15091512
continue;
@@ -1571,6 +1574,24 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
15711574
experimentalFeatureSettings.require(Xp::ImpureDerivations);
15721575
}
15731576
break;
1577+
case EvalState::s.meta.getId():
1578+
experimentalFeatureSettings.require(Xp::Provenance);
1579+
1580+
{
1581+
auto meta = printValueAsJSON(state, true, *i->value, pos, context);
1582+
1583+
for (auto it = meta.begin(); it != meta.end();) {
1584+
if (it.key() == "identifiers" || it.key() == "license" || it.key() == "licenses") {
1585+
it++;
1586+
continue;
1587+
}
1588+
1589+
it = meta.erase(it);
1590+
}
1591+
1592+
provenance = std::make_shared<const MetaProvenance>(provenance, make_ref<nlohmann::json>(meta));
1593+
}
1594+
break;
15741595
/* The `args' attribute is special: it supplies the
15751596
command-line arguments to the builder. */
15761597
case EvalState::s.args.getId():
@@ -1847,8 +1868,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
18471868
}
18481869

18491870
/* Write the resulting term into the Nix store directory. */
1850-
auto drvPath =
1851-
writeDerivation(*state.store, *state.asyncPathWriter, drv, state.repair, false, state.evalContext.provenance);
1871+
auto drvPath = writeDerivation(*state.store, *state.asyncPathWriter, drv, state.repair, false, provenance);
18521872
auto drvPathS = state.store->printStorePath(drvPath);
18531873

18541874
printMsg(lvlChatty, "instantiated '%1%' -> '%2%'", drvName, drvPathS);
@@ -5420,7 +5440,14 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
54205440
language feature gets added. It's not necessary to increase it
54215441
when primops get added, because you can just use `builtins ?
54225442
primOp' to check. */
5423-
v.mkInt(6);
5443+
if (experimentalFeatureSettings.isEnabled(Xp::Provenance)) {
5444+
/* Provenance allows for meta to be inside of derivations.
5445+
We increment the version to 7 so Nixpkgs will know when
5446+
provenance is available. */
5447+
v.mkInt(7);
5448+
} else {
5449+
v.mkInt(6);
5450+
}
54245451
addConstant(
54255452
"__langVersion",
54265453
v,

src/libexpr/provenance.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "nix/expr/provenance.hh"
2+
3+
#include <nlohmann/json.hpp>
4+
5+
namespace nix {
6+
7+
nlohmann::json MetaProvenance::to_json() const
8+
{
9+
return nlohmann::json{
10+
{"type", "meta"},
11+
{"meta", *meta},
12+
{"next", next ? next->to_json() : nlohmann::json(nullptr)},
13+
};
14+
}
15+
16+
} // namespace nix

tests/functional/config.nix.in

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ let
55
outputHashMode = "recursive";
66
outputHashAlgo = "sha256";
77
} else {};
8+
9+
optional = cond: elem: if cond then [ elem ] else [];
10+
optionalAttrs = cond: attrs: if cond then attrs else {};
811
in
912

1013
rec {
@@ -25,6 +28,6 @@ rec {
2528
eval "$buildCommand"
2629
'')];
2730
PATH = path;
28-
} // caArgs // removeAttrs args ["builder" "meta"])
29-
// { meta = args.meta or {}; };
31+
} // caArgs // removeAttrs args (["builder"] ++ optional (builtins.langVersion < 7) "meta"))
32+
// optionalAttrs (builtins.langVersion < 7) { meta = args.meta or {}; };
3033
}

tests/functional/flakes/provenance.sh

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,44 @@ lastModified=$(nix flake metadata --json "$flake1Dir" | jq -r .locked.lastModifi
1515
treePath=$(nix flake prefetch --json "$flake1Dir" | jq -r .storePath)
1616
builder=$(nix eval --raw "$flake1Dir#packages.$system.default._builder")
1717

18-
# Building a derivation should have tree+subpath+flake+build provenance.
18+
# Building a derivation should have tree+subpath+flake+meta+build provenance.
1919
[[ $(nix path-info --json --json-format 1 "$outPath" | jq ".\"$outPath\".provenance") = $(cat <<EOF
2020
{
2121
"drv": "$(basename "$drvPath")",
2222
"next": {
23-
"flakeOutput": "packages.$system.default",
23+
"meta": {
24+
"license": [
25+
{
26+
"deprecated": true,
27+
"free": true,
28+
"fullName": "GNU Lesser General Public License v2.1",
29+
"redistributable": true,
30+
"shortName": "lgpl21",
31+
"spdxId": "LGPL-2.1",
32+
"url": "https://spdx.org/licenses/LGPL-2.1.html"
33+
}
34+
]
35+
},
2436
"next": {
37+
"flakeOutput": "packages.$system.default",
2538
"next": {
26-
"attrs": {
27-
"lastModified": $lastModified,
28-
"ref": "refs/heads/master",
29-
"rev": "$rev",
30-
"revCount": 1,
31-
"type": "git",
32-
"url": "file://$flake1Dir"
39+
"next": {
40+
"attrs": {
41+
"lastModified": $lastModified,
42+
"ref": "refs/heads/master",
43+
"rev": "$rev",
44+
"revCount": 1,
45+
"type": "git",
46+
"url": "file://$flake1Dir"
47+
},
48+
"type": "tree"
3349
},
34-
"type": "tree"
50+
"subpath": "/flake.nix",
51+
"type": "subpath"
3552
},
36-
"subpath": "/flake.nix",
37-
"type": "subpath"
53+
"type": "flake"
3854
},
39-
"type": "flake"
55+
"type": "meta"
4056
},
4157
"output": "out",
4258
"type": "build"

tests/functional/simple.nix

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,20 @@ mkDerivation {
66
_builder = ./simple.builder.sh;
77
PATH = "";
88
goodPath = path;
9-
meta.position = "${__curPos.file}:${toString __curPos.line}";
9+
meta = {
10+
position = "${__curPos.file}:${toString __curPos.line}";
11+
license = [
12+
# Since this file is from Nix, use Nix's license.
13+
# Keep in sync with `lib.licenses.lgpl21` from Nixpkgs.
14+
{
15+
deprecated = true;
16+
free = true;
17+
fullName = "GNU Lesser General Public License v2.1";
18+
redistributable = true;
19+
shortName = "lgpl21";
20+
spdxId = "LGPL-2.1";
21+
url = "https://spdx.org/licenses/LGPL-2.1.html";
22+
}
23+
];
24+
};
1025
}

0 commit comments

Comments
 (0)