@@ -71,11 +71,17 @@ static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
71
71
return {std::move (tree), resolvedRef, lockedRef};
72
72
}
73
73
74
- static void expectType (EvalState & state, ValueType type,
75
- Value & value, const Pos & pos)
74
+ static void forceTrivialValue (EvalState & state, Value & value, const Pos & pos)
76
75
{
77
76
if (value.type == tThunk && value.isTrivial ())
78
77
state.forceValue (value, pos);
78
+ }
79
+
80
+
81
+ static void expectType (EvalState & state, ValueType type,
82
+ Value & value, const Pos & pos)
83
+ {
84
+ forceTrivialValue (state, value, pos);
79
85
if (value.type != type)
80
86
throw Error (" expected %s but got %s at %s" ,
81
87
showType (type), showType (value.type ), pos);
@@ -114,7 +120,6 @@ static FlakeInput parseFlakeInput(EvalState & state,
114
120
expectType (state, tString, *attr.value , *attr.pos );
115
121
input.follows = parseInputPath (attr.value ->string .s );
116
122
} else {
117
- state.forceValue (*attr.value );
118
123
if (attr.value ->type == tString)
119
124
attrs.emplace (attr.name , attr.value ->string .s );
120
125
else
@@ -223,10 +228,41 @@ static Flake getFlake(
223
228
} else
224
229
throw Error (" flake '%s' lacks attribute 'outputs'" , lockedRef);
225
230
231
+ auto sNixConfig = state.symbols .create (" nixConfig" );
232
+
233
+ if (auto nixConfig = vInfo.attrs ->get (sNixConfig )) {
234
+ expectType (state, tAttrs, *nixConfig->value , *nixConfig->pos );
235
+
236
+ for (auto & option : *nixConfig->value ->attrs ) {
237
+ forceTrivialValue (state, *option.value , *option.pos );
238
+ if (option.value ->type == tString)
239
+ flake.config .options .insert ({option.name , state.forceStringNoCtx (*option.value , *option.pos )});
240
+ else if (option.value ->type == tInt)
241
+ flake.config .options .insert ({option.name , state.forceInt (*option.value , *option.pos )});
242
+ else if (option.value ->type == tBool)
243
+ flake.config .options .insert ({option.name , state.forceBool (*option.value , *option.pos )});
244
+ else if (option.value ->isList ()) {
245
+ std::vector<std::string> ss;
246
+ for (unsigned int n = 0 ; n < option.value ->listSize (); ++n) {
247
+ auto elem = option.value ->listElems ()[n];
248
+ if (elem->type != tString)
249
+ throw TypeError (" list element in flake configuration option '%s' is %s while a string is expected" ,
250
+ option.name , showType (*option.value ));
251
+ ss.push_back (state.forceStringNoCtx (*elem, *option.pos ));
252
+ }
253
+ flake.config .options .insert ({option.name , ss});
254
+ }
255
+ else
256
+ throw TypeError (" flake configuration option '%s' is %s" ,
257
+ option.name , showType (*option.value ));
258
+ }
259
+ }
260
+
226
261
for (auto & attr : *vInfo.attrs ) {
227
262
if (attr.name != state.sDescription &&
228
263
attr.name != sInputs &&
229
- attr.name != sOutputs )
264
+ attr.name != sOutputs &&
265
+ attr.name != sNixConfig )
230
266
throw Error (" flake '%s' has an unsupported attribute '%s', at %s" ,
231
267
lockedRef, attr.name , *attr.pos );
232
268
}
@@ -599,4 +635,30 @@ Fingerprint LockedFlake::getFingerprint() const
599
635
600
636
Flake::~Flake () { }
601
637
638
+ void ConfigFile::apply ()
639
+ {
640
+ for (auto & [name, value] : options) {
641
+ // FIXME: support 'trusted-public-keys' (and other options), but make it TOFU.
642
+ if (name != " bash-prompt-suffix" &&
643
+ name != " bash-prompt" &&
644
+ name != " substituters" &&
645
+ name != " extra-substituters" )
646
+ {
647
+ warn (" ignoring untrusted flake configuration option '%s'" , name);
648
+ continue ;
649
+ }
650
+ // FIXME: Move into libutil/config.cc.
651
+ if (auto s = std::get_if<std::string>(&value))
652
+ globalConfig.set (name, *s);
653
+ else if (auto n = std::get_if<int64_t >(&value))
654
+ globalConfig.set (name, fmt (" %d" , n));
655
+ else if (auto b = std::get_if<Explicit<bool >>(&value))
656
+ globalConfig.set (name, b->t ? " true" : " false" );
657
+ else if (auto ss = std::get_if<std::vector<std::string>>(&value))
658
+ globalConfig.set (name, concatStringsSep (" " , *ss)); // FIXME: evil
659
+ else
660
+ assert (false );
661
+ }
662
+ }
663
+
602
664
}
0 commit comments