From 57a30e101b36a064f09619bf4a3f0b8a3fdcdcad Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Wed, 19 Jul 2017 16:06:10 +0200
Subject: [PATCH] nix search: Ignore top-level eval errors

$NIX_PATH may contain elements that don't evaluate to an attrset (like
"nixos-config"), so ignore those.
---
 src/nix/installables.cc | 6 +++++-
 src/nix/search.cc       | 9 ++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index 4da736f4d..59162fdc1 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -16,6 +16,8 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
 {
     if (vSourceExpr) return vSourceExpr;
 
+    auto sToplevel = state.symbols.create("_toplevel");
+
     vSourceExpr = state.allocValue();
 
     if (file != "") {
@@ -29,7 +31,9 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
 
         auto searchPath = state.getSearchPath();
 
-        state.mkAttrs(*vSourceExpr, searchPath.size());
+        state.mkAttrs(*vSourceExpr, searchPath.size() + 1);
+
+        mkBool(*state.allocAttr(*vSourceExpr, sToplevel), true);
 
         std::unordered_set<std::string> seen;
 
diff --git a/src/nix/search.cc b/src/nix/search.cc
index 8aac06ad2..970dcb983 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -54,6 +54,8 @@ struct CmdSearch : SourceExprCommand, MixJSON
 
         auto jsonOut = json ? std::make_unique<JSONObject>(std::cout, true) : nullptr;
 
+        auto sToplevel = state->symbols.create("_toplevel");
+
         doExpr = [&](Value * v, std::string attrPath, bool toplevel) {
             debug("at attribute ‘%s’", attrPath);
 
@@ -123,7 +125,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
                         if (j == attrs->end() || !state->forceBool(*j->value, *j->pos)) return;
                     }
 
-                    Bindings::iterator j = v->attrs->find(state->symbols.create("_toplevel"));
+                    Bindings::iterator j = v->attrs->find(sToplevel);
                     bool toplevel2 = j != v->attrs->end() && state->forceBool(*j->value, *j->pos);
 
                     for (auto & i : *v->attrs) {
@@ -134,6 +136,11 @@ struct CmdSearch : SourceExprCommand, MixJSON
                 }
 
             } catch (AssertionError & e) {
+            } catch (Error & e) {
+                if (!toplevel) {
+                    e.addPrefix(fmt("While evaluating the attribute ‘%s’:\n", attrPath));
+                    throw;
+                }
             }
         };
 
-- 
GitLab