Merge remote-tracking branch 'origin/master' into flakes

This commit is contained in:
Eelco Dolstra 2020-03-20 13:15:11 +01:00
commit 1537e270fb
7 changed files with 45 additions and 51 deletions

View file

@ -19,6 +19,3 @@ of the manual. It helps you to get started with building Nix from source.
## License ## License
Nix is released under the LGPL v2.1 Nix is released under the LGPL v2.1
This product includes software developed by the OpenSSL Project for
use in the [OpenSSL Toolkit](https://www.OpenSSL.org/).

View file

@ -1066,7 +1066,8 @@ user environment elements, etc. -->
the derivation, which can be used to unambiguously select it using the derivation, which can be used to unambiguously select it using
the <link linkend="opt-attr"><option>--attr</option> option</link> the <link linkend="opt-attr"><option>--attr</option> option</link>
available in commands that install derivations like available in commands that install derivations like
<literal>nix-env --install</literal>.</para></listitem> <literal>nix-env --install</literal>. This option only works
together with <option>--available</option></para></listitem>
</varlistentry> </varlistentry>

View file

@ -360,7 +360,6 @@ EOF
<arg choice='plain'><option>--print-roots</option></arg> <arg choice='plain'><option>--print-roots</option></arg>
<arg choice='plain'><option>--print-live</option></arg> <arg choice='plain'><option>--print-live</option></arg>
<arg choice='plain'><option>--print-dead</option></arg> <arg choice='plain'><option>--print-dead</option></arg>
<arg choice='plain'><option>--delete</option></arg>
</group> </group>
<arg><option>--max-freed</option> <replaceable>bytes</replaceable></arg> <arg><option>--max-freed</option> <replaceable>bytes</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
@ -407,14 +406,6 @@ the Nix store not reachable via file system references from a set of
</varlistentry> </varlistentry>
<varlistentry><term><option>--delete</option></term>
<listitem><para>This operation performs an actual garbage
collection. All dead paths are removed from the
store. This is the default.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
<para>By default, all unreachable paths are deleted. The following <para>By default, all unreachable paths are deleted. The following
@ -444,10 +435,10 @@ and <link
linkend="conf-keep-derivations"><literal>keep-derivations</literal></link> linkend="conf-keep-derivations"><literal>keep-derivations</literal></link>
variables in the Nix configuration file.</para> variables in the Nix configuration file.</para>
<para>With <option>--delete</option>, the collector prints the total <para>By default, the collector prints the total number of freed bytes
number of freed bytes when it finishes (or when it is interrupted). when it finishes (or when it is interrupted). With
With <option>--print-dead</option>, it prints the number of bytes that <option>--print-dead</option>, it prints the number of bytes that would
would be freed.</para> be freed.</para>
</refsection> </refsection>

View file

@ -6,6 +6,7 @@
#include "symbol-table.hh" #include "symbol-table.hh"
#include "config.hh" #include "config.hh"
#include <regex>
#include <map> #include <map>
#include <optional> #include <optional>
#include <unordered_map> #include <unordered_map>

View file

@ -914,6 +914,8 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
throw UsageError(format("unknown flag '%1%'") % arg); throw UsageError(format("unknown flag '%1%'") % arg);
} }
if (printAttrPath && source != sAvailable)
throw UsageError("--attr-path(-P) only works with --available");
/* Obtain derivation information from the specified source. */ /* Obtain derivation information from the specified source. */
DrvInfos availElems, installedElems; DrvInfos availElems, installedElems;

View file

@ -572,7 +572,6 @@ static void opGC(Strings opFlags, Strings opArgs)
if (*i == "--print-roots") printRoots = true; if (*i == "--print-roots") printRoots = true;
else if (*i == "--print-live") options.action = GCOptions::gcReturnLive; else if (*i == "--print-live") options.action = GCOptions::gcReturnLive;
else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead; else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead;
else if (*i == "--delete") options.action = GCOptions::gcDeleteDead;
else if (*i == "--max-freed") { else if (*i == "--max-freed") {
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true); long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
options.maxFreed = maxFreed >= 0 ? maxFreed : 0; options.maxFreed = maxFreed >= 0 ? maxFreed : 0;

View file

@ -32,6 +32,9 @@ extern "C" {
#include "command.hh" #include "command.hh"
#include "finally.hh" #include "finally.hh"
#define GC_INCLUDE_NEW
#include <gc/gc_cpp.h>
namespace nix { namespace nix {
#define ESC_RED "\033[31m" #define ESC_RED "\033[31m"
@ -42,10 +45,10 @@ namespace nix {
#define ESC_CYA "\033[36m" #define ESC_CYA "\033[36m"
#define ESC_END "\033[0m" #define ESC_END "\033[0m"
struct NixRepl struct NixRepl : gc
{ {
string curDir; string curDir;
EvalState state; std::unique_ptr<EvalState> state;
Bindings * autoArgs; Bindings * autoArgs;
Strings loadedFiles; Strings loadedFiles;
@ -123,8 +126,8 @@ string removeWhitespace(string s)
NixRepl::NixRepl(const Strings & searchPath, nix::ref<Store> store) NixRepl::NixRepl(const Strings & searchPath, nix::ref<Store> store)
: state(searchPath, store) : state(std::make_unique<EvalState>(searchPath, store))
, staticEnv(false, &state.staticBaseEnv) , staticEnv(false, &state->staticBaseEnv)
, historyFile(getDataDir() + "/nix/repl-history") , historyFile(getDataDir() + "/nix/repl-history")
{ {
curDir = absPath("."); curDir = absPath(".");
@ -353,8 +356,8 @@ StringSet NixRepl::completePrefix(string prefix)
Expr * e = parseString(expr); Expr * e = parseString(expr);
Value v; Value v;
e->eval(state, *env, v); e->eval(*state, *env, v);
state.forceAttrs(v); state->forceAttrs(v);
for (auto & i : *v.attrs) { for (auto & i : *v.attrs) {
string name = i.name; string name = i.name;
@ -409,11 +412,11 @@ bool isVarName(const string & s)
Path NixRepl::getDerivationPath(Value & v) { Path NixRepl::getDerivationPath(Value & v) {
auto drvInfo = getDerivation(state, v, false); auto drvInfo = getDerivation(*state, v, false);
if (!drvInfo) if (!drvInfo)
throw Error("expression does not evaluate to a derivation, so I can't build it"); throw Error("expression does not evaluate to a derivation, so I can't build it");
Path drvPath = drvInfo->queryDrvPath(); Path drvPath = drvInfo->queryDrvPath();
if (drvPath == "" || !state.store->isValidPath(state.store->parseStorePath(drvPath))) if (drvPath == "" || !state->store->isValidPath(state->store->parseStorePath(drvPath)))
throw Error("expression did not evaluate to a valid derivation"); throw Error("expression did not evaluate to a valid derivation");
return drvPath; return drvPath;
} }
@ -459,12 +462,12 @@ bool NixRepl::processLine(string line)
} }
else if (command == ":l" || command == ":load") { else if (command == ":l" || command == ":load") {
state.resetFileCache(); state->resetFileCache();
loadFile(arg); loadFile(arg);
} }
else if (command == ":r" || command == ":reload") { else if (command == ":r" || command == ":reload") {
state.resetFileCache(); state->resetFileCache();
reloadFiles(); reloadFiles();
} }
@ -476,13 +479,13 @@ bool NixRepl::processLine(string line)
if (v.type == tPath || v.type == tString) { if (v.type == tPath || v.type == tString) {
PathSet context; PathSet context;
auto filename = state.coerceToString(noPos, v, context); auto filename = state->coerceToString(noPos, v, context);
pos.file = state.symbols.create(filename); pos.file = state->symbols.create(filename);
} else if (v.type == tLambda) { } else if (v.type == tLambda) {
pos = v.lambda.fun->pos; pos = v.lambda.fun->pos;
} else { } else {
// assume it's a derivation // assume it's a derivation
pos = findDerivationFilename(state, v, arg); pos = findDerivationFilename(*state, v, arg);
} }
// Open in EDITOR // Open in EDITOR
@ -492,7 +495,7 @@ bool NixRepl::processLine(string line)
runProgram(editor, args); runProgram(editor, args);
// Reload right after exiting the editor // Reload right after exiting the editor
state.resetFileCache(); state->resetFileCache();
reloadFiles(); reloadFiles();
} }
@ -505,7 +508,7 @@ bool NixRepl::processLine(string line)
Value v, f, result; Value v, f, result;
evalString(arg, v); evalString(arg, v);
evalString("drv: (import <nixpkgs> {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); evalString("drv: (import <nixpkgs> {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f);
state.callFunction(f, v, result, Pos()); state->callFunction(f, v, result, Pos());
Path drvPath = getDerivationPath(result); Path drvPath = getDerivationPath(result);
runProgram(settings.nixBinDir + "/nix-shell", Strings{drvPath}); runProgram(settings.nixBinDir + "/nix-shell", Strings{drvPath});
@ -521,10 +524,10 @@ bool NixRepl::processLine(string line)
but doing it in a child makes it easier to recover from but doing it in a child makes it easier to recover from
problems / SIGINT. */ problems / SIGINT. */
if (runProgram(settings.nixBinDir + "/nix", Strings{"build", "--no-link", drvPath}) == 0) { if (runProgram(settings.nixBinDir + "/nix", Strings{"build", "--no-link", drvPath}) == 0) {
auto drv = readDerivation(*state.store, drvPath); auto drv = readDerivation(*state->store, drvPath);
std::cout << std::endl << "this derivation produced the following outputs:" << std::endl; std::cout << std::endl << "this derivation produced the following outputs:" << std::endl;
for (auto & i : drv.outputs) for (auto & i : drv.outputs)
std::cout << fmt(" %s -> %s\n", i.first, state.store->printStorePath(i.second.path)); std::cout << fmt(" %s -> %s\n", i.first, state->store->printStorePath(i.second.path));
} }
} else if (command == ":i") { } else if (command == ":i") {
runProgram(settings.nixBinDir + "/nix-env", Strings{"-i", drvPath}); runProgram(settings.nixBinDir + "/nix-env", Strings{"-i", drvPath});
@ -554,11 +557,11 @@ bool NixRepl::processLine(string line)
isVarName(name = removeWhitespace(string(line, 0, p)))) isVarName(name = removeWhitespace(string(line, 0, p))))
{ {
Expr * e = parseString(string(line, p + 1)); Expr * e = parseString(string(line, p + 1));
Value & v(*state.allocValue()); Value & v(*state->allocValue());
v.type = tThunk; v.type = tThunk;
v.thunk.env = env; v.thunk.env = env;
v.thunk.expr = e; v.thunk.expr = e;
addVarToScope(state.symbols.create(name), v); addVarToScope(state->symbols.create(name), v);
} else { } else {
Value v; Value v;
evalString(line, v); evalString(line, v);
@ -575,21 +578,21 @@ void NixRepl::loadFile(const Path & path)
loadedFiles.remove(path); loadedFiles.remove(path);
loadedFiles.push_back(path); loadedFiles.push_back(path);
Value v, v2; Value v, v2;
state.evalFile(lookupFileArg(state, path), v); state->evalFile(lookupFileArg(*state, path), v);
state.autoCallFunction(*autoArgs, v, v2); state->autoCallFunction(*autoArgs, v, v2);
addAttrsToScope(v2); addAttrsToScope(v2);
} }
void NixRepl::initEnv() void NixRepl::initEnv()
{ {
env = &state.allocEnv(envSize); env = &state->allocEnv(envSize);
env->up = &state.baseEnv; env->up = &state->baseEnv;
displ = 0; displ = 0;
staticEnv.vars.clear(); staticEnv.vars.clear();
varNames.clear(); varNames.clear();
for (auto & i : state.staticBaseEnv.vars) for (auto & i : state->staticBaseEnv.vars)
varNames.insert(i.first); varNames.insert(i.first);
} }
@ -613,7 +616,7 @@ void NixRepl::reloadFiles()
void NixRepl::addAttrsToScope(Value & attrs) void NixRepl::addAttrsToScope(Value & attrs)
{ {
state.forceAttrs(attrs); state->forceAttrs(attrs);
for (auto & i : *attrs.attrs) for (auto & i : *attrs.attrs)
addVarToScope(i.name, *i.value); addVarToScope(i.name, *i.value);
std::cout << format("Added %1% variables.") % attrs.attrs->size() << std::endl; std::cout << format("Added %1% variables.") % attrs.attrs->size() << std::endl;
@ -632,7 +635,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v)
Expr * NixRepl::parseString(string s) Expr * NixRepl::parseString(string s)
{ {
Expr * e = state.parseExprFromString(s, curDir, staticEnv); Expr * e = state->parseExprFromString(s, curDir, staticEnv);
return e; return e;
} }
@ -640,8 +643,8 @@ Expr * NixRepl::parseString(string s)
void NixRepl::evalString(string s, Value & v) void NixRepl::evalString(string s, Value & v)
{ {
Expr * e = parseString(s); Expr * e = parseString(s);
e->eval(state, *env, v); e->eval(*state, *env, v);
state.forceValue(v); state->forceValue(v);
} }
@ -671,7 +674,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
str.flush(); str.flush();
checkInterrupt(); checkInterrupt();
state.forceValue(v); state->forceValue(v);
switch (v.type) { switch (v.type) {
@ -700,13 +703,13 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
case tAttrs: { case tAttrs: {
seen.insert(&v); seen.insert(&v);
bool isDrv = state.isDerivation(v); bool isDrv = state->isDerivation(v);
if (isDrv) { if (isDrv) {
str << "«derivation "; str << "«derivation ";
Bindings::iterator i = v.attrs->find(state.sDrvPath); Bindings::iterator i = v.attrs->find(state->sDrvPath);
PathSet context; PathSet context;
Path drvPath = i != v.attrs->end() ? state.coerceToPath(*i->pos, *i->value, context) : "???"; Path drvPath = i != v.attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : "???";
str << drvPath << "»"; str << drvPath << "»";
} }
@ -810,7 +813,7 @@ struct CmdRepl : StoreCommand, MixEvalArgs
{ {
evalSettings.pureEval = false; evalSettings.pureEval = false;
auto repl = std::make_unique<NixRepl>(searchPath, openStore()); auto repl = std::make_unique<NixRepl>(searchPath, openStore());
repl->autoArgs = getAutoArgs(repl->state); repl->autoArgs = getAutoArgs(*repl->state);
repl->mainLoop(files); repl->mainLoop(files);
} }
}; };