From 854e155b2ce22ed9413710807791c6df96b43c94 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Mon, 8 Oct 2007 10:20:43 +0000 Subject: [PATCH] Merged R8636 --- configure.ac | 1 + corepkgs/channels/unpack.sh.in | 29 +++++++++++++------ doc/manual/release-notes.xml | 6 ++++ scripts/nix-channel.in | 17 ++++++------ src/libexpr/get-drvs.cc | 24 ++++++++++++++-- src/libexpr/get-drvs.hh | 1 + src/nix-env/nix-env.cc | 51 +++++++++++++++++++++++++--------- substitute.mk | 1 + 8 files changed, 97 insertions(+), 33 deletions(-) diff --git a/configure.ac b/configure.ac index 5af239cbd..1842b1e15 100644 --- a/configure.ac +++ b/configure.ac @@ -139,6 +139,7 @@ fi AC_MSG_RESULT(yes) NEED_PROG(cat, cat) +NEED_PROG(tr, tr) AC_ARG_WITH(coreutils-bin, AC_HELP_STRING([--with-coreutils-bin=PATH], [path of cat, mkdir, etc.]), coreutils=$withval, coreutils=$(dirname $cat)) diff --git a/corepkgs/channels/unpack.sh.in b/corepkgs/channels/unpack.sh.in index 80c177024..03c6e5b2f 100644 --- a/corepkgs/channels/unpack.sh.in +++ b/corepkgs/channels/unpack.sh.in @@ -5,18 +5,29 @@ cd $out/tmp expr=$out/default.nix -echo '[' > $expr +echo '{' > $expr -nr=0 -for i in $inputs; do - echo "unpacking $i" - @bunzip2@ < $i | @tar@ xf - - @coreutils@/mv * ../$nr # !!! hacky - echo "(import ./$nr)" >> $expr - nr=$(($nr + 1)) +inputs=($inputs) +for ((n = 0; n < ${#inputs[*]}; n += 2)); do + channelName=${inputs[n]} + channelTarball=${inputs[n+1]} + echo "unpacking channel $channelName" + @bunzip2@ < $channelTarball | @tar@ xf - + + nr=1 + dirName=$channelName + while test -e ../$dirName; do + nr=$((nr+1)) + dirName=$channelName-$nr + done + + @coreutils@/mv * ../$dirName # !!! hacky + + attrName=$(echo $dirName | @tr@ -- '- ' '__') + echo "$attrName = import ./$dirName {};" >> $expr done -echo ']' >> $expr +echo '} // {_combineChannels = true;}' >> $expr cd .. @coreutils@/rmdir tmp diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml index da8c47588..43358fe55 100644 --- a/doc/manual/release-notes.xml +++ b/doc/manual/release-notes.xml @@ -70,10 +70,16 @@ info about installed packages in user environments. to show all meta info. + TODO: nix-env . Specific flags: active, priority, keep. + + + TODO: nix-env + / take package priorities into + account. nix-env -q now has a flag diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in index 73096a12b..095f36d79 100644 --- a/scripts/nix-channel.in +++ b/scripts/nix-channel.in @@ -89,21 +89,22 @@ sub update { # Create a Nix expression that fetches and unpacks the channel Nix # expressions. - my $nixExpr = "["; + my $inputs = "["; foreach my $url (@channels) { + $url =~ /\/([^\/]+)\/?$/; + my $channelName = $1; + $channelName = "unnamed" unless defined $channelName; + print "$channelName\n"; + my $fullURL = "$url/nixexprs.tar.bz2"; print "downloading Nix expressions from `$fullURL'...\n"; $ENV{"PRINT_PATH"} = 1; my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL' 2> /dev/null`; die "cannot fetch `$fullURL'" if $? != 0; chomp $path; - $nixExpr .= $path . " "; + $inputs .= '"' . $channelName . '"' . " " . $path . " "; } - $nixExpr .= "]"; - - $nixExpr = - "(import @datadir@/nix/corepkgs/channels/unpack.nix) " . - "{inputs = $nixExpr; system = \"@system@\";}"; + $inputs .= "]"; # Figure out a name for the GC root. my $userName = getpwuid($<); @@ -113,7 +114,7 @@ sub update { # Instantiate the Nix expression. print "unpacking channel Nix expressions...\n"; - my $storeExpr = `echo '$nixExpr' | @bindir@/nix-instantiate --add-root '$rootFile'.tmp -` + my $storeExpr = `@bindir@/nix-instantiate --add-root '$rootFile'.tmp @datadir@/nix/corepkgs/channels/unpack.nix --argstr system @system@ --arg inputs '$inputs'` or die "cannot instantiate Nix expression"; chomp $storeExpr; diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 7c16a7798..f79b2fd0e 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -107,6 +107,15 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const } +string DrvInfo::queryMetaInfo(EvalState & state, const string & name) const +{ + /* !!! evaluates all meta attributes => inefficient */ + MetaInfo meta = queryMetaInfo(state); + MetaInfo::iterator i = meta.find(name); + return i == meta.end() ? "" : i->second; +} + + void DrvInfo::setMetaInfo(const MetaInfo & meta) { ATermMap metaAttrs; @@ -214,12 +223,21 @@ static void getDerivations(EvalState & state, Expr e, if (matchAttrs(e, es)) { ATermMap drvMap(ATgetLength(es)); queryAllAttrs(e, drvMap); + + /* !!! undocumented hackery to support + corepkgs/channels/unpack.sh. */ + Expr e2 = drvMap.get(toATerm("_combineChannels")); + bool combineChannels = e2 && evalBool(state, e2); for (ATermMap::const_iterator i = drvMap.begin(); i != drvMap.end(); ++i) { startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % aterm2String(i->key)); string pathPrefix2 = addToPath(pathPrefix, aterm2String(i->key)); - if (getDerivation(state, i->value, pathPrefix2, drvs, doneExprs)) { + if (combineChannels) { + if (((string) aterm2String(i->key)) != "_combineChannels") + getDerivations(state, i->value, pathPrefix2, autoArgs, drvs, doneExprs); + } + else if (getDerivation(state, i->value, pathPrefix2, drvs, doneExprs)) { /* If the value of this attribute is itself an attribute set, should we recurse into it? => Only if it has a `recurseForDerivations = true' @@ -229,8 +247,8 @@ static void getDerivations(EvalState & state, Expr e, if (matchAttrs(e, es)) { ATermMap attrs(ATgetLength(es)); queryAllAttrs(e, attrs, false); - Expr e2 = attrs.get(toATerm("recurseForDerivations")); - if (e2 && evalBool(state, e2)) + if (((e2 = attrs.get(toATerm("recurseForDerivations"))) + && evalBool(state, e2))) getDerivations(state, e, pathPrefix2, autoArgs, drvs, doneExprs); } } diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 5fffd434a..ccce36bf6 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -38,6 +38,7 @@ public: string queryStateIdentifier(EvalState & state) const; string queryRuntimeStateArgs(EvalState & state) const; MetaInfo queryMetaInfo(EvalState & state) const; + string queryMetaInfo(EvalState & state, const string & name) const; void setDrvPath(const string & s) { diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 3a1fbba8b..93741ca6b 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -252,6 +252,16 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, } +static int comparePriorities(EvalState & state, + const DrvInfo & drv1, const DrvInfo & drv2) +{ + int prio1, prio2; + if (!string2Int(drv1.queryMetaInfo(state, "priority"), prio1)) prio1 = 0; + if (!string2Int(drv2.queryMetaInfo(state, "priority"), prio2)) prio2 = 0; + return prio2 - prio1; /* higher number = lower priority, so negate */ +} + + static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems, const Strings & args, bool newestOnly) @@ -278,8 +288,10 @@ static DrvInfos filterBySelector(EvalState & state, } /* If `newestOnly', if a selector matches multiple derivations - with the same name, pick the one with the highest version. - If there are multiple derivations with the same name *and* + with the same name, pick the one with the highest priority. + If there are multiple derivations with the same priority, + pick the one with the highest version. If there are + multiple derivations with the same priority and name and version, then pick the first one. */ if (newestOnly) { @@ -290,13 +302,22 @@ static DrvInfos filterBySelector(EvalState & state, for (Matches::iterator j = matches.begin(); j != matches.end(); ++j) { DrvName drvName(j->first.name); + int d = 1; + Newest::iterator k = newest.find(drvName.name); + if (k != newest.end()) { - int d = compareVersions(drvName.version, DrvName(k->second.first.name).version); - if (d > 0) newest[drvName.name] = *j; - else if (d == 0) multiple.insert(j->first.name); - } else + d = comparePriorities(state, j->first, k->second.first); + if (d == 0) + d = compareVersions(drvName.version, DrvName(k->second.first.name).version); + } + + if (d > 0) { newest[drvName.name] = *j; + multiple.erase(j->first.name); + } else if (d == 0) { + multiple.insert(j->first.name); + } } matches.clear(); @@ -712,9 +733,10 @@ static void upgradeDerivations(Globals & globals, if (meta["keep"] == "true") continue; /* Find the derivation in the input Nix expression with the - same name and satisfying the version constraints specified + same name that satisfies the version constraints specified by upgradeType. If there are multiple matches, take the - one with highest version. */ + one with the highest priority. If there are still multiple + matches, take the one with the highest version. */ DrvInfos::iterator bestElem = availElems.end(); DrvName bestName; for (DrvInfos::iterator j = availElems.begin(); @@ -722,16 +744,19 @@ static void upgradeDerivations(Globals & globals, { DrvName newName(j->name); if (newName.name == drvName.name) { - int d = compareVersions(drvName.version, newName.version); + int d = comparePriorities(globals.state, *i, *j); + if (d == 0) d = compareVersions(drvName.version, newName.version); if (upgradeType == utLt && d < 0 || upgradeType == utLeq && d <= 0 || upgradeType == utEq && d == 0 || upgradeType == utAlways) { - if ((bestElem == availElems.end() || - compareVersions( - bestName.version, newName.version) < 0)) - { + int d2 = -1; + if (bestElem != availElems.end()) { + d2 = comparePriorities(globals.state, *bestElem, *j); + if (d2 == 0) d2 = compareVersions(bestName.version, newName.version); + } + if (d2 < 0) { bestElem = j; bestName = newName; } diff --git a/substitute.mk b/substitute.mk index 5038bd4bf..bdc9c4350 100644 --- a/substitute.mk +++ b/substitute.mk @@ -17,6 +17,7 @@ -e "s^@perl\@^$(perl)^g" \ -e "s^@coreutils\@^$(coreutils)^g" \ -e "s^@tar\@^$(tar)^g" \ + -e "s^@tr\@^$(tr)^g" \ -e "s^@dot\@^$(dot)^g" \ -e "s^@xmllint\@^$(xmllint)^g" \ -e "s^@xmlflags\@^$(xmlflags)^g" \