diff --git a/corepkgs/channels/unpack.sh.in b/corepkgs/channels/unpack.sh.in index 1f2886a6a..1be4a39a1 100644 --- a/corepkgs/channels/unpack.sh.in +++ b/corepkgs/channels/unpack.sh.in @@ -4,9 +4,6 @@ @coreutils@/mkdir $out/tmp cd $out/tmp -expr=$out/default.nix -echo '{' > $expr - inputs=($inputs) for ((n = 0; n < ${#inputs[*]}; n += 2)); do channelName=${inputs[n]} @@ -15,19 +12,15 @@ for ((n = 0; n < ${#inputs[*]}; n += 2)); do @bunzip2@ < $channelTarball | @tar@ xf - nr=1 - dirName=$channelName + attrName=$(echo $channelName | @tr@ -- '- ' '__') + dirName=$attrName while test -e ../$dirName; do nr=$((nr+1)) - dirName=$channelName-$nr + dirName=$attrName-$nr done @coreutils@/mv * ../$dirName # !!! hacky - - attrName=$(echo $dirName | @tr@ -- '- ' '__') - echo "$attrName = let e = import ./$dirName; in if builtins.isFunction e then e {} else e;" >> $expr done -echo '} // {_combineChannels = true;}' >> $expr - cd .. @coreutils@/rmdir tmp diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml index 247471d9b..9c9114a90 100644 --- a/doc/manual/nix-env.xml +++ b/doc/manual/nix-env.xml @@ -142,14 +142,14 @@ linkend="sec-common-options" />. ~/.nix-defexpr + + The default Nix expression used by the , , and operations to obtain - derivations. It is generally a symbolic link to some other - location set using the operation. The - option may be used to override this - default. + derivations. The option may be used to + override this default. @@ -1061,43 +1061,4 @@ error: no generation older than the current (91) exists - - -Operation <option>--import</option> - -Synopsis - - - nix-env - - - - - path - - - - - -Description - -This operation makes path the default -active Nix expression for the user. That is, the symlink -~/.nix-userenv is made to point to -path. - - - - -Examples - - -$ nix-env -I ~/nixpkgs-0.5/ - - - - - - - diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml index 9770e9182..01194d4c6 100644 --- a/doc/manual/writing-nix-expressions.xml +++ b/doc/manual/writing-nix-expressions.xml @@ -1217,6 +1217,10 @@ set, the attributes of which specify the inputs of the build. They are simply concatenated, separated by spaces. + true is passed as + 1, false + and null are passed as empty string. + diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in index 1efb1a03a..c023a7539 100644 --- a/scripts/nix-channel.in +++ b/scripts/nix-channel.in @@ -18,6 +18,8 @@ $ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache; my $home = $ENV{"HOME"}; die '$HOME not set' unless defined $home; my $channelsList = "$home/.nix-channels"; + +my $nixDefExpr = "$home/.nix-defexpr"; my @channels; @@ -136,9 +138,12 @@ sub update { unlink "$rootFile.tmp"; - # Make it the default Nix expression for `nix-env'. - system("@bindir@/nix-env", "--import", "$outPath") == 0 - or die "cannot pull set default Nix expression to `$outPath'"; + # Make the channels appear in nix-env. + unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr + mkdir $nixDefExpr or die "cannot create directory `$nixDefExpr'" if !-e $nixDefExpr; + my $channelLink = "$nixDefExpr/channels"; + unlink $channelLink; # !!! not atomic + symlink($outPath, $channelLink) or die "cannot symlink `$channelLink' to `$outPath'"; } diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in index bb72601eb..3aaed7e59 100644 --- a/scripts/nix-install-package.in +++ b/scripts/nix-install-package.in @@ -13,7 +13,7 @@ downloading it from URL. Flags: --profile / -p LINK: install into the specified profile - --non-interactive: don't run inside a new terminal XXX + --non-interactive: don't run inside a new terminal EOF ; # ' exit 1; diff --git a/scripts/nix-prefetch-url.in b/scripts/nix-prefetch-url.in index 5621d5204..bd970e373 100644 --- a/scripts/nix-prefetch-url.in +++ b/scripts/nix-prefetch-url.in @@ -48,7 +48,7 @@ if test -z "$finalPath"; then tmpPath=/tmp/nix-prefetch-url-$$ # !!! security? tmpFile=$tmpPath/$name - mkdir $tmpPath + mkdir $tmpPath # !!! retry if tmpPath already exists # Optionally do timestamp-based caching of the download. # Actually, the only thing that we cache in $NIX_DOWNLOAD_CACHE is diff --git a/scripts/nix-push.in b/scripts/nix-push.in index 992622fbb..dd00841d7 100644 --- a/scripts/nix-push.in +++ b/scripts/nix-push.in @@ -264,8 +264,12 @@ foreach my $narArchive (@narArchives) { print STDERR "uploading manifest...\n"; if ($localCopy) { copyFile $manifest, $localManifestFile; + copyFile "$manifest.bz2", "$localManifestFile.bz2"; } else { system("$curl --show-error --upload-file " . "'$manifest' '$manifestPutURL' > /dev/null") == 0 or die "curl failed on $manifest: $?"; + system("$curl --show-error --upload-file " . + "'$manifest'.bz2 '$manifestPutURL'.bz2 > /dev/null") == 0 or + die "curl failed on $manifest: $?"; } diff --git a/scripts/readmanifest.pm.in b/scripts/readmanifest.pm.in index 1d4444470..b41e72dfb 100644 --- a/scripts/readmanifest.pm.in +++ b/scripts/readmanifest.pm.in @@ -222,6 +222,14 @@ sub writeManifest rename("$manifest.tmp", $manifest) or die "cannot rename $manifest.tmp: $!"; + + + # Create a bzipped manifest. + system("@bzip2@ < $manifest > $manifest.bz2.tmp") == 0 + or die "cannot compress manifest"; + + rename("$manifest.bz2.tmp", "$manifest.bz2") + or die "cannot rename $manifest.bz2.tmp: $!"; } diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index f79b2fd0e..e07b333a5 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -224,8 +224,8 @@ static void getDerivations(EvalState & state, Expr e, ATermMap drvMap(ATgetLength(es)); queryAllAttrs(e, drvMap); - /* !!! undocumented hackery to support - corepkgs/channels/unpack.sh. */ + /* !!! undocumented hackery to support combining channels in + nix-env.cc. */ Expr e2 = drvMap.get(toATerm("_combineChannels")); bool combineChannels = e2 && evalBool(state, e2); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index f696d8267..17118364b 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -921,7 +921,6 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) if (matchAttrs(evaledExpr, attrs)){ Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("attr"))); string attr = evalStringNoCtx(state,e); - ATerm value; Expr r = makeSelect(evaledExpr, toATerm("value")); res.set(toATerm(attr), makeAttrRHS(r, makeNoPos())); } @@ -931,7 +930,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) } // for return makeAttrs(res); } catch (Error & e) { - e.addPrefix(format("while calling listToAttrs ")); + e.addPrefix(format("in `listToAttrs':\n")); throw; } } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 518678515..396e5077d 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -54,18 +54,24 @@ RemoteStore::RemoteStore() from.fd = fdSocket; to.fd = fdSocket; - /* Send the magic greeting, check for the reply. */ try { writeInt(WORKER_MAGIC_1, to); - writeInt(verbosity, to); unsigned int magic = readInt(from); if (magic != WORKER_MAGIC_2) throw Error("protocol mismatch"); + + unsigned int daemonVersion = readInt(from); + if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) + throw Error("Nix daemon protocol version not supported"); + writeInt(PROTOCOL_VERSION, to); processStderr(); + } catch (Error & e) { throw Error(format("cannot start worker (%1%)") % e.msg()); } + + setOptions(); } @@ -155,6 +161,19 @@ RemoteStore::~RemoteStore() } +void RemoteStore::setOptions() +{ + writeInt(wopSetOptions, to); + writeInt(keepFailed, to); + writeInt(keepGoing, to); + writeInt(tryFallback, to); + writeInt(verbosity, to); + writeInt(maxBuildJobs, to); + writeInt(maxSilentTime, to); + processStderr(); +} + + bool RemoteStore::isValidPath(const Path & path) { writeInt(wopIsValidPath, to); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 0ef3e730a..77daae195 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -117,6 +117,8 @@ private: void forkSlave(); void connectToDaemon(); + + void setOptions(); }; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index 66ccc1da1..1831ff775 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -5,8 +5,11 @@ namespace nix { -#define WORKER_MAGIC_1 0x6e697864 -#define WORKER_MAGIC_2 0x6478696e +#define WORKER_MAGIC_1 0x6e697863 +#define WORKER_MAGIC_2 0x6478696f + +#define PROTOCOL_VERSION 0x101 +#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) typedef enum { @@ -48,6 +51,7 @@ typedef enum { wopRevertToRevision, wopShareState, wopUnShareState, //37 + wopSetOptions, } WorkerOp; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 4f7effb23..4a1ff59ea 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -155,6 +155,7 @@ bool pathExists(const Path & path) Path readLink(const Path & path) { + checkInterrupt(); struct stat st; if (lstat(path.c_str(), &st)) throw SysError(format("getting status of `%1%'") % path); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 4e9f26624..39da0288e 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -24,6 +24,8 @@ #include #include +#include +#include #include @@ -65,7 +67,7 @@ struct Globals typedef void (* Operation) (Globals & globals, - Strings opFlags, Strings opArgs); + Strings args, Strings opFlags, Strings opArgs); void printHelp() @@ -74,11 +76,86 @@ void printHelp() } +static string needArg(Strings::iterator & i, + Strings & args, const string & arg) +{ + if (i == args.end()) throw UsageError( + format("`%1%' requires an argument") % arg); + return *i++; +} + + +static bool parseInstallSourceOptions(Globals & globals, + Strings::iterator & i, Strings & args, const string & arg) +{ + if (arg == "--from-expression" || arg == "-E") + globals.instSource.type = srcNixExprs; + else if (arg == "--from-profile") { + globals.instSource.type = srcProfile; + globals.instSource.profile = needArg(i, args, arg); + } + else if (arg == "--attr" || arg == "-A") + globals.instSource.type = srcAttrPath; + else return false; + return true; +} + + +static bool isNixExpr(const Path & path) +{ + struct stat st; + if (stat(path.c_str(), &st) == -1) + throw SysError(format("getting information about `%1%'") % path); + + return !S_ISDIR(st.st_mode) || pathExists(path + "/default.nix"); +} + + +static void getAllExprs(EvalState & state, + const Path & path, ATermMap & attrs) +{ + Strings names = readDirectory(path); + + for (Strings::iterator i = names.begin(); i != names.end(); ++i) { + Path path2 = path + "/" + *i; + + struct stat st; + if (stat(path2.c_str(), &st) == -1) + continue; // ignore dangling symlinks in ~/.nix-defexpr + + if (isNixExpr(path2)) + attrs.set(toATerm(*i), makeAttrRHS( + parseExprFromFile(state, absPath(path2)), makeNoPos())); + else + getAllExprs(state, path2, attrs); + } +} + + +static Expr loadSourceExpr(EvalState & state, const Path & path) +{ + if (isNixExpr(path)) return parseExprFromFile(state, absPath(path)); + + /* The path is a directory. Put the Nix expressions in the + directory in an attribute set, with the file name of each + expression as the attribute name. Recurse into subdirectories + (but keep the attribute set flat, not nested, to make it easier + for a user to have a ~/.nix-defexpr directory that includes + some system-wide directory). */ + ATermMap attrs; + attrs.set(toATerm("_combineChannels"), makeAttrRHS(eTrue, makeNoPos())); + getAllExprs(state, path, attrs); + return makeAttrs(attrs); +} + + static void loadDerivations(EvalState & state, Path nixExprPath, - string systemFilter, const ATermMap & autoArgs, DrvInfos & elems) + string systemFilter, const ATermMap & autoArgs, + const string & pathPrefix, DrvInfos & elems) { getDerivations(state, - parseExprFromFile(state, absPath(nixExprPath)), "", autoArgs, elems); + findAlongAttrPath(state, pathPrefix, autoArgs, loadSourceExpr(state, nixExprPath)), + pathPrefix, autoArgs, elems); /* Filter out all derivations not applicable to the current system. */ @@ -371,7 +448,7 @@ static void queryInstSources(EvalState & state, Nix expression. */ DrvInfos allElems; loadDerivations(state, instSource.nixExprPath, - instSource.systemFilter, instSource.autoArgs, allElems); + instSource.systemFilter, instSource.autoArgs, "", allElems); elems = filterBySelector(state, allElems, args, newestOnly); @@ -386,9 +463,7 @@ static void queryInstSources(EvalState & state, (import ./foo.nix)' = `(import ./foo.nix).bar'. */ case srcNixExprs: { - - Expr e1 = parseExprFromFile(state, - absPath(instSource.nixExprPath)); + Expr e1 = loadSourceExpr(state, instSource.nixExprPath); for (Strings::const_iterator i = args.begin(); i != args.end(); ++i) @@ -452,7 +527,7 @@ static void queryInstSources(EvalState & state, i != args.end(); ++i) getDerivations(state, findAlongAttrPath(state, *i, instSource.autoArgs, - parseExprFromFile(state, instSource.nixExprPath)), + loadSourceExpr(state, instSource.nixExprPath)), "", instSource.autoArgs, elems); break; } @@ -690,10 +765,15 @@ static void installDerivations(Globals & globals, static void opInstall(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { - if (opFlags.size() > 0) - throw UsageError(format("unknown flag `%1%'") % opFlags.front()); + for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { + string arg = *i++; + if (parseInstallSourceOptions(globals, i, opFlags, arg)) ; + else if (arg == "--preserve-installed" || arg == "-P") + globals.preserveInstalled = true; + else throw UsageError(format("unknown flag `%1%'") % arg); + } installDerivations(globals, opArgs, globals.profile); } @@ -789,16 +869,18 @@ static void upgradeDerivations(Globals & globals, static void opUpgrade(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { UpgradeType upgradeType = utLt; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--lt") upgradeType = utLt; - else if (*i == "--leq") upgradeType = utLeq; - else if (*i == "--eq") upgradeType = utEq; - else if (*i == "--always") upgradeType = utAlways; - else throw UsageError(format("unknown flag `%1%'") % *i); + for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { + string arg = *i++; + if (parseInstallSourceOptions(globals, i, opFlags, arg)) ; + else if (arg == "--lt") upgradeType = utLt; + else if (arg == "--leq") upgradeType = utLeq; + else if (arg == "--eq") upgradeType = utEq; + else if (arg == "--always") upgradeType = utAlways; + else throw UsageError(format("unknown flag `%1%'") % arg); + } upgradeDerivations(globals, opArgs, upgradeType); } @@ -814,7 +896,7 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv, static void opSetFlag(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -853,10 +935,13 @@ static void opSetFlag(Globals & globals, static void opSet(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { - if (opFlags.size() > 0) - throw UsageError(format("unknown flag `%1%'") % opFlags.front()); + for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { + string arg = *i++; + if (parseInstallSourceOptions(globals, i, opFlags, arg)) ; + else throw UsageError(format("unknown flag `%1%'") % arg); + } DrvInfos elems; queryInstSources(globals.state, globals.instSource, opArgs, elems, true); @@ -909,7 +994,7 @@ static void uninstallDerivations(Globals & globals, DrvNames & selectors, static void opUninstall(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1016,9 +1101,11 @@ static string colorString(const string & s) static void opQuery(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { typedef vector< map > ResultSet; + Strings remaining; + string attrPath; bool printStatus = false; bool printName = true; @@ -1036,45 +1123,46 @@ static void opQuery(Globals & globals, readOnlyMode = true; /* makes evaluation a bit faster */ - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - 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; - else if (*i == "--meta") printMeta = true; - else if (*i == "--installed") source = sInstalled; - else if (*i == "--available" || *i == "-a") source = sAvailable; - else if (*i == "--prebuilt-only" || *i == "-b") prebuiltOnly = true; - else if (*i == "--xml") xmlOutput = true; - else throw UsageError(format("unknown flag `%1%'") % *i); - - if (globals.instSource.type == srcAttrPath) printAttrPath = true; /* hack */ - - if (opArgs.size() == 0) { - printMsg(lvlInfo, "warning: you probably meant to specify the argument '*' to show all packages"); + for (Strings::iterator i = args.begin(); i != args.end(); ) { + string arg = *i++; + if (arg == "--status" || arg == "-s") printStatus = true; + else if (arg == "--no-name") printName = false; + else if (arg == "--system") printSystem = true; + else if (arg == "--description") printDescription = true; + else if (arg == "--compare-versions" || arg == "-c") compareVersions = true; + else if (arg == "--drv-path") printDrvPath = true; + else if (arg == "--out-path") printOutPath = true; + else if (arg == "--meta") printMeta = true; + else if (arg == "--installed") source = sInstalled; + else if (arg == "--available" || arg == "-a") source = sAvailable; + else if (arg == "--prebuilt-only" || arg == "-b") prebuiltOnly = true; + else if (arg == "--xml") xmlOutput = true; + else if (arg == "--attr-path" || arg == "-P") printAttrPath = true; + else if (arg == "--attr" || arg == "-A") + attrPath = needArg(i, args, arg); + else if (arg[0] == '-') + throw UsageError(format("unknown flag `%1%'") % arg); + else remaining.push_back(arg); } + if (remaining.size() == 0) + printMsg(lvlInfo, "warning: you probably meant to specify the argument '*' to show all packages"); + /* Obtain derivation information from the specified source. */ DrvInfos availElems, installedElems; - if (source == sInstalled || compareVersions || printStatus) { + if (source == sInstalled || compareVersions || printStatus) installedElems = queryInstalled(globals.state, globals.profile); - } - if (source == sAvailable || compareVersions) { + if (source == sAvailable || compareVersions) loadDerivations(globals.state, globals.instSource.nixExprPath, globals.instSource.systemFilter, globals.instSource.autoArgs, - availElems); - } + attrPath, availElems); DrvInfos elems = filterBySelector(globals.state, source == sInstalled ? installedElems : availElems, - opArgs, false); + remaining, false); DrvInfos & otherElems(source == sInstalled ? availElems : installedElems); @@ -1234,7 +1322,7 @@ static void opQuery(Globals & globals, static void opSwitchProfile(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1282,7 +1370,7 @@ static void switchGeneration(Globals & globals, int dstGen) static void opSwitchGeneration(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1298,7 +1386,7 @@ static void opSwitchGeneration(Globals & globals, static void opRollback(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1310,7 +1398,7 @@ static void opRollback(Globals & globals, static void opListGenerations(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1343,7 +1431,7 @@ static void deleteGeneration2(const Path & profile, unsigned int gen) static void opDeleteGenerations(Globals & globals, - Strings opFlags, Strings opArgs) + Strings args, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1381,30 +1469,9 @@ static void opDeleteGenerations(Globals & globals, } -static void opDefaultExpr(Globals & globals, - Strings opFlags, Strings opArgs) -{ - if (opFlags.size() > 0) - throw UsageError(format("unknown flag `%1%'") % opFlags.front()); - if (opArgs.size() != 1) - throw UsageError(format("exactly one argument expected")); - - switchLink(getDefNixExprPath(), absPath(opArgs.front())); -} - - -static string needArg(Strings::iterator & i, - Strings & args, const string & arg) -{ - if (i == args.end()) throw UsageError( - format("`%1%' requires an argument") % arg); - return *i++; -} - - void run(Strings args) { - Strings opFlags, opArgs; + Strings opFlags, opArgs, remaining; Operation op = 0; Globals globals; @@ -1426,14 +1493,6 @@ void run(Strings args) if (arg == "--install" || arg == "-i") op = opInstall; - else if (arg == "--from-expression" || arg == "-E") - globals.instSource.type = srcNixExprs; - else if (arg == "--from-profile") { - globals.instSource.type = srcProfile; - globals.instSource.profile = needArg(i, args, arg); - } - else if (arg == "--attr" || arg == "-A") - globals.instSource.type = srcAttrPath; else if (parseOptionArg(arg, i, args.end(), globals.state, globals.instSource.autoArgs)) ; @@ -1449,8 +1508,6 @@ void run(Strings args) op = opSet; else if (arg == "--query" || arg == "-q") op = opQuery; - else if (arg == "--import" || arg == "-I") /* !!! bad name */ - op = opDefaultExpr; else if (arg == "--profile" || arg == "-p") globals.profile = absPath(needArg(i, args, arg)); else if (arg == "--file" || arg == "-f") @@ -1469,14 +1526,15 @@ void run(Strings args) printMsg(lvlInfo, "(dry run; not doing anything)"); globals.dryRun = true; } - else if (arg == "--preserve-installed" || arg == "-P") - globals.preserveInstalled = true; else if (arg == "--system-filter") globals.instSource.systemFilter = needArg(i, args, arg); - else if (arg[0] == '-') - opFlags.push_back(arg); - else - opArgs.push_back(arg); + else { + remaining.push_back(arg); + if (arg[0] == '-') + opFlags.push_back(arg); + else + opArgs.push_back(arg); + } if (oldOp && oldOp != op) throw UsageError("only one operation may be specified"); @@ -1493,7 +1551,7 @@ void run(Strings args) store = openStore(); - op(globals, opFlags, opArgs); + op(globals, remaining, opFlags, opArgs); printEvalStats(globals.state); } diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index f901649a9..a85fbf9b5 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -623,6 +623,18 @@ static void performOp(Source & from, Sink & to, unsigned int op) writeInt(1, to); break; } + + case wopSetOptions: { + keepFailed = readInt(from) != 0; + keepGoing = readInt(from) != 0; + tryFallback = readInt(from) != 0; + verbosity = (Verbosity) readInt(from); + maxBuildJobs = readInt(from); + maxSilentTime = readInt(from); + startWork(); + stopWork(); + break; + } default: throw Error(format("invalid operation %1%") % op); @@ -647,14 +659,19 @@ static void processConnection() unsigned int magic = readInt(from); if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch"); - verbosity = (Verbosity) readInt(from); writeInt(WORKER_MAGIC_2, to); + writeInt(PROTOCOL_VERSION, to); + unsigned int clientVersion = readInt(from); + /* Send startup error messages to the client. */ startWork(); try { + /* If we can't accept clientVersion, then throw an error + *here* (not above). */ + /* Prevent users from doing something very dangerous. */ if (geteuid() == 0 && querySetting("build-users-group", "") == "") diff --git a/tests/fixed.builder1.sh b/tests/fixed.builder1.sh index c792f52a5..c41bb2b9a 100644 --- a/tests/fixed.builder1.sh +++ b/tests/fixed.builder1.sh @@ -1 +1,3 @@ +if test "$IMPURE_VAR1" != "foo"; then exit 1; fi +if test "$IMPURE_VAR2" != "bar"; then exit 1; fi echo "Hello World!" > $out diff --git a/tests/fixed.nix.in b/tests/fixed.nix.in index c7dd99e6f..5d364eb39 100644 --- a/tests/fixed.nix.in +++ b/tests/fixed.nix.in @@ -10,6 +10,7 @@ rec { outputHash = hash; PATH = "@testPath@"; inherit dummy; + impureEnvVars = ["IMPURE_VAR1" "IMPURE_VAR2"]; }; f = f2 ""; diff --git a/tests/fixed.sh b/tests/fixed.sh index d0a284af4..72038adfc 100644 --- a/tests/fixed.sh +++ b/tests/fixed.sh @@ -2,6 +2,9 @@ source common.sh clearStore +export IMPURE_VAR1=foo +export IMPURE_VAR2=bar + echo 'testing good...' drvs=$($nixinstantiate fixed.nix -A good) echo $drvs diff --git a/tests/init.sh b/tests/init.sh index 6fff25944..b3470f4de 100644 --- a/tests/init.sh +++ b/tests/init.sh @@ -29,6 +29,7 @@ ln -s $TOP/scripts/nix-prefetch-url $NIX_BIN_DIR/ ln -s $TOP/scripts/nix-collect-garbage $NIX_BIN_DIR/ ln -s $TOP/scripts/nix-build $NIX_BIN_DIR/ ln -s $TOP/scripts/nix-install-package $NIX_BIN_DIR/ +ln -s $TOP/scripts/nix-push $NIX_BIN_DIR/ ln -s $TOP/scripts/nix-pull $NIX_BIN_DIR/ ln -s $bzip2_bin_test/bzip2 $NIX_BIN_DIR/ ln -s $bzip2_bin_test/bunzip2 $NIX_BIN_DIR/ @@ -59,7 +60,9 @@ for i in \ $NIX_BIN_DIR/nix-collect-garbage \ $NIX_BIN_DIR/nix-build \ $NIX_BIN_DIR/nix-install-package \ + $NIX_BIN_DIR/nix-push \ $NIX_BIN_DIR/nix-pull \ + $NIX_BIN_DIR/nix/readmanifest.pm \ ; do sed < $i > $i.tmp \ -e "s^$REAL_BIN_DIR^$NIX_BIN_DIR^" \ diff --git a/tests/nix-pull.sh b/tests/nix-pull.sh index 5ef3e55ca..d2309742d 100644 --- a/tests/nix-pull.sh +++ b/tests/nix-pull.sh @@ -2,7 +2,7 @@ source common.sh pullCache () { echo "pulling cache..." - $PERL -w -I$TOP/scripts $TOP/scripts/nix-pull file://$TEST_ROOT/manifest + $NIX_BIN_DIR/nix-pull file://$TEST_ROOT/manifest } clearStore diff --git a/tests/nix-push.sh b/tests/nix-push.sh index 46f1edb40..a9a2f5f9c 100644 --- a/tests/nix-push.sh +++ b/tests/nix-push.sh @@ -7,5 +7,5 @@ echo "pushing $drvPath" mkdir $TEST_ROOT/cache -$PERL -w -I$TOP/scripts $TOP/scripts/nix-push \ +$NIX_BIN_DIR/nix-push \ --copy $TEST_ROOT/cache $TEST_ROOT/manifest $drvPath