11#include " nix/store/derivation-options.hh"
22#include " nix/util/json-utils.hh"
33#include " nix/store/parsed-derivations.hh"
4+ #include " nix/store/derivations.hh"
5+ #include " nix/store/store-api.hh"
46#include " nix/util/types.hh"
57#include " nix/util/util.hh"
68
1113
1214namespace nix {
1315
16+ static std::optional<std::string>
17+ getStringAttr (const StringMap & env, const StructuredAttrs * parsed, const std::string & name)
18+ {
19+ if (parsed) {
20+ auto i = parsed->structuredAttrs .find (name);
21+ if (i == parsed->structuredAttrs .end ())
22+ return {};
23+ else {
24+ if (!i->is_string ())
25+ throw Error (" attribute '%s' of must be a string" , name);
26+ return i->get <std::string>();
27+ }
28+ } else {
29+ auto i = env.find (name);
30+ if (i == env.end ())
31+ return {};
32+ else
33+ return i->second ;
34+ }
35+ }
36+
37+ static bool getBoolAttr (const StringMap & env, const StructuredAttrs * parsed, const std::string & name, bool def)
38+ {
39+ if (parsed) {
40+ auto i = parsed->structuredAttrs .find (name);
41+ if (i == parsed->structuredAttrs .end ())
42+ return def;
43+ else {
44+ if (!i->is_boolean ())
45+ throw Error (" attribute '%s' must be a Boolean" , name);
46+ return i->get <bool >();
47+ }
48+ } else {
49+ auto i = env.find (name);
50+ if (i == env.end ())
51+ return def;
52+ else
53+ return i->second == " 1" ;
54+ }
55+ }
56+
57+ static std::optional<Strings>
58+ getStringsAttr (const StringMap & env, const StructuredAttrs * parsed, const std::string & name)
59+ {
60+ if (parsed) {
61+ auto i = parsed->structuredAttrs .find (name);
62+ if (i == parsed->structuredAttrs .end ())
63+ return {};
64+ else {
65+ if (!i->is_array ())
66+ throw Error (" attribute '%s' must be a list of strings" , name);
67+ Strings res;
68+ for (auto j = i->begin (); j != i->end (); ++j) {
69+ if (!j->is_string ())
70+ throw Error (" attribute '%s' must be a list of strings" , name);
71+ res.push_back (j->get <std::string>());
72+ }
73+ return res;
74+ }
75+ } else {
76+ auto i = env.find (name);
77+ if (i == env.end ())
78+ return {};
79+ else
80+ return tokenizeString<Strings>(i->second );
81+ }
82+ }
83+
84+ static std::optional<StringSet>
85+ getStringSetAttr (const StringMap & env, const StructuredAttrs * parsed, const std::string & name)
86+ {
87+ auto ss = getStringsAttr (env, parsed, name);
88+ return ss ? (std::optional{StringSet{ss->begin (), ss->end ()}}) : (std::optional<StringSet>{});
89+ }
90+
1491using OutputChecks = DerivationOptions::OutputChecks;
1592
1693using OutputChecksVariant = std::variant<OutputChecks, std::map<std::string, OutputChecks>>;
1794
18- DerivationOptions
19- DerivationOptions::fromParsedDerivation ( const StoreDirConfig & store, const ParsedDerivation & parsed, bool shouldWarn)
95+ DerivationOptions DerivationOptions::fromStructuredAttrs (
96+ const StoreDirConfig & store, const StringMap & env, const StructuredAttrs * parsed, bool shouldWarn)
2097{
2198 DerivationOptions defaults = {};
2299
23- auto structuredAttrs = parsed.structuredAttrs .get ();
24-
25- if (shouldWarn && structuredAttrs) {
26- if (get (*structuredAttrs, " allowedReferences" )) {
100+ if (shouldWarn && parsed) {
101+ if (get (parsed->structuredAttrs , " allowedReferences" )) {
27102 warn (
28103 " 'structuredAttrs' disables the effect of the top-level attribute 'allowedReferences'; use 'outputChecks' instead" );
29104 }
30- if (get (* structuredAttrs, " allowedRequisites" )) {
105+ if (get (parsed-> structuredAttrs , " allowedRequisites" )) {
31106 warn (
32107 " 'structuredAttrs' disables the effect of the top-level attribute 'allowedRequisites'; use 'outputChecks' instead" );
33108 }
34- if (get (* structuredAttrs, " disallowedRequisites" )) {
109+ if (get (parsed-> structuredAttrs , " disallowedRequisites" )) {
35110 warn (
36111 " 'structuredAttrs' disables the effect of the top-level attribute 'disallowedRequisites'; use 'outputChecks' instead" );
37112 }
38- if (get (* structuredAttrs, " disallowedReferences" )) {
113+ if (get (parsed-> structuredAttrs , " disallowedReferences" )) {
39114 warn (
40115 " 'structuredAttrs' disables the effect of the top-level attribute 'disallowedReferences'; use 'outputChecks' instead" );
41116 }
42- if (get (* structuredAttrs, " maxSize" )) {
117+ if (get (parsed-> structuredAttrs , " maxSize" )) {
43118 warn (
44119 " 'structuredAttrs' disables the effect of the top-level attribute 'maxSize'; use 'outputChecks' instead" );
45120 }
46- if (get (* structuredAttrs, " maxClosureSize" )) {
121+ if (get (parsed-> structuredAttrs , " maxClosureSize" )) {
47122 warn (
48123 " 'structuredAttrs' disables the effect of the top-level attribute 'maxClosureSize'; use 'outputChecks' instead" );
49124 }
50125 }
51126
52127 return {
53128 .outputChecks = [&]() -> OutputChecksVariant {
54- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
129+ if (parsed) {
55130 std::map<std::string, OutputChecks> res;
56- if (auto outputChecks = get (* structuredAttrs, " outputChecks" )) {
131+ if (auto outputChecks = get (parsed-> structuredAttrs , " outputChecks" )) {
57132 for (auto & [outputName, output] : getObject (*outputChecks)) {
58133 OutputChecks checks;
59134
@@ -91,19 +166,19 @@ DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const Pars
91166 return OutputChecks{
92167 // legacy non-structured-attributes case
93168 .ignoreSelfRefs = true ,
94- .allowedReferences = parsed. getStringSetAttr (" allowedReferences" ),
95- .disallowedReferences = parsed. getStringSetAttr (" disallowedReferences" ).value_or (StringSet{}),
96- .allowedRequisites = parsed. getStringSetAttr (" allowedRequisites" ),
97- .disallowedRequisites = parsed. getStringSetAttr (" disallowedRequisites" ).value_or (StringSet{}),
169+ .allowedReferences = getStringSetAttr (env, parsed, " allowedReferences" ),
170+ .disallowedReferences = getStringSetAttr (env, parsed, " disallowedReferences" ).value_or (StringSet{}),
171+ .allowedRequisites = getStringSetAttr (env, parsed, " allowedRequisites" ),
172+ .disallowedRequisites = getStringSetAttr (env, parsed, " disallowedRequisites" ).value_or (StringSet{}),
98173 };
99174 }
100175 }(),
101176 .unsafeDiscardReferences =
102177 [&] {
103178 std::map<std::string, bool > res;
104179
105- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
106- if (auto udr = get (* structuredAttrs, " unsafeDiscardReferences" )) {
180+ if (parsed) {
181+ if (auto udr = get (parsed-> structuredAttrs , " unsafeDiscardReferences" )) {
107182 for (auto & [outputName, output] : getObject (*udr)) {
108183 if (!output.is_boolean ())
109184 throw Error (" attribute 'unsafeDiscardReferences.\" %s\" ' must be a Boolean" , outputName);
@@ -117,8 +192,8 @@ DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const Pars
117192 .passAsFile =
118193 [&] {
119194 StringSet res;
120- if (auto * passAsFileString = get (parsed. env , " passAsFile" )) {
121- if (parsed. hasStructuredAttrs () ) {
195+ if (auto * passAsFileString = get (env, " passAsFile" )) {
196+ if (parsed) {
122197 if (shouldWarn) {
123198 warn (
124199 " 'structuredAttrs' disables the effect of the top-level attribute 'passAsFile'; because all JSON is always passed via file" );
@@ -133,8 +208,8 @@ DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const Pars
133208 [&] {
134209 std::map<std::string, StorePathSet> ret;
135210
136- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
137- auto e = optionalValueAt (* structuredAttrs, " exportReferencesGraph" );
211+ if (parsed) {
212+ auto e = optionalValueAt (parsed-> structuredAttrs , " exportReferencesGraph" );
138213 if (!e || !e->is_object ())
139214 return ret;
140215 for (auto & [key, storePathsJson] : getObject (*e)) {
@@ -144,10 +219,10 @@ DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const Pars
144219 ret.insert_or_assign (key, std::move (storePaths));
145220 }
146221 } else {
147- auto s = getOr (parsed. env , " exportReferencesGraph" , " " );
222+ auto s = getOr (env, " exportReferencesGraph" , " " );
148223 Strings ss = tokenizeString<Strings>(s);
149224 if (ss.size () % 2 != 0 )
150- throw BuildError (" odd number of tokens in 'exportReferencesGraph': '%1%'" , s);
225+ throw Error (" odd number of tokens in 'exportReferencesGraph': '%1%'" , s);
151226 for (Strings::iterator i = ss.begin (); i != ss.end ();) {
152227 auto fileName = std::move (*i++);
153228 static std::regex regex (" [A-Za-z_][A-Za-z0-9_.-]*" );
@@ -163,15 +238,15 @@ DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const Pars
163238 return ret;
164239 }(),
165240 .additionalSandboxProfile =
166- parsed. getStringAttr (" __sandboxProfile" ).value_or (defaults.additionalSandboxProfile ),
167- .noChroot = parsed. getBoolAttr (" __noChroot" , defaults.noChroot ),
168- .impureHostDeps = parsed. getStringSetAttr (" __impureHostDeps" ).value_or (defaults.impureHostDeps ),
169- .impureEnvVars = parsed. getStringSetAttr (" impureEnvVars" ).value_or (defaults.impureEnvVars ),
170- .allowLocalNetworking = parsed. getBoolAttr (" __darwinAllowLocalNetworking" , defaults.allowLocalNetworking ),
241+ getStringAttr (env, parsed, " __sandboxProfile" ).value_or (defaults.additionalSandboxProfile ),
242+ .noChroot = getBoolAttr (env, parsed, " __noChroot" , defaults.noChroot ),
243+ .impureHostDeps = getStringSetAttr (env, parsed, " __impureHostDeps" ).value_or (defaults.impureHostDeps ),
244+ .impureEnvVars = getStringSetAttr (env, parsed, " impureEnvVars" ).value_or (defaults.impureEnvVars ),
245+ .allowLocalNetworking = getBoolAttr (env, parsed, " __darwinAllowLocalNetworking" , defaults.allowLocalNetworking ),
171246 .requiredSystemFeatures =
172- parsed. getStringSetAttr (" requiredSystemFeatures" ).value_or (defaults.requiredSystemFeatures ),
173- .preferLocalBuild = parsed. getBoolAttr (" preferLocalBuild" , defaults.preferLocalBuild ),
174- .allowSubstitutes = parsed. getBoolAttr (" allowSubstitutes" , defaults.allowSubstitutes ),
247+ getStringSetAttr (env, parsed, " requiredSystemFeatures" ).value_or (defaults.requiredSystemFeatures ),
248+ .preferLocalBuild = getBoolAttr (env, parsed, " preferLocalBuild" , defaults.preferLocalBuild ),
249+ .allowSubstitutes = getBoolAttr (env, parsed, " allowSubstitutes" , defaults.allowSubstitutes ),
175250 };
176251}
177252
0 commit comments