mirror of
https://github.com/NixOS/nix.git
synced 2025-12-03 23:51:00 +01:00
Tagging release 2.26.2
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEtUHVUwEnDgvPFcpdgXC0cm1xmN4FAmetA5oTHGVkb2xzdHJh QGdtYWlsLmNvbQAKCRCBcLRybXGY3g2pB/9JAFyjmaXuccbMTO/6x9qwsWuuXNLk OQWzfbdUekvsihZZSFZg1r7KqqXHCi64f0nxLPsJ/0oeDWZktJ5KnbV630nuUlDj ulLCpKdvhWFa8dVx9LiziGwQw4KLx8PjOfwThtQ4DqCWxWEmu6lKkijag9cE+ai4 3mw9YtUjBRxlXyhYLzWz3whLbv37c/m+R8iGS8xm8W260pmei6D0beOIPdfXYBQF PzPlPORyI08A06uqyA3z7bTxzmSMnzvu0QInCPCKSHzFUnTZPHUYuYStFl28NrZS fXKK59L0G7QEfdTRAmqQkdHdtPj2RlYFiMN0kQiNLflvKfGGWdi/kvdx =rRix -----END PGP SIGNATURE----- Merge tag '2.26.2' into sync-2.26.2 Tagging release 2.26.2
This commit is contained in:
commit
4055239936
1395 changed files with 24694 additions and 16040 deletions
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include <algorithm>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "command.hh"
|
||||
|
|
@ -9,8 +10,7 @@
|
|||
#include "profiles.hh"
|
||||
#include "repl.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
extern char * * environ __attribute__((weak));
|
||||
#include "environment-variables.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
@ -23,7 +23,8 @@ nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & p
|
|||
if (name.size() == prefix.size() + 1) {
|
||||
bool equal = true;
|
||||
for (size_t i = 0; i < prefix.size(); ++i)
|
||||
if (name[i] != prefix[i]) equal = false;
|
||||
if (name[i] != prefix[i])
|
||||
equal = false;
|
||||
if (equal)
|
||||
res.insert_or_assign(name[prefix.size()], command);
|
||||
}
|
||||
|
|
@ -42,16 +43,16 @@ void NixMultiCommand::run()
|
|||
std::set<std::string> subCommandTextLines;
|
||||
for (auto & [name, _] : commands)
|
||||
subCommandTextLines.insert(fmt("- `%s`", name));
|
||||
std::string markdownError = fmt("`nix %s` requires a sub-command. Available sub-commands:\n\n%s\n",
|
||||
commandName, concatStringsSep("\n", subCommandTextLines));
|
||||
std::string markdownError =
|
||||
fmt("`nix %s` requires a sub-command. Available sub-commands:\n\n%s\n",
|
||||
commandName,
|
||||
concatStringsSep("\n", subCommandTextLines));
|
||||
throw UsageError(renderMarkdownToTerminal(markdownError));
|
||||
}
|
||||
command->second->run();
|
||||
}
|
||||
|
||||
StoreCommand::StoreCommand()
|
||||
{
|
||||
}
|
||||
StoreCommand::StoreCommand() {}
|
||||
|
||||
ref<Store> StoreCommand::getStore()
|
||||
{
|
||||
|
|
@ -126,15 +127,8 @@ ref<Store> EvalCommand::getEvalStore()
|
|||
ref<EvalState> EvalCommand::getEvalState()
|
||||
{
|
||||
if (!evalState) {
|
||||
evalState =
|
||||
#if HAVE_BOEHMGC
|
||||
std::allocate_shared<EvalState>(
|
||||
traceable_allocator<EvalState>(),
|
||||
#else
|
||||
std::make_shared<EvalState>(
|
||||
#endif
|
||||
lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore())
|
||||
;
|
||||
evalState = std::allocate_shared<EvalState>(
|
||||
traceable_allocator<EvalState>(), lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore());
|
||||
|
||||
evalState->repair = repair;
|
||||
|
||||
|
|
@ -149,7 +143,8 @@ MixOperateOnOptions::MixOperateOnOptions()
|
|||
{
|
||||
addFlag({
|
||||
.longName = "derivation",
|
||||
.description = "Operate on the [store derivation](@docroot@/glossary.md#gloss-store-derivation) rather than its outputs.",
|
||||
.description =
|
||||
"Operate on the [store derivation](@docroot@/glossary.md#gloss-store-derivation) rather than its outputs.",
|
||||
.category = installablesCategory,
|
||||
.handler = {&operateOn, OperateOn::Derivation},
|
||||
});
|
||||
|
|
@ -184,30 +179,34 @@ BuiltPathsCommand::BuiltPathsCommand(bool recursive)
|
|||
|
||||
void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
|
||||
{
|
||||
BuiltPaths paths;
|
||||
BuiltPaths rootPaths, allPaths;
|
||||
|
||||
if (all) {
|
||||
if (installables.size())
|
||||
throw UsageError("'--all' does not expect arguments");
|
||||
// XXX: Only uses opaque paths, ignores all the realisations
|
||||
for (auto & p : store->queryAllValidPaths())
|
||||
paths.emplace_back(BuiltPath::Opaque{p});
|
||||
rootPaths.emplace_back(BuiltPath::Opaque{p});
|
||||
allPaths = rootPaths;
|
||||
} else {
|
||||
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
||||
rootPaths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
||||
allPaths = rootPaths;
|
||||
|
||||
if (recursive) {
|
||||
// XXX: This only computes the store path closure, ignoring
|
||||
// intermediate realisations
|
||||
StorePathSet pathsRoots, pathsClosure;
|
||||
for (auto & root : paths) {
|
||||
for (auto & root : rootPaths) {
|
||||
auto rootFromThis = root.outPaths();
|
||||
pathsRoots.insert(rootFromThis.begin(), rootFromThis.end());
|
||||
}
|
||||
store->computeFSClosure(pathsRoots, pathsClosure);
|
||||
for (auto & path : pathsClosure)
|
||||
paths.emplace_back(BuiltPath::Opaque{path});
|
||||
allPaths.emplace_back(BuiltPath::Opaque{path});
|
||||
}
|
||||
}
|
||||
|
||||
run(store, std::move(paths));
|
||||
run(store, std::move(allPaths), std::move(rootPaths));
|
||||
}
|
||||
|
||||
StorePathsCommand::StorePathsCommand(bool recursive)
|
||||
|
|
@ -215,10 +214,10 @@ StorePathsCommand::StorePathsCommand(bool recursive)
|
|||
{
|
||||
}
|
||||
|
||||
void StorePathsCommand::run(ref<Store> store, BuiltPaths && paths)
|
||||
void StorePathsCommand::run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths)
|
||||
{
|
||||
StorePathSet storePaths;
|
||||
for (auto & builtPath : paths)
|
||||
for (auto & builtPath : allPaths)
|
||||
for (auto & p : builtPath.outPaths())
|
||||
storePaths.insert(p);
|
||||
|
||||
|
|
@ -238,46 +237,48 @@ void StorePathCommand::run(ref<Store> store, StorePaths && storePaths)
|
|||
|
||||
MixProfile::MixProfile()
|
||||
{
|
||||
addFlag({
|
||||
.longName = "profile",
|
||||
.description = "The profile to operate on.",
|
||||
.labels = {"path"},
|
||||
.handler = {&profile},
|
||||
.completer = completePath
|
||||
});
|
||||
addFlag(
|
||||
{.longName = "profile",
|
||||
.description = "The profile to operate on.",
|
||||
.labels = {"path"},
|
||||
.handler = {&profile},
|
||||
.completer = completePath});
|
||||
}
|
||||
|
||||
void MixProfile::updateProfile(const StorePath & storePath)
|
||||
{
|
||||
if (!profile) return;
|
||||
auto store = getStore().dynamic_pointer_cast<LocalFSStore>();
|
||||
if (!store) throw Error("'--profile' is not supported for this Nix store");
|
||||
if (!profile)
|
||||
return;
|
||||
auto store = getDstStore().dynamic_pointer_cast<LocalFSStore>();
|
||||
if (!store)
|
||||
throw Error("'--profile' is not supported for this Nix store");
|
||||
auto profile2 = absPath(*profile);
|
||||
switchLink(profile2,
|
||||
createGeneration(*store, profile2, storePath));
|
||||
switchLink(profile2, createGeneration(*store, profile2, storePath));
|
||||
}
|
||||
|
||||
void MixProfile::updateProfile(const BuiltPaths & buildables)
|
||||
{
|
||||
if (!profile) return;
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
StorePaths result;
|
||||
|
||||
for (auto & buildable : buildables) {
|
||||
std::visit(overloaded {
|
||||
[&](const BuiltPath::Opaque & bo) {
|
||||
result.push_back(bo.path);
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const BuiltPath::Opaque & bo) { result.push_back(bo.path); },
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs) {
|
||||
result.push_back(output.second);
|
||||
}
|
||||
},
|
||||
},
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs) {
|
||||
result.push_back(output.second);
|
||||
}
|
||||
},
|
||||
}, buildable.raw());
|
||||
buildable.raw());
|
||||
}
|
||||
|
||||
if (result.size() != 1)
|
||||
throw UsageError("'--profile' requires that the arguments produce a single store path, but there are %d", result.size());
|
||||
throw UsageError(
|
||||
"'--profile' requires that the arguments produce a single store path, but there are %d", result.size());
|
||||
|
||||
updateProfile(result[0]);
|
||||
}
|
||||
|
|
@ -287,50 +288,111 @@ MixDefaultProfile::MixDefaultProfile()
|
|||
profile = getDefaultProfile();
|
||||
}
|
||||
|
||||
MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
|
||||
MixEnvironment::MixEnvironment()
|
||||
: ignoreEnvironment(false)
|
||||
{
|
||||
addFlag({
|
||||
.longName = "ignore-environment",
|
||||
.longName = "ignore-env",
|
||||
.aliases = {"ignore-environment"},
|
||||
.shortName = 'i',
|
||||
.description = "Clear the entire environment (except those specified with `--keep`).",
|
||||
.description = "Clear the entire environment, except for those specified with `--keep-env-var`.",
|
||||
.category = environmentVariablesCategory,
|
||||
.handler = {&ignoreEnvironment, true},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "keep",
|
||||
.longName = "keep-env-var",
|
||||
.aliases = {"keep"},
|
||||
.shortName = 'k',
|
||||
.description = "Keep the environment variable *name*.",
|
||||
.description = "Keep the environment variable *name*, when using `--ignore-env`.",
|
||||
.category = environmentVariablesCategory,
|
||||
.labels = {"name"},
|
||||
.handler = {[&](std::string s) { keep.insert(s); }},
|
||||
.handler = {[&](std::string s) { keepVars.insert(s); }},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "unset",
|
||||
.longName = "unset-env-var",
|
||||
.aliases = {"unset"},
|
||||
.shortName = 'u',
|
||||
.description = "Unset the environment variable *name*.",
|
||||
.category = environmentVariablesCategory,
|
||||
.labels = {"name"},
|
||||
.handler = {[&](std::string s) { unset.insert(s); }},
|
||||
.handler = {[&](std::string name) {
|
||||
if (setVars.contains(name))
|
||||
throw UsageError("Cannot unset environment variable '%s' that is set with '%s'", name, "--set-env-var");
|
||||
|
||||
unsetVars.insert(name);
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "set-env-var",
|
||||
.shortName = 's',
|
||||
.description = "Sets an environment variable *name* with *value*.",
|
||||
.category = environmentVariablesCategory,
|
||||
.labels = {"name", "value"},
|
||||
.handler = {[&](std::string name, std::string value) {
|
||||
if (unsetVars.contains(name))
|
||||
throw UsageError(
|
||||
"Cannot set environment variable '%s' that is unset with '%s'", name, "--unset-env-var");
|
||||
|
||||
if (setVars.contains(name))
|
||||
throw UsageError(
|
||||
"Duplicate definition of environment variable '%s' with '%s' is ambiguous", name, "--set-env-var");
|
||||
|
||||
setVars.insert_or_assign(name, value);
|
||||
}},
|
||||
});
|
||||
}
|
||||
|
||||
void MixEnvironment::setEnviron() {
|
||||
if (ignoreEnvironment) {
|
||||
if (!unset.empty())
|
||||
throw UsageError("--unset does not make sense with --ignore-environment");
|
||||
void MixEnvironment::setEnviron()
|
||||
{
|
||||
if (ignoreEnvironment && !unsetVars.empty())
|
||||
throw UsageError("--unset-env-var does not make sense with --ignore-env");
|
||||
|
||||
for (const auto & var : keep) {
|
||||
auto val = getenv(var.c_str());
|
||||
if (val) stringsEnv.emplace_back(fmt("%s=%s", var.c_str(), val));
|
||||
}
|
||||
if (!ignoreEnvironment && !keepVars.empty())
|
||||
throw UsageError("--keep-env-var does not make sense without --ignore-env");
|
||||
|
||||
vectorEnv = stringsToCharPtrs(stringsEnv);
|
||||
environ = vectorEnv.data();
|
||||
} else {
|
||||
if (!keep.empty())
|
||||
throw UsageError("--keep does not make sense without --ignore-environment");
|
||||
auto env = getEnv();
|
||||
|
||||
for (const auto & var : unset)
|
||||
unsetenv(var.c_str());
|
||||
if (ignoreEnvironment)
|
||||
std::erase_if(env, [&](const auto & var) { return !keepVars.contains(var.first); });
|
||||
|
||||
for (const auto & [name, value] : setVars)
|
||||
env[name] = value;
|
||||
|
||||
if (!unsetVars.empty())
|
||||
std::erase_if(env, [&](const auto & var) { return unsetVars.contains(var.first); });
|
||||
|
||||
replaceEnv(env);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & buildables, LocalFSStore & store)
|
||||
{
|
||||
for (const auto & [_i, buildable] : enumerate(buildables)) {
|
||||
auto i = _i;
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const BuiltPath::Opaque & bo) {
|
||||
auto symlink = outLink;
|
||||
if (i)
|
||||
symlink += fmt("-%d", i);
|
||||
store.addPermRoot(bo.path, absPath(symlink.string()));
|
||||
},
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs) {
|
||||
auto symlink = outLink;
|
||||
if (i)
|
||||
symlink += fmt("-%d", i);
|
||||
if (output.first != "out")
|
||||
symlink += fmt("-%s", output.first);
|
||||
store.addPermRoot(output.second, absPath(symlink.string()));
|
||||
}
|
||||
},
|
||||
},
|
||||
buildable.raw());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,18 +13,20 @@ namespace nix {
|
|||
|
||||
extern std::string programPath;
|
||||
|
||||
extern char * * savedArgv;
|
||||
extern char ** savedArgv;
|
||||
|
||||
class EvalState;
|
||||
struct Pos;
|
||||
class Store;
|
||||
class LocalFSStore;
|
||||
|
||||
static constexpr Command::Category catHelp = -1;
|
||||
static constexpr Command::Category catSecondary = 100;
|
||||
static constexpr Command::Category catUtility = 101;
|
||||
static constexpr Command::Category catNixInstallation = 102;
|
||||
|
||||
static constexpr auto installablesCategory = "Options that change the interpretation of [installables](@docroot@/command-ref/new-cli/nix.md#installables)";
|
||||
static constexpr auto installablesCategory =
|
||||
"Options that change the interpretation of [installables](@docroot@/command-ref/new-cli/nix.md#installables)";
|
||||
|
||||
struct NixMultiCommand : MultiCommand, virtual Command
|
||||
{
|
||||
|
|
@ -45,7 +47,20 @@ struct StoreCommand : virtual Command
|
|||
{
|
||||
StoreCommand();
|
||||
void run() override;
|
||||
|
||||
/**
|
||||
* Return the default Nix store.
|
||||
*/
|
||||
ref<Store> getStore();
|
||||
|
||||
/**
|
||||
* Return the destination Nix store.
|
||||
*/
|
||||
virtual ref<Store> getDstStore()
|
||||
{
|
||||
return getStore();
|
||||
}
|
||||
|
||||
virtual ref<Store> createStore();
|
||||
/**
|
||||
* Main entry point, with a `Store` provided
|
||||
|
|
@ -68,7 +83,7 @@ struct CopyCommand : virtual StoreCommand
|
|||
|
||||
ref<Store> createStore() override;
|
||||
|
||||
ref<Store> getDstStore();
|
||||
ref<Store> getDstStore() override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -112,7 +127,9 @@ struct MixFlakeOptions : virtual Args, EvalCommand
|
|||
* arguments) so that the completions for these flags can use them.
|
||||
*/
|
||||
virtual std::vector<FlakeRef> getFlakeRefsForCompletion()
|
||||
{ return {}; }
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||
|
|
@ -122,11 +139,9 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
|
|||
|
||||
SourceExprCommand();
|
||||
|
||||
Installables parseInstallables(
|
||||
ref<Store> store, std::vector<std::string> ss);
|
||||
Installables parseInstallables(ref<Store> store, std::vector<std::string> ss);
|
||||
|
||||
ref<Installable> parseInstallable(
|
||||
ref<Store> store, const std::string & installable);
|
||||
ref<Installable> parseInstallable(ref<Store> store, const std::string & installable);
|
||||
|
||||
virtual Strings getDefaultFlakeAttrPaths();
|
||||
|
||||
|
|
@ -238,7 +253,7 @@ public:
|
|||
|
||||
BuiltPathsCommand(bool recursive = false);
|
||||
|
||||
virtual void run(ref<Store> store, BuiltPaths && paths) = 0;
|
||||
virtual void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) = 0;
|
||||
|
||||
void run(ref<Store> store, Installables && installables) override;
|
||||
|
||||
|
|
@ -251,7 +266,7 @@ struct StorePathsCommand : public BuiltPathsCommand
|
|||
|
||||
virtual void run(ref<Store> store, StorePaths && storePaths) = 0;
|
||||
|
||||
void run(ref<Store> store, BuiltPaths && paths) override;
|
||||
void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -272,10 +287,10 @@ struct RegisterCommand
|
|||
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
||||
static Commands * commands;
|
||||
|
||||
RegisterCommand(std::vector<std::string> && name,
|
||||
std::function<ref<Command>()> command)
|
||||
RegisterCommand(std::vector<std::string> && name, std::function<ref<Command>()> command)
|
||||
{
|
||||
if (!commands) commands = new Commands;
|
||||
if (!commands)
|
||||
commands = new Commands;
|
||||
commands->emplace(name, command);
|
||||
}
|
||||
|
||||
|
|
@ -285,13 +300,13 @@ struct RegisterCommand
|
|||
template<class T>
|
||||
static RegisterCommand registerCommand(const std::string & name)
|
||||
{
|
||||
return RegisterCommand({name}, [](){ return make_ref<T>(); });
|
||||
return RegisterCommand({name}, []() { return make_ref<T>(); });
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
||||
{
|
||||
return RegisterCommand(std::move(name), [](){ return make_ref<T>(); });
|
||||
return RegisterCommand(std::move(name), []() { return make_ref<T>(); });
|
||||
}
|
||||
|
||||
struct MixProfile : virtual StoreCommand
|
||||
|
|
@ -313,19 +328,21 @@ struct MixDefaultProfile : MixProfile
|
|||
MixDefaultProfile();
|
||||
};
|
||||
|
||||
struct MixEnvironment : virtual Args {
|
||||
struct MixEnvironment : virtual Args
|
||||
{
|
||||
|
||||
StringSet keep, unset;
|
||||
Strings stringsEnv;
|
||||
std::vector<char*> vectorEnv;
|
||||
StringSet keepVars;
|
||||
StringSet unsetVars;
|
||||
std::map<std::string, std::string> setVars;
|
||||
bool ignoreEnvironment;
|
||||
|
||||
MixEnvironment();
|
||||
|
||||
/***
|
||||
* Modify global environ based on `ignoreEnvironment`, `keep`, and
|
||||
* `unset`. It's expected that exec will be called before this class
|
||||
* goes out of scope, otherwise `environ` will become invalid.
|
||||
* Modify global environ based on `ignoreEnvironment`, `keep`,
|
||||
* `unset`, and `added`. It's expected that exec will be called
|
||||
* before this class goes out of scope, otherwise `environ` will
|
||||
* become invalid.
|
||||
*/
|
||||
void setEnviron();
|
||||
};
|
||||
|
|
@ -349,9 +366,12 @@ void completeFlakeRefWithFragment(
|
|||
std::string showVersions(const std::set<std::string> & versions);
|
||||
|
||||
void printClosureDiff(
|
||||
ref<Store> store,
|
||||
const StorePath & beforePath,
|
||||
const StorePath & afterPath,
|
||||
std::string_view indent);
|
||||
ref<Store> store, const StorePath & beforePath, const StorePath & afterPath, std::string_view indent);
|
||||
|
||||
/**
|
||||
* Create symlinks prefixed by `outLink` to the store paths in
|
||||
* `buildables`.
|
||||
*/
|
||||
void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & buildables, LocalFSStore & store);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
namespace fs { using namespace std::filesystem; }
|
||||
|
||||
fetchers::Settings fetchSettings;
|
||||
|
||||
static GlobalConfig::Register rFetchSettings(&fetchSettings);
|
||||
|
|
@ -27,12 +29,12 @@ EvalSettings evalSettings {
|
|||
{
|
||||
{
|
||||
"flake",
|
||||
[](ref<Store> store, std::string_view rest) {
|
||||
[](EvalState & state, std::string_view rest) {
|
||||
// FIXME `parseFlakeRef` should take a `std::string_view`.
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
|
||||
debug("fetching flake search path element '%s''", rest);
|
||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
|
||||
return store->toRealPath(storePath);
|
||||
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first;
|
||||
return state.rootPath(state.store->toRealPath(storePath));
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -118,8 +120,8 @@ MixEvalArgs::MixEvalArgs()
|
|||
.category = category,
|
||||
.labels = {"original-ref", "resolved-ref"},
|
||||
.handler = {[&](std::string _from, std::string _to) {
|
||||
auto from = parseFlakeRef(fetchSettings, _from, absPath("."));
|
||||
auto to = parseFlakeRef(fetchSettings, _to, absPath("."));
|
||||
auto from = parseFlakeRef(fetchSettings, _from, fs::current_path().string());
|
||||
auto to = parseFlakeRef(fetchSettings, _to, fs::current_path().string());
|
||||
fetchers::Attrs extraAttrs;
|
||||
if (to.subdir != "") extraAttrs["dir"] = to.subdir;
|
||||
fetchers::overrideRegistry(from.input, to.input, extraAttrs);
|
||||
|
|
|
|||
|
|
@ -32,16 +32,6 @@ InstallableDerivedPath InstallableDerivedPath::parse(
|
|||
// store path.
|
||||
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
||||
auto storePath = store->followLinksToStorePath(prefix);
|
||||
// Remove this prior to stabilizing the new CLI.
|
||||
if (storePath.isDerivation()) {
|
||||
auto oldDerivedPath = DerivedPath::Built {
|
||||
.drvPath = makeConstantStorePathRef(storePath),
|
||||
.outputs = OutputsSpec::All { },
|
||||
};
|
||||
warn(
|
||||
"The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'",
|
||||
oldDerivedPath.to_string(*store));
|
||||
};
|
||||
return DerivedPath::Opaque {
|
||||
.path = std::move(storePath),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -104,12 +104,12 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
|||
|
||||
auto drvPath = attr->forceDerivation();
|
||||
|
||||
std::optional<NixInt> priority;
|
||||
std::optional<NixInt::Inner> priority;
|
||||
|
||||
if (attr->maybeGetAttr(state->sOutputSpecified)) {
|
||||
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
|
||||
if (auto aPriority = aMeta->maybeGetAttr("priority"))
|
||||
priority = aPriority->getInt();
|
||||
priority = aPriority->getInt().value;
|
||||
}
|
||||
|
||||
return {{
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
|
|||
Flake flake;
|
||||
|
||||
ExtraPathInfoFlake(Value && v, Flake && f)
|
||||
: ExtraPathInfoValue(std::move(v)), flake(f)
|
||||
: ExtraPathInfoValue(std::move(v)), flake(std::move(f))
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ struct ExtraPathInfoValue : ExtraPathInfo
|
|||
/**
|
||||
* An optional priority for use with "build envs". See Package
|
||||
*/
|
||||
std::optional<NixInt> priority;
|
||||
std::optional<NixInt::Inner> priority;
|
||||
|
||||
/**
|
||||
* The attribute path associated with this value. The idea is
|
||||
|
|
@ -59,7 +59,7 @@ struct ExtraPathInfoValue : ExtraPathInfo
|
|||
Value value;
|
||||
|
||||
ExtraPathInfoValue(Value && v)
|
||||
: value(v)
|
||||
: value(std::move(v))
|
||||
{ }
|
||||
|
||||
virtual ~ExtraPathInfoValue() = default;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
namespace fs { using namespace std::filesystem; }
|
||||
|
||||
void completeFlakeInputPath(
|
||||
AddCompletions & completions,
|
||||
ref<EvalState> evalState,
|
||||
|
|
@ -86,7 +88,7 @@ MixFlakeOptions::MixFlakeOptions()
|
|||
|
||||
> **DEPRECATED**
|
||||
>
|
||||
> Use [`--no-use-registries`](#opt-no-use-registries) instead.
|
||||
> Use [`--no-use-registries`](@docroot@/command-ref/conf-file.md#conf-use-registries) instead.
|
||||
)",
|
||||
.category = category,
|
||||
.handler = {[&]() {
|
||||
|
|
@ -341,7 +343,7 @@ void completeFlakeRefWithFragment(
|
|||
auto flakeRefS = std::string(prefix.substr(0, hash));
|
||||
|
||||
// TODO: ideally this would use the command base directory instead of assuming ".".
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), absPath("."));
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), fs::current_path().string());
|
||||
|
||||
auto evalCache = openEvalCache(*evalState,
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(
|
||||
|
|
@ -445,7 +447,7 @@ ref<eval_cache::EvalCache> openEvalCache(
|
|||
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
||||
{
|
||||
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
||||
? lockedFlake->getFingerprint(state.store)
|
||||
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
|
||||
: std::nullopt;
|
||||
auto rootLoader = [&state, lockedFlake]()
|
||||
{
|
||||
|
|
@ -852,7 +854,8 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
|
|||
{
|
||||
applyDefaultInstallables(rawInstallables);
|
||||
std::vector<FlakeRef> res;
|
||||
for (auto i : rawInstallables)
|
||||
res.reserve(rawInstallables.size());
|
||||
for (const auto & i : rawInstallables)
|
||||
res.push_back(parseFlakeRefWithFragment(
|
||||
fetchSettings,
|
||||
expandTilde(i),
|
||||
|
|
@ -912,4 +915,12 @@ void BuiltPathsCommand::applyDefaultInstallables(std::vector<std::string> & rawI
|
|||
rawInstallables.push_back(".");
|
||||
}
|
||||
|
||||
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult)
|
||||
{
|
||||
BuiltPaths res;
|
||||
for (auto & i : builtPathsWithResult)
|
||||
res.push_back(i.path);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ struct BuiltPathWithResult
|
|||
std::optional<BuildResult> result;
|
||||
};
|
||||
|
||||
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult);
|
||||
|
||||
/**
|
||||
* Shorthand, for less typing and helping us keep the choice of
|
||||
* collection in sync.
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
libraries += libcmd
|
||||
|
||||
libcmd_NAME = libnixcmd
|
||||
|
||||
libcmd_DIR := $(d)
|
||||
|
||||
libcmd_SOURCES := $(wildcard $(d)/*.cc)
|
||||
|
||||
libcmd_CXXFLAGS += $(INCLUDE_libutil) $(INCLUDE_libstore) $(INCLUDE_libfetchers) $(INCLUDE_libexpr) $(INCLUDE_libflake) $(INCLUDE_libmain)
|
||||
|
||||
libcmd_LDFLAGS = $(EDITLINE_LIBS) $(LOWDOWN_LIBS) $(THREAD_LDFLAGS)
|
||||
|
||||
libcmd_LIBS = libutil libstore libfetchers libflake libexpr libmain
|
||||
|
||||
$(eval $(call install-file-in, $(buildprefix)$(d)/nix-cmd.pc, $(libdir)/pkgconfig, 0644))
|
||||
|
|
@ -16,13 +16,25 @@ static std::string doRenderMarkdownToTerminal(std::string_view markdown)
|
|||
{
|
||||
int windowWidth = getWindowSize().second;
|
||||
|
||||
struct lowdown_opts opts
|
||||
{
|
||||
.type = LOWDOWN_TERM,
|
||||
.maxdepth = 20,
|
||||
#if HAVE_LOWDOWN_1_4
|
||||
struct lowdown_opts_term opts_term {
|
||||
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||
.hmargin = 0,
|
||||
.vmargin = 0,
|
||||
};
|
||||
#endif
|
||||
struct lowdown_opts opts
|
||||
{
|
||||
.type = LOWDOWN_TERM,
|
||||
#if HAVE_LOWDOWN_1_4
|
||||
.term = opts_term,
|
||||
#endif
|
||||
.maxdepth = 20,
|
||||
#if !HAVE_LOWDOWN_1_4
|
||||
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||
.hmargin = 0,
|
||||
.vmargin = 0,
|
||||
#endif
|
||||
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
|
||||
.oflags = LOWDOWN_TERM_NOLINK,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ project('nix-cmd', 'cpp',
|
|||
'cpp_std=c++2a',
|
||||
# TODO(Qyriad): increase the warning level
|
||||
'warning_level=1',
|
||||
'debug=true',
|
||||
'optimization=2',
|
||||
'errorlogs=true', # Please print logs for tests that fail
|
||||
],
|
||||
meson_version : '>= 1.1',
|
||||
|
|
@ -14,7 +12,7 @@ project('nix-cmd', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
|
@ -28,9 +26,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-flake'),
|
||||
dependency('nix-main'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||
deps_public += nlohmann_json
|
||||
|
|
@ -38,6 +34,8 @@ deps_public += nlohmann_json
|
|||
lowdown = dependency('lowdown', version : '>= 0.9.0', required : get_option('markdown'))
|
||||
deps_private += lowdown
|
||||
configdata.set('HAVE_LOWDOWN', lowdown.found().to_int())
|
||||
# The API changed slightly around terminal initialization.
|
||||
configdata.set('HAVE_LOWDOWN_1_4', lowdown.version().version_compare('>= 1.4.0').to_int())
|
||||
|
||||
readline_flavor = get_option('readline-flavor')
|
||||
if readline_flavor == 'editline'
|
||||
|
|
@ -72,7 +70,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'built-path.cc',
|
||||
|
|
@ -127,4 +125,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
prefix=@prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Nix
|
||||
Description: Nix Package Manager
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -lnixcmd
|
||||
Cflags: -I${includedir}/nix -std=c++2a
|
||||
1
src/libcmd/nix-meson-build-support
Symbolic link
1
src/libcmd/nix-meson-build-support
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
||||
|
|
@ -1,51 +1,47 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
nix-util,
|
||||
nix-store,
|
||||
nix-fetchers,
|
||||
nix-expr,
|
||||
nix-flake,
|
||||
nix-main,
|
||||
editline,
|
||||
readline,
|
||||
lowdown,
|
||||
nlohmann_json,
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
, nix-fetchers
|
||||
, nix-expr
|
||||
, nix-flake
|
||||
, nix-main
|
||||
, editline
|
||||
, readline
|
||||
, lowdown
|
||||
, nlohmann_json
|
||||
# Configuration Options
|
||||
|
||||
# Configuration Options
|
||||
version,
|
||||
|
||||
, version
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
enableMarkdown ? !stdenv.hostPlatform.isWindows,
|
||||
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
, enableMarkdown ? !stdenv.hostPlatform.isWindows
|
||||
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
, readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline"
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline",
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
mkMesonLibrary (finalAttrs: {
|
||||
pname = "nix-cmd";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
@ -54,14 +50,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
({ inherit editline readline; }.${readlineFlavor})
|
||||
] ++ lib.optional enableMarkdown lowdown;
|
||||
|
|
@ -89,14 +77,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(lib.mesonOption "readline-flavor" readlineFlavor)
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "error.hh"
|
||||
#include "repl-interacter.hh"
|
||||
#include "repl.hh"
|
||||
|
||||
#include "ansicolor.hh"
|
||||
#include "shared.hh"
|
||||
#include "config-global.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "attr-path.hh"
|
||||
|
|
@ -29,11 +29,6 @@
|
|||
#include "ref.hh"
|
||||
#include "value.hh"
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
#define GC_INCLUDE_NEW
|
||||
#include <gc/gc_cpp.h>
|
||||
#endif
|
||||
|
||||
#include "strings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
@ -62,9 +57,7 @@ enum class ProcessLineResult {
|
|||
struct NixRepl
|
||||
: AbstractNixRepl
|
||||
, detail::ReplCompleterMixin
|
||||
#if HAVE_BOEHMGC
|
||||
, gc
|
||||
#endif
|
||||
{
|
||||
size_t debugTraceIndex;
|
||||
|
||||
|
|
@ -77,10 +70,14 @@ struct NixRepl
|
|||
int displ;
|
||||
StringSet varNames;
|
||||
|
||||
RunNix * runNixPtr;
|
||||
|
||||
void runNix(Path program, const Strings & args, const std::optional<std::string> & input = {});
|
||||
|
||||
std::unique_ptr<ReplInteracter> interacter;
|
||||
|
||||
NixRepl(const LookupPath & lookupPath, nix::ref<Store> store,ref<EvalState> state,
|
||||
std::function<AnnotatedValues()> getValues);
|
||||
std::function<AnnotatedValues()> getValues, RunNix * runNix);
|
||||
virtual ~NixRepl() = default;
|
||||
|
||||
ReplExitStatus mainLoop() override;
|
||||
|
|
@ -125,32 +122,16 @@ std::string removeWhitespace(std::string s)
|
|||
|
||||
|
||||
NixRepl::NixRepl(const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||
std::function<NixRepl::AnnotatedValues()> getValues)
|
||||
std::function<NixRepl::AnnotatedValues()> getValues, RunNix * runNix = nullptr)
|
||||
: AbstractNixRepl(state)
|
||||
, debugTraceIndex(0)
|
||||
, getValues(getValues)
|
||||
, staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get()))
|
||||
, interacter(make_unique<ReadlineLikeInteracter>(getDataDir() + "/nix/repl-history"))
|
||||
, runNixPtr{runNix}
|
||||
, interacter(make_unique<ReadlineLikeInteracter>(getDataDir() + "/repl-history"))
|
||||
{
|
||||
}
|
||||
|
||||
void runNix(Path program, const Strings & args,
|
||||
const std::optional<std::string> & input = {})
|
||||
{
|
||||
auto subprocessEnv = getEnv();
|
||||
subprocessEnv["NIX_CONFIG"] = globalConfig.toKeyValue();
|
||||
//isInteractive avoid grabling interactive commands
|
||||
runProgram2(RunOptions {
|
||||
.program = settings.nixBinDir+ "/" + program,
|
||||
.args = args,
|
||||
.environment = subprocessEnv,
|
||||
.input = input,
|
||||
.isInteractive = true,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positions, const DebugTrace & dt)
|
||||
{
|
||||
if (dt.isError)
|
||||
|
|
@ -635,7 +616,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
// When missing, trigger the normal exception
|
||||
// e.g. :doc builtins.foo
|
||||
// behaves like
|
||||
// nix-repl> builtins.foo
|
||||
// nix-repl> builtins.foo<tab>
|
||||
// error: attribute 'foo' missing
|
||||
evalString(arg, v);
|
||||
assert(false);
|
||||
|
|
@ -664,7 +645,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
|
||||
logger->cout(trim(renderMarkdownToTerminal(markdown)));
|
||||
} else if (fallbackPos) {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << "Attribute `" << fallbackName << "`\n\n";
|
||||
ss << " … defined at " << state->positions[fallbackPos] << "\n\n";
|
||||
if (fallbackDoc) {
|
||||
|
|
@ -673,7 +654,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
ss << "No documentation found.\n\n";
|
||||
}
|
||||
|
||||
auto markdown = ss.str();
|
||||
auto markdown = toView(ss);
|
||||
logger->cout(trim(renderMarkdownToTerminal(markdown)));
|
||||
|
||||
} else
|
||||
|
|
@ -733,7 +714,14 @@ void NixRepl::loadFlake(const std::string & flakeRefS)
|
|||
if (flakeRefS.empty())
|
||||
throw Error("cannot use ':load-flake' without a path specified. (Use '.' for the current working directory.)");
|
||||
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, flakeRefS, absPath("."), true);
|
||||
std::filesystem::path cwd;
|
||||
try {
|
||||
cwd = std::filesystem::current_path();
|
||||
} catch (std::filesystem::filesystem_error & e) {
|
||||
throw SysError("cannot determine current working directory");
|
||||
}
|
||||
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, flakeRefS, cwd.string(), true);
|
||||
if (evalSettings.pureEval && !flakeRef.input.isLocked())
|
||||
throw Error("cannot use ':load-flake' on locked flake reference '%s' (use --impure to override)", flakeRefS);
|
||||
|
||||
|
|
@ -833,9 +821,18 @@ void NixRepl::evalString(std::string s, Value & v)
|
|||
}
|
||||
|
||||
|
||||
void NixRepl::runNix(Path program, const Strings & args, const std::optional<std::string> & input)
|
||||
{
|
||||
if (runNixPtr)
|
||||
(*runNixPtr)(program, args, input);
|
||||
else
|
||||
throw Error("Cannot run '%s' because no method of calling the Nix CLI was provided. This is a configuration problem pertaining to how this program was built. See Nix 2.25 release notes", program);
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create(
|
||||
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||
std::function<AnnotatedValues()> getValues)
|
||||
std::function<AnnotatedValues()> getValues, RunNix * runNix)
|
||||
{
|
||||
return std::make_unique<NixRepl>(
|
||||
lookupPath,
|
||||
|
|
|
|||
|
|
@ -19,9 +19,19 @@ struct AbstractNixRepl
|
|||
|
||||
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
|
||||
|
||||
using RunNix = void(Path program, const Strings & args, const std::optional<std::string> & input);
|
||||
|
||||
/**
|
||||
* @param runNix Function to run the nix CLI to support various
|
||||
* `:<something>` commands. Optional; if not provided,
|
||||
* everything else will still work fine, but those commands won't.
|
||||
*/
|
||||
static std::unique_ptr<AbstractNixRepl> create(
|
||||
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||
std::function<AnnotatedValues()> getValues);
|
||||
const LookupPath & lookupPath,
|
||||
nix::ref<Store> store,
|
||||
ref<EvalState> state,
|
||||
std::function<AnnotatedValues()> getValues,
|
||||
RunNix * runNix = nullptr);
|
||||
|
||||
static ReplExitStatus runSimple(
|
||||
ref<EvalState> evalState,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue