about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.hh1
-rw-r--r--src/libexpr/get-drvs.cc43
-rw-r--r--src/libexpr/get-drvs.hh24
-rw-r--r--src/libexpr/primops.cc17
-rw-r--r--src/nix-env/main.cc7
-rw-r--r--tests/user-envs.nix.in8
-rw-r--r--tests/user-envs.sh4
7 files changed, 79 insertions, 25 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 602f63fdedaf..cbdcb274e062 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -56,6 +56,7 @@ Expr evalFile(EvalState & state, const Path & path);
 string evalString(EvalState & state, Expr e);
 Path evalPath(EvalState & state, Expr e);
 ATermList evalList(EvalState & state, Expr e);
+ATerm coerceToString(Expr e);
 
 /* Print statistics. */
 void printEvalStats(EvalState & state);
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 63e68eb6f489..ff38ff794812 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -2,6 +2,49 @@
 #include "nixexpr-ast.hh"
 
 
+string DrvInfo::queryDrvPath(EvalState & state) const
+{
+    if (drvPath == "") {
+        Expr a = attrs.get("drvPath");
+        (string &) drvPath = a ? evalPath(state, a) : "";
+    }
+    return drvPath;
+}
+
+
+string DrvInfo::queryOutPath(EvalState & state) const
+{
+    if (outPath == "") {
+        Expr a = attrs.get("outPath");
+        if (!a) throw Error("output path missing");
+        (string &) outPath = evalPath(state, a);
+    }
+    return outPath;
+}
+
+
+MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
+{
+    MetaInfo meta;
+    
+    Expr a = attrs.get("meta");
+    if (!a) return meta; /* fine, empty meta information */
+
+    ATermMap attrs2;
+    queryAllAttrs(evalExpr(state, a), attrs2);
+
+    for (ATermIterator i(attrs2.keys()); i; ++i) {
+        ATerm s = coerceToString(evalExpr(state, attrs2.get(*i)));
+        if (s)
+            meta[aterm2String(*i)] = aterm2String(s);
+        /* For future compatibility, ignore attribute values that are
+           not strings. */
+    }
+
+    return meta;
+}
+
+
 typedef set<Expr> Exprs;
 
 
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 5b1c0e6d4cc1..e692a5c660e1 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -7,6 +7,9 @@
 #include "eval.hh"
 
 
+typedef map<string, string> MetaInfo;
+
+
 struct DrvInfo
 {
 private:
@@ -19,24 +22,9 @@ public:
 
     ATermMap attrs;
 
-    string queryDrvPath(EvalState & state) const
-    {
-        if (drvPath == "") {
-            Expr a = attrs.get("drvPath");
-            (string &) drvPath = a ? evalPath(state, a) : "";
-        }
-        return drvPath;
-    }
-    
-    string queryOutPath(EvalState & state) const
-    {
-        if (outPath == "") {
-            Expr a = attrs.get("outPath");
-            if (!a) throw Error("output path missing");
-            (string &) outPath = evalPath(state, a);
-        }
-        return outPath;
-    }
+    string queryDrvPath(EvalState & state) const;
+    string queryOutPath(EvalState & state) const;
+    MetaInfo queryMetaInfo(EvalState & state) const;
 
     void setDrvPath(const string & s)
     {
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 77721a5a8d87..c5560be971df 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -390,14 +390,21 @@ static Expr primDirOf(EvalState & state, const ATermVector & args)
 }
 
 
+ATerm coerceToString(Expr e)
+{
+    ATerm s;
+    if (matchStr(e, s) || matchPath(e, s) || matchUri(e, s))
+        return s;
+    return 0;
+}
+
+
 /* Convert the argument (which can be a path or a uri) to a string. */
 static Expr primToString(EvalState & state, const ATermVector & args)
 {
-    Expr arg = evalExpr(state, args[0]);
-    ATerm s;
-    if (matchStr(arg, s) || matchPath(arg, s) || matchUri(arg, s))
-        return makeStr(s);
-    throw Error("cannot coerce value to string");
+    ATerm s = coerceToString(evalExpr(state, args[0]));
+    if (!s) throw Error("cannot coerce value to string");
+    return makeStr(s);
 }
 
 
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 4f299a7fe36d..f9a0c19a9b63 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -699,6 +699,7 @@ static void opQuery(Globals & globals,
     bool printSystem = false;
     bool printDrvPath = false;
     bool printOutPath = false;
+    bool printDescription = false;
     bool compareVersions = false;
 
     enum { sInstalled, sAvailable } source = sInstalled;
@@ -710,6 +711,7 @@ static void opQuery(Globals & globals,
         if (*i == "--status" || *i == "-s") printStatus = true;
         else if (*i == "--no-name") printName = false;
         else if (*i == "--system") printSystem = true;
+        else if (*i == "--description") printDescription = true;
         else if (*i == "--compare-versions" || *i == "-c") compareVersions = true;
         else if (*i == "--drv-path") printDrvPath = true;
         else if (*i == "--out-path") printOutPath = true;
@@ -808,6 +810,11 @@ static void opQuery(Globals & globals,
                 ? "-" : i->queryDrvPath(globals.state));
         
             if (printOutPath) columns.push_back(i->queryOutPath(globals.state));
+
+            if (printDescription) {
+                MetaInfo meta = i->queryMetaInfo(globals.state);
+                columns.push_back(meta["description"]);
+            }
             
             table.push_back(columns);
         }
diff --git a/tests/user-envs.nix.in b/tests/user-envs.nix.in
index 21feea0d31c9..6b9bbe86db41 100644
--- a/tests/user-envs.nix.in
+++ b/tests/user-envs.nix.in
@@ -7,12 +7,16 @@ assert foo == "foo";
 
 let {
 
-  makeDrv = name: progName: derivation {
+  makeDrv = name: progName: (derivation {
     inherit name progName system;
     builder = "@shell@";
     shell = "@shell@";
     args = ["-e" "-x" ./user-envs.builder.sh];
-  };
+  } // {
+    meta = {
+      description = "A silly test package";
+    };
+  });
 
   body = [
     (makeDrv "foo-1.0" "foo")
diff --git a/tests/user-envs.sh b/tests/user-envs.sh
index b8df8c37355c..b1ba0ccc164d 100644
--- a/tests/user-envs.sh
+++ b/tests/user-envs.sh
@@ -1,6 +1,7 @@
 source common.sh
 
 profiles="$NIX_STATE_DIR"/profiles
+rm -f $profiles/*
 
 # Query installed: should be empty.
 test "$($nixenv -p $profiles/test -q '*' | wc -l)" -eq 0
@@ -8,6 +9,9 @@ test "$($nixenv -p $profiles/test -q '*' | wc -l)" -eq 0
 # Query available: should contain several.
 test "$($nixenv -p $profiles/test -f ./user-envs.nix -qa '*' | wc -l)" -eq 5
 
+# Query descriptions.
+$nixenv -p $profiles/test -f ./user-envs.nix -qa '*' --description | grep silly
+
 # Install "foo-1.0".
 $nixenv -p $profiles/test -f ./user-envs.nix -i foo-1.0