aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-02-07 14:22:01 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-02-07 14:22:01 +0100
commitd2032edb2f86e955a8a7724a27c0c3225f386500 (patch)
tree33f4b8874c2e1816947e2086937b9175ec0b0e64
parent0b013a54dc570395bed887369f8dd622b8ce337b (diff)
nix edit: Support non-derivation attributes
E.g. $ nix edit .#nixosConfigurations.bla now works.
-rw-r--r--src/libexpr/attr-path.cc2
-rw-r--r--src/libexpr/attr-path.hh1
-rw-r--r--src/nix/edit.cc10
-rw-r--r--src/nix/eval.cc2
-rw-r--r--src/nix/installables.cc20
-rw-r--r--src/nix/installables.hh7
6 files changed, 24 insertions, 18 deletions
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 1e22f5708..4545bfd72 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -103,7 +103,7 @@ Pos findDerivationFilename(EvalState & state, Value & v, std::string what)
auto dummyArgs = state.allocBindings(0);
v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v).first;
} catch (Error &) {
- throw Error("package '%s' has no source location information", what);
+ throw NoPositionInfo("package '%s' has no source location information", what);
}
// FIXME: is it possible to extract the Pos object instead of doing this
diff --git a/src/libexpr/attr-path.hh b/src/libexpr/attr-path.hh
index 3e78e2899..fce160da7 100644
--- a/src/libexpr/attr-path.hh
+++ b/src/libexpr/attr-path.hh
@@ -8,6 +8,7 @@
namespace nix {
MakeError(AttrPathNotFound, Error);
+MakeError(NoPositionInfo, Error);
std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings & autoArgs, Value & vIn);
diff --git a/src/nix/edit.cc b/src/nix/edit.cc
index ca410cd1f..1683eada0 100644
--- a/src/nix/edit.cc
+++ b/src/nix/edit.cc
@@ -29,9 +29,15 @@ struct CmdEdit : InstallableCommand
{
auto state = getEvalState();
- auto v = installable->toValue(*state);
+ auto [v, pos] = installable->toValue(*state);
- Pos pos = findDerivationFilename(*state, *v, installable->what());
+ try {
+ pos = findDerivationFilename(*state, *v, installable->what());
+ } catch (NoPositionInfo &) {
+ }
+
+ if (pos == noPos)
+ throw Error("cannot find position information for '%s", installable->what());
stopProgressBar();
diff --git a/src/nix/eval.cc b/src/nix/eval.cc
index a991ee608..f23625161 100644
--- a/src/nix/eval.cc
+++ b/src/nix/eval.cc
@@ -52,7 +52,7 @@ struct CmdEval : MixJSON, InstallableCommand
auto state = getEvalState();
- auto v = installable->toValue(*state);
+ auto v = installable->toValue(*state).first;
PathSet context;
stopProgressBar();
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index fc9c8ab45..39ce9b38f 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -130,7 +130,7 @@ App::App(EvalState & state, Value & vApp)
App Installable::toApp(EvalState & state)
{
- return App(state, *toValue(state));
+ return App(state, *toValue(state).first);
}
struct InstallableStorePath : Installable
@@ -166,7 +166,7 @@ std::vector<flake::EvalCache::Derivation> InstallableValue::toDerivations()
{
auto state = cmd.getEvalState();
- auto v = toValue(*state);
+ auto v = toValue(*state).first;
Bindings & autoArgs = *cmd.getAutoArgs(*state);
@@ -229,11 +229,11 @@ struct InstallableExpr : InstallableValue
std::string what() override { return text; }
- Value * toValue(EvalState & state) override
+ std::pair<Value *, Pos> toValue(EvalState & state) override
{
auto v = state.allocValue();
state.eval(state.parseExprFromString(text, absPath(".")), *v);
- return v;
+ return {v, noPos};
}
};
@@ -248,11 +248,11 @@ struct InstallableAttrPath : InstallableValue
std::string what() override { return attrPath; }
- Value * toValue(EvalState & state) override
+ std::pair<Value *, Pos> toValue(EvalState & state) override
{
- auto vRes = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), *v).first;
+ auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), *v);
state.forceValue(*vRes);
- return vRes;
+ return {vRes, pos};
}
};
@@ -391,7 +391,7 @@ std::vector<flake::EvalCache::Derivation> InstallableFlake::toDerivations()
return res;
}
-Value * InstallableFlake::toValue(EvalState & state)
+std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state)
{
auto lockedFlake = lockFlake(state, flakeRef, cmd.lockFlags);
@@ -401,9 +401,9 @@ Value * InstallableFlake::toValue(EvalState & state)
for (auto & attrPath : getActualAttrPaths()) {
try {
- auto * v = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs).first;
+ auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
state.forceValue(*v);
- return v;
+ return {v, pos};
} catch (AttrPathNotFound & e) {
}
}
diff --git a/src/nix/installables.hh b/src/nix/installables.hh
index 2fd09dbf8..a96b07718 100644
--- a/src/nix/installables.hh
+++ b/src/nix/installables.hh
@@ -3,14 +3,13 @@
#include "util.hh"
#include "path.hh"
#include "flake/eval-cache.hh"
+#include "eval.hh"
#include <optional>
namespace nix {
-struct Value;
struct DrvInfo;
-class EvalState;
struct SourceExprCommand;
struct Buildable
@@ -45,7 +44,7 @@ struct Installable
App toApp(EvalState & state);
- virtual Value * toValue(EvalState & state)
+ virtual std::pair<Value *, Pos> toValue(EvalState & state)
{
throw Error("argument '%s' cannot be evaluated", what());
}
@@ -91,7 +90,7 @@ struct InstallableFlake : InstallableValue
std::vector<flake::EvalCache::Derivation> toDerivations() override;
- Value * toValue(EvalState & state) override;
+ std::pair<Value *, Pos> toValue(EvalState & state) override;
};
}