@@ -78,7 +78,7 @@ struct InstallableStoreDrv : Installable
7878
7979 std::string what () override { return storePath; }
8080
81- Buildables toBuildable () override
81+ Buildables toBuildable (bool singular ) override
8282 {
8383 return {{storePath, {}}};
8484 }
@@ -92,25 +92,21 @@ struct InstallableStorePath : Installable
9292
9393 std::string what () override { return storePath; }
9494
95- Buildables toBuildable () override
95+ Buildables toBuildable (bool singular ) override
9696 {
9797 return {{storePath, {}}};
9898 }
9999};
100100
101- struct InstallableExpr : Installable
101+ struct InstallableValue : Installable
102102{
103- InstallablesCommand & installables;
104- std::string text;
105-
106- InstallableExpr (InstallablesCommand & installables, const std::string & text)
107- : installables(installables), text(text) { }
103+ SourceExprCommand & cmd;
108104
109- std::string what () override { return text; }
105+ InstallableValue (SourceExprCommand & cmd) : cmd(cmd) { }
110106
111- Buildables toBuildable () override
107+ Buildables toBuildable (bool singular ) override
112108 {
113- auto state = installables .getEvalState ();
109+ auto state = cmd .getEvalState ();
114110
115111 auto v = toValue (*state);
116112
@@ -121,6 +117,9 @@ struct InstallableExpr : Installable
121117 DrvInfos drvs;
122118 getDerivations (*state, *v, " " , autoArgs, drvs, false );
123119
120+ if (singular && drvs.size () != 1 )
121+ throw Error (" installable '%s' evaluates to %d derivations, where only one is expected" , what (), drvs.size ());
122+
124123 Buildables res;
125124
126125 for (auto & drv : drvs)
@@ -129,6 +128,16 @@ struct InstallableExpr : Installable
129128
130129 return res;
131130 }
131+ };
132+
133+ struct InstallableExpr : InstallableValue
134+ {
135+ std::string text;
136+
137+ InstallableExpr (SourceExprCommand & cmd, const std::string & text)
138+ : InstallableValue(cmd), text(text) { }
139+
140+ std::string what () override { return text; }
132141
133142 Value * toValue (EvalState & state) override
134143 {
@@ -138,42 +147,19 @@ struct InstallableExpr : Installable
138147 }
139148};
140149
141- struct InstallableAttrPath : Installable
150+ struct InstallableAttrPath : InstallableValue
142151{
143- InstallablesCommand & installables;
144152 std::string attrPath;
145153
146- InstallableAttrPath (InstallablesCommand & installables , const std::string & attrPath)
147- : installables(installables ), attrPath(attrPath)
154+ InstallableAttrPath (SourceExprCommand & cmd , const std::string & attrPath)
155+ : InstallableValue(cmd ), attrPath(attrPath)
148156 { }
149157
150158 std::string what () override { return attrPath; }
151159
152- Buildables toBuildable () override
153- {
154- auto state = installables.getEvalState ();
155-
156- auto v = toValue (*state);
157-
158- // FIXME
159- std::map<string, string> autoArgs_;
160- Bindings & autoArgs (*evalAutoArgs (*state, autoArgs_));
161-
162- DrvInfos drvs;
163- getDerivations (*state, *v, " " , autoArgs, drvs, false );
164-
165- Buildables res;
166-
167- for (auto & drv : drvs)
168- for (auto & output : drv.queryOutputs ())
169- res.emplace (output.second , Whence{output.first , drv.queryDrvPath ()});
170-
171- return res;
172- }
173-
174160 Value * toValue (EvalState & state) override
175161 {
176- auto source = installables .getSourceExpr (state);
162+ auto source = cmd .getSourceExpr (state);
177163
178164 // FIXME
179165 std::map<string, string> autoArgs_;
@@ -190,20 +176,21 @@ struct InstallableAttrPath : Installable
190176std::string attrRegex = R"( [A-Za-z_][A-Za-z0-9-_+]*)" ;
191177static std::regex attrPathRegex (fmt(R"( %1%(\.%1%)*)" , attrRegex));
192178
193- std::vector<std::shared_ptr<Installable>> InstallablesCommand::parseInstallables (ref<Store> store, Strings ss)
179+ static std::vector<std::shared_ptr<Installable>> parseInstallables (
180+ SourceExprCommand & cmd, ref<Store> store, Strings ss, bool useDefaultInstallables)
194181{
195182 std::vector<std::shared_ptr<Installable>> result;
196183
197- if (ss.empty () && useDefaultInstallables () ) {
198- if (file == " " )
199- file = " ." ;
184+ if (ss.empty () && useDefaultInstallables) {
185+ if (cmd. file == " " )
186+ cmd. file = " ." ;
200187 ss = Strings{" " };
201188 }
202189
203190 for (auto & s : ss) {
204191
205192 if (s.compare (0 , 1 , " (" ) == 0 )
206- result.push_back (std::make_shared<InstallableExpr>(* this , s));
193+ result.push_back (std::make_shared<InstallableExpr>(cmd , s));
207194
208195 else if (s.find (" /" ) != std::string::npos) {
209196
@@ -218,7 +205,7 @@ std::vector<std::shared_ptr<Installable>> InstallablesCommand::parseInstallables
218205 }
219206
220207 else if (s == " " || std::regex_match (s, attrPathRegex))
221- result.push_back (std::make_shared<InstallableAttrPath>(* this , s));
208+ result.push_back (std::make_shared<InstallableAttrPath>(cmd , s));
222209
223210 else
224211 throw UsageError (" don't know what to do with argument '%s'" , s);
@@ -250,7 +237,14 @@ PathSet InstallablesCommand::toStorePaths(ref<Store> store, ToStorePathsMode mod
250237
251238void InstallablesCommand::prepare ()
252239{
253- installables = parseInstallables (getStore (), _installables);
240+ installables = parseInstallables (*this , getStore (), _installables, useDefaultInstallables ());
241+ }
242+
243+ void InstallableCommand::prepare ()
244+ {
245+ auto installables = parseInstallables (*this , getStore (), {_installable}, false );
246+ assert (installables.size () == 1 );
247+ installable = installables.front ();
254248}
255249
256250}
0 commit comments