From 37d1b1cafd17a18dc7dbef3b4ba7fb204158d58b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Mar 2006 16:20:42 +0000 Subject: [PATCH] * `nix-env -qa --description' shows human-readable descriptions of packages (provided that they have a `meta.description' attribute). E.g., $ ./src/nix-env/nix-env -qa --description gcc gcc-4.0.2 GNU Compiler Collection, 4.0.x (cross-compiler for sparc-linux) gcc-4.0.2 GNU Compiler Collection, 4.0.x (cross-compiler for mips-linux) gcc-4.0.2 GNU Compiler Collection, 4.0.x (cross-compiler for arm-linux) gcc-4.0.2 GNU Compiler Collection, 4.0.x --- src/libexpr/eval.hh | 1 + src/libexpr/get-drvs.cc | 43 +++++++++++++++++++++++++++++++++++++++++ src/libexpr/get-drvs.hh | 24 ++++++----------------- src/libexpr/primops.cc | 17 +++++++++++----- src/nix-env/main.cc | 7 +++++++ tests/user-envs.nix.in | 8 ++++++-- tests/user-envs.sh | 4 ++++ 7 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 602f63fd..cbdcb274 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 63e68eb6..ff38ff79 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 Exprs; diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 5b1c0e6d..e692a5c6 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -7,6 +7,9 @@ #include "eval.hh" +typedef map 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 77721a5a..c5560be9 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 4f299a7f..f9a0c19a 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 21feea0d..6b9bbe86 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 b8df8c37..b1ba0ccc 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