From d2032edb2f86e955a8a7724a27c0c3225f386500 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 7 Feb 2020 14:22:01 +0100 Subject: [PATCH] nix edit: Support non-derivation attributes E.g. $ nix edit .#nixosConfigurations.bla now works. --- src/libexpr/attr-path.cc | 2 +- src/libexpr/attr-path.hh | 1 + src/nix/edit.cc | 10 ++++++++-- src/nix/eval.cc | 2 +- src/nix/installables.cc | 20 ++++++++++---------- src/nix/installables.hh | 7 +++---- 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 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 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 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 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 InstallableFlake::toDerivations() return res; } -Value * InstallableFlake::toValue(EvalState & state) +std::pair 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 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 toValue(EvalState & state) { throw Error("argument '%s' cannot be evaluated", what()); } @@ -91,7 +90,7 @@ struct InstallableFlake : InstallableValue std::vector toDerivations() override; - Value * toValue(EvalState & state) override; + std::pair toValue(EvalState & state) override; }; }