nix flake check: Check apps
This commit is contained in:
parent
3b2ebd029c
commit
9d1207c02c
4 changed files with 47 additions and 21 deletions
|
@ -51,21 +51,20 @@ void EvalState::realiseContext(const PathSet & context)
|
|||
PathSet drvs;
|
||||
|
||||
for (auto & i : context) {
|
||||
std::pair<string, string> decoded = decodeContext(i);
|
||||
Path ctx = decoded.first;
|
||||
auto [ctx, outputName] = decodeContext(i);
|
||||
assert(store->isStorePath(ctx));
|
||||
if (!store->isValidPath(ctx))
|
||||
throw InvalidPathError(ctx);
|
||||
if (!decoded.second.empty() && nix::isDerivation(ctx)) {
|
||||
drvs.insert(decoded.first + "!" + decoded.second);
|
||||
if (!outputName.empty() && nix::isDerivation(ctx)) {
|
||||
drvs.insert(ctx + "!" + outputName);
|
||||
|
||||
/* Add the output of this derivation to the allowed
|
||||
paths. */
|
||||
if (allowedPaths) {
|
||||
auto drv = store->derivationFromPath(decoded.first);
|
||||
DerivationOutputs::iterator i = drv.outputs.find(decoded.second);
|
||||
auto drv = store->derivationFromPath(ctx);
|
||||
DerivationOutputs::iterator i = drv.outputs.find(outputName);
|
||||
if (i == drv.outputs.end())
|
||||
throw Error("derivation '%s' does not have an output named '%s'", decoded.first, decoded.second);
|
||||
throw Error("derivation '%s' does not have an output named '%s'", ctx, outputName);
|
||||
allowedPaths->insert(i->second.path);
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +79,7 @@ void EvalState::realiseContext(const PathSet & context)
|
|||
PathSet willBuild, willSubstitute, unknown;
|
||||
unsigned long long downloadSize, narSize;
|
||||
store->queryMissing(drvs, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
|
||||
store->buildPaths(drvs);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ struct App
|
|||
PathSet context;
|
||||
Path program;
|
||||
// FIXME: add args, sandbox settings, metadata, ...
|
||||
|
||||
App(EvalState & state, Value & vApp);
|
||||
};
|
||||
|
||||
struct Installable
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "flake/flake.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "derivations.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <queue>
|
||||
|
@ -301,13 +302,27 @@ struct CmdFlakeCheck : FlakeCommand, MixJSON
|
|||
// FIXME: check meta attributes
|
||||
return drvInfo->queryDrvPath();
|
||||
} catch (Error & e) {
|
||||
e.addPrefix(fmt("while checking flake output attribute '" ANSI_BOLD "%s" ANSI_NORMAL "':\n", attrPath));
|
||||
e.addPrefix(fmt("while checking the derivation '" ANSI_BOLD "%s" ANSI_NORMAL "':\n", attrPath));
|
||||
throw;
|
||||
}
|
||||
};
|
||||
|
||||
PathSet drvPaths;
|
||||
|
||||
auto checkApp = [&](const std::string & attrPath, Value & v) {
|
||||
try {
|
||||
auto app = App(*state, v);
|
||||
for (auto & i : app.context) {
|
||||
auto [drvPath, outputName] = decodeContext(i);
|
||||
if (!outputName.empty() && nix::isDerivation(drvPath))
|
||||
drvPaths.insert(drvPath + "!" + outputName);
|
||||
}
|
||||
} catch (Error & e) {
|
||||
e.addPrefix(fmt("while checking the app definition '" ANSI_BOLD "%s" ANSI_NORMAL "':\n", attrPath));
|
||||
throw;
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
Activity act(*logger, lvlInfo, actUnknown, "evaluating flake");
|
||||
|
||||
|
@ -337,9 +352,19 @@ struct CmdFlakeCheck : FlakeCommand, MixJSON
|
|||
name + "." + (std::string) aCheck.name, *aCheck.value);
|
||||
}
|
||||
|
||||
else if (name == "apps") {
|
||||
state->forceAttrs(vProvide);
|
||||
for (auto & aCheck : *vProvide.attrs)
|
||||
checkApp(
|
||||
name + "." + (std::string) aCheck.name, *aCheck.value);
|
||||
}
|
||||
|
||||
else if (name == "defaultPackage" || name == "devShell")
|
||||
checkDerivation(name, vProvide);
|
||||
|
||||
else if (name == "defaultApp")
|
||||
checkApp(name, vProvide);
|
||||
|
||||
} catch (Error & e) {
|
||||
e.addPrefix(fmt("while checking flake output '" ANSI_BOLD "%s" ANSI_NORMAL "':\n", name));
|
||||
throw;
|
||||
|
@ -347,7 +372,7 @@ struct CmdFlakeCheck : FlakeCommand, MixJSON
|
|||
});
|
||||
}
|
||||
|
||||
if (build) {
|
||||
if (build && !drvPaths.empty()) {
|
||||
Activity act(*logger, lvlInfo, actUnknown, "running flake checks");
|
||||
store->buildPaths(drvPaths);
|
||||
}
|
||||
|
|
|
@ -69,26 +69,25 @@ Buildable Installable::toBuildable()
|
|||
return std::move(buildables[0]);
|
||||
}
|
||||
|
||||
App Installable::toApp(EvalState & state)
|
||||
App::App(EvalState & state, Value & vApp)
|
||||
{
|
||||
auto v = toValue(state);
|
||||
state.forceAttrs(vApp);
|
||||
|
||||
state.forceAttrs(*v);
|
||||
|
||||
auto aType = v->attrs->need(state.sType);
|
||||
auto aType = vApp.attrs->need(state.sType);
|
||||
if (state.forceStringNoCtx(*aType.value, *aType.pos) != "app")
|
||||
throw Error("value does not have type 'app', at %s", *aType.pos);
|
||||
|
||||
App app;
|
||||
|
||||
auto aProgram = v->attrs->need(state.symbols.create("program"));
|
||||
app.program = state.forceString(*aProgram.value, app.context, *aProgram.pos);
|
||||
auto aProgram = vApp.attrs->need(state.symbols.create("program"));
|
||||
program = state.forceString(*aProgram.value, context, *aProgram.pos);
|
||||
|
||||
// FIXME: check that 'program' is in the closure of 'context'.
|
||||
if (!state.store->isInStore(app.program))
|
||||
throw Error("app program '%s' is not in the Nix store", app.program);
|
||||
if (!state.store->isInStore(program))
|
||||
throw Error("app program '%s' is not in the Nix store", program);
|
||||
}
|
||||
|
||||
return app;
|
||||
App Installable::toApp(EvalState & state)
|
||||
{
|
||||
return App(state, *toValue(state));
|
||||
}
|
||||
|
||||
struct InstallableStorePath : Installable
|
||||
|
|
Loading…
Reference in a new issue