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 DerivationOptions::fromParsedDerivation (const ParsedDerivation & parsed, bool shouldWarn)
95+ DerivationOptions
96+ DerivationOptions::fromStructuredAttrs (const StringMap & env, const StructuredAttrs * parsed, bool shouldWarn)
1997{
2098 DerivationOptions defaults = {};
2199
22- auto structuredAttrs = parsed.structuredAttrs .get ();
23-
24- if (shouldWarn && structuredAttrs) {
25- if (get (*structuredAttrs, " allowedReferences" )) {
100+ if (shouldWarn && parsed) {
101+ if (get (parsed->structuredAttrs , " allowedReferences" )) {
26102 warn (
27103 " 'structuredAttrs' disables the effect of the top-level attribute 'allowedReferences'; use 'outputChecks' instead" );
28104 }
29- if (get (* structuredAttrs, " allowedRequisites" )) {
105+ if (get (parsed-> structuredAttrs , " allowedRequisites" )) {
30106 warn (
31107 " 'structuredAttrs' disables the effect of the top-level attribute 'allowedRequisites'; use 'outputChecks' instead" );
32108 }
33- if (get (* structuredAttrs, " disallowedRequisites" )) {
109+ if (get (parsed-> structuredAttrs , " disallowedRequisites" )) {
34110 warn (
35111 " 'structuredAttrs' disables the effect of the top-level attribute 'disallowedRequisites'; use 'outputChecks' instead" );
36112 }
37- if (get (* structuredAttrs, " disallowedReferences" )) {
113+ if (get (parsed-> structuredAttrs , " disallowedReferences" )) {
38114 warn (
39115 " 'structuredAttrs' disables the effect of the top-level attribute 'disallowedReferences'; use 'outputChecks' instead" );
40116 }
41- if (get (* structuredAttrs, " maxSize" )) {
117+ if (get (parsed-> structuredAttrs , " maxSize" )) {
42118 warn (
43119 " 'structuredAttrs' disables the effect of the top-level attribute 'maxSize'; use 'outputChecks' instead" );
44120 }
45- if (get (* structuredAttrs, " maxClosureSize" )) {
121+ if (get (parsed-> structuredAttrs , " maxClosureSize" )) {
46122 warn (
47123 " 'structuredAttrs' disables the effect of the top-level attribute 'maxClosureSize'; use 'outputChecks' instead" );
48124 }
49125 }
50126
51127 return {
52128 .outputChecks = [&]() -> OutputChecksVariant {
53- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
129+ if (parsed) {
54130 std::map<std::string, OutputChecks> res;
55- if (auto outputChecks = get (* structuredAttrs, " outputChecks" )) {
131+ if (auto outputChecks = get (parsed-> structuredAttrs , " outputChecks" )) {
56132 for (auto & [outputName, output] : getObject (*outputChecks)) {
57133 OutputChecks checks;
58134
@@ -90,19 +166,19 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
90166 return OutputChecks{
91167 // legacy non-structured-attributes case
92168 .ignoreSelfRefs = true ,
93- .allowedReferences = parsed. getStringSetAttr (" allowedReferences" ),
94- .disallowedReferences = parsed. getStringSetAttr (" disallowedReferences" ).value_or (StringSet{}),
95- .allowedRequisites = parsed. getStringSetAttr (" allowedRequisites" ),
96- .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{}),
97173 };
98174 }
99175 }(),
100176 .unsafeDiscardReferences =
101177 [&] {
102178 std::map<std::string, bool > res;
103179
104- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
105- if (auto udr = get (* structuredAttrs, " unsafeDiscardReferences" )) {
180+ if (parsed) {
181+ if (auto udr = get (parsed-> structuredAttrs , " unsafeDiscardReferences" )) {
106182 for (auto & [outputName, output] : getObject (*udr)) {
107183 if (!output.is_boolean ())
108184 throw Error (" attribute 'unsafeDiscardReferences.\" %s\" ' must be a Boolean" , outputName);
@@ -116,8 +192,8 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
116192 .passAsFile =
117193 [&] {
118194 StringSet res;
119- if (auto * passAsFileString = get (parsed. drv . env , " passAsFile" )) {
120- if (parsed. hasStructuredAttrs () ) {
195+ if (auto * passAsFileString = get (env, " passAsFile" )) {
196+ if (parsed) {
121197 if (shouldWarn) {
122198 warn (
123199 " 'structuredAttrs' disables the effect of the top-level attribute 'passAsFile'; because all JSON is always passed via file" );
@@ -132,18 +208,18 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
132208 [&] {
133209 std::map<std::string, StringSet> ret;
134210
135- if (auto structuredAttrs = parsed. structuredAttrs . get () ) {
136- auto e = optionalValueAt (* structuredAttrs, " exportReferencesGraph" );
211+ if (parsed) {
212+ auto e = optionalValueAt (parsed-> structuredAttrs , " exportReferencesGraph" );
137213 if (!e || !e->is_object ())
138214 return ret;
139215 for (auto & [key, storePathsJson] : getObject (*e)) {
140216 ret.insert_or_assign (key, storePathsJson);
141217 }
142218 } else {
143- auto s = getOr (parsed. drv . env , " exportReferencesGraph" , " " );
219+ auto s = getOr (env, " exportReferencesGraph" , " " );
144220 Strings ss = tokenizeString<Strings>(s);
145221 if (ss.size () % 2 != 0 )
146- throw BuildError (" odd number of tokens in 'exportReferencesGraph': '%1%'" , s);
222+ throw Error (" odd number of tokens in 'exportReferencesGraph': '%1%'" , s);
147223 for (Strings::iterator i = ss.begin (); i != ss.end ();) {
148224 auto fileName = std::move (*i++);
149225 static std::regex regex (" [A-Za-z_][A-Za-z0-9_.-]*" );
@@ -157,15 +233,15 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
157233 return ret;
158234 }(),
159235 .additionalSandboxProfile =
160- parsed. getStringAttr (" __sandboxProfile" ).value_or (defaults.additionalSandboxProfile ),
161- .noChroot = parsed. getBoolAttr (" __noChroot" , defaults.noChroot ),
162- .impureHostDeps = parsed. getStringSetAttr (" __impureHostDeps" ).value_or (defaults.impureHostDeps ),
163- .impureEnvVars = parsed. getStringSetAttr (" impureEnvVars" ).value_or (defaults.impureEnvVars ),
164- .allowLocalNetworking = parsed. getBoolAttr (" __darwinAllowLocalNetworking" , defaults.allowLocalNetworking ),
236+ getStringAttr (env, parsed, " __sandboxProfile" ).value_or (defaults.additionalSandboxProfile ),
237+ .noChroot = getBoolAttr (env, parsed, " __noChroot" , defaults.noChroot ),
238+ .impureHostDeps = getStringSetAttr (env, parsed, " __impureHostDeps" ).value_or (defaults.impureHostDeps ),
239+ .impureEnvVars = getStringSetAttr (env, parsed, " impureEnvVars" ).value_or (defaults.impureEnvVars ),
240+ .allowLocalNetworking = getBoolAttr (env, parsed, " __darwinAllowLocalNetworking" , defaults.allowLocalNetworking ),
165241 .requiredSystemFeatures =
166- parsed. getStringSetAttr (" requiredSystemFeatures" ).value_or (defaults.requiredSystemFeatures ),
167- .preferLocalBuild = parsed. getBoolAttr (" preferLocalBuild" , defaults.preferLocalBuild ),
168- .allowSubstitutes = parsed. getBoolAttr (" allowSubstitutes" , defaults.allowSubstitutes ),
242+ getStringSetAttr (env, parsed, " requiredSystemFeatures" ).value_or (defaults.requiredSystemFeatures ),
243+ .preferLocalBuild = getBoolAttr (env, parsed, " preferLocalBuild" , defaults.preferLocalBuild ),
244+ .allowSubstitutes = getBoolAttr (env, parsed, " allowSubstitutes" , defaults.allowSubstitutes ),
169245 };
170246}
171247
0 commit comments