aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-06-29 19:08:50 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-06-29 19:08:50 +0200
commit26cf0c674f543ec86a5ccb7e05a4773559bb8f8a (patch)
tree9544ce8a48f6b7fc72fa8bbf86879a7e7887a864
parent50f13b06fb1b2f50a97323c000d1094d090f08ea (diff)
nix run: Use packages/legacyPackages as fallback if there is no app definition
'nix run' will try to run $out/bin/<name>, where <name> is the derivation name (excluding the version). This often works well: $ nix run nixpkgs#hello Hello, world! $ nix run nix -- --version nix (Nix) 2.4pre20200626_adf2fbb $ nix run patchelf -- --version patchelf 0.11.20200623.e61654b $ nix run nixpkgs#firefox -- --version Mozilla Firefox 77.0.1 $ nix run nixpkgs#gimp -- --version GNU Image Manipulation Program version 2.10.14 though not always: $ nix run nixpkgs#git error: unable to execute '/nix/store/kp7wp760l4gryq9s36x481b2x4rfklcy-git-2.25.4/bin/git-minimal': No such file or directory
-rw-r--r--src/nix/app.cc46
-rw-r--r--src/nix/flake.cc7
-rw-r--r--src/nix/installables.hh4
-rw-r--r--src/nix/run.cc12
4 files changed, 47 insertions, 22 deletions
diff --git a/src/nix/app.cc b/src/nix/app.cc
index 749dea02b..3935297cf 100644
--- a/src/nix/app.cc
+++ b/src/nix/app.cc
@@ -1,28 +1,46 @@
#include "installables.hh"
#include "store-api.hh"
#include "eval-inline.hh"
+#include "eval-cache.hh"
+#include "names.hh"
namespace nix {
-App::App(EvalState & state, Value & vApp)
+App Installable::toApp(EvalState & state)
{
- state.forceAttrs(vApp);
+ auto [cursor, attrPath] = getCursor(state, true);
- 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);
+ auto type = cursor->getAttr("type")->getString();
- auto aProgram = vApp.attrs->need(state.symbols.create("program"));
- program = state.forceString(*aProgram.value, context, *aProgram.pos);
+ if (type == "app") {
+ auto [program, context] = cursor->getAttr("program")->getStringWithContext();
- // FIXME: check that 'program' is in the closure of 'context'.
- if (!state.store->isInStore(program))
- throw Error("app program '%s' is not in the Nix store", program);
-}
+ if (!state.store->isInStore(program))
+ throw Error("app program '%s' is not in the Nix store", program);
-App Installable::toApp(EvalState & state)
-{
- return App(state, *toValue(state).first);
+ std::vector<StorePathWithOutputs> context2;
+ for (auto & [path, name] : context)
+ context2.push_back({state.store->parseStorePath(path), {name}});
+
+ return App {
+ .context = std::move(context2),
+ .program = program,
+ };
+ }
+
+ else if (type == "derivation") {
+ auto drvPath = cursor->forceDerivation();
+ auto outPath = cursor->getAttr(state.sOutPath)->getString();
+ auto outputName = cursor->getAttr(state.sOutputName)->getString();
+ auto name = cursor->getAttr(state.sName)->getString();
+ return App {
+ .context = { { drvPath, {outputName} } },
+ .program = outPath + "/bin/" + DrvName(name).name,
+ };
+ }
+
+ else
+ throw Error("attribute '%s' has unsupported type '%s'", attrPath, type);
}
}
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 17df29fdb..847985ea3 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -243,11 +243,14 @@ struct CmdFlakeCheck : FlakeCommand
auto checkApp = [&](const std::string & attrPath, Value & v, const Pos & pos) {
try {
+ #if 0
+ // FIXME
auto app = App(*state, v);
for (auto & i : app.context) {
auto [drvPathS, outputName] = decodeContext(i);
store->parseStorePath(drvPathS);
}
+ #endif
} catch (Error & e) {
e.addPrefix(fmt("while checking the app definition '" ANSI_BOLD "%s" ANSI_NORMAL "' at %s:\n", attrPath, pos));
throw;
@@ -544,9 +547,9 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
Strings{templateName == "" ? "defaultTemplate" : templateName},
Strings(attrsPathPrefixes), lockFlags);
- auto cursor = installable.getCursor(*evalState, true);
+ auto [cursor, attrPath] = installable.getCursor(*evalState, true);
- auto templateDir = cursor.first->getAttr("path")->getString();
+ auto templateDir = cursor->getAttr("path")->getString();
assert(store->isInStore(templateDir));
diff --git a/src/nix/installables.hh b/src/nix/installables.hh
index 1e6623f88..eb34365d4 100644
--- a/src/nix/installables.hh
+++ b/src/nix/installables.hh
@@ -24,11 +24,9 @@ typedef std::vector<Buildable> Buildables;
struct App
{
- PathSet context;
+ std::vector<StorePathWithOutputs> context;
Path program;
// FIXME: add args, sandbox settings, metadata, ...
-
- App(EvalState & state, Value & vApp);
};
struct Installable
diff --git a/src/nix/run.cc b/src/nix/run.cc
index 204937cbc..59a6c7252 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -172,12 +172,18 @@ struct CmdRun : InstallableCommand, RunCommon
Strings getDefaultFlakeAttrPaths() override
{
- return {"defaultApp." + settings.thisSystem.get()};
+ Strings res{"defaultApp." + settings.thisSystem.get()};
+ for (auto & s : SourceExprCommand::getDefaultFlakeAttrPaths())
+ res.push_back(s);
+ return res;
}
Strings getDefaultFlakeAttrPathPrefixes() override
{
- return {"apps." + settings.thisSystem.get() + "."};
+ Strings res{"apps." + settings.thisSystem.get() + ".", "packages"};
+ for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes())
+ res.push_back(s);
+ return res;
}
void run(ref<Store> store) override
@@ -186,7 +192,7 @@ struct CmdRun : InstallableCommand, RunCommon
auto app = installable->toApp(*state);
- state->realiseContext(app.context);
+ state->store->buildPaths(app.context);
Strings allArgs{app.program};
for (auto & i : args) allArgs.push_back(i);