1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-10 20:46:01 +01:00

Apply clang-format universally.

* It is tough to contribute to a project that doesn't use a formatter,
* It is extra hard to contribute to a project which has configured the formatter, but ignores it for some files
* Code formatting makes it harder to hide obscure / weird bugs by accident or on purpose,

Let's rip the bandaid off?

Note that PRs currently in flight should be able to be merged relatively easily by applying `clang-format` to their tip prior to merge.
This commit is contained in:
Graham Christensen 2025-07-18 12:47:27 -04:00
parent 41bf87ec70
commit e4f62e4608
587 changed files with 23258 additions and 23135 deletions

View file

@ -10,23 +10,13 @@
namespace nix {
// Custom implementation to avoid `ref` ptr equality
GENERATE_CMP_EXT(
,
std::strong_ordering,
SingleBuiltPathBuilt,
*me->drvPath,
me->output);
GENERATE_CMP_EXT(, std::strong_ordering, SingleBuiltPathBuilt, *me->drvPath, me->output);
// Custom implementation to avoid `ref` ptr equality
// TODO no `GENERATE_CMP_EXT` because no `std::set::operator<=>` on
// Darwin, per header.
GENERATE_EQUAL(
,
BuiltPathBuilt ::,
BuiltPathBuilt,
*me->drvPath,
me->outputs);
GENERATE_EQUAL(, BuiltPathBuilt ::, BuiltPathBuilt, *me->drvPath, me->outputs);
StorePath SingleBuiltPath::outPath() const
{
@ -34,8 +24,8 @@ StorePath SingleBuiltPath::outPath() const
overloaded{
[](const SingleBuiltPath::Opaque & p) { return p.path; },
[](const SingleBuiltPath::Built & b) { return b.output.second; },
}, raw()
);
},
raw());
}
StorePathSet BuiltPath::outPaths() const
@ -49,13 +39,13 @@ StorePathSet BuiltPath::outPaths() const
res.insert(path);
return res;
},
}, raw()
);
},
raw());
}
SingleDerivedPath::Built SingleBuiltPath::Built::discardOutputPath() const
{
return SingleDerivedPath::Built {
return SingleDerivedPath::Built{
.drvPath = make_ref<SingleDerivedPath>(drvPath->discardOutputPath()),
.output = output.first,
};
@ -65,14 +55,10 @@ SingleDerivedPath SingleBuiltPath::discardOutputPath() const
{
return std::visit(
overloaded{
[](const SingleBuiltPath::Opaque & p) -> SingleDerivedPath {
return p;
},
[](const SingleBuiltPath::Built & b) -> SingleDerivedPath {
return b.discardOutputPath();
},
}, raw()
);
[](const SingleBuiltPath::Opaque & p) -> SingleDerivedPath { return p; },
[](const SingleBuiltPath::Built & b) -> SingleDerivedPath { return b.discardOutputPath(); },
},
raw());
}
nlohmann::json BuiltPath::Built::toJSON(const StoreDirConfig & store) const
@ -97,16 +83,12 @@ nlohmann::json SingleBuiltPath::Built::toJSON(const StoreDirConfig & store) cons
nlohmann::json SingleBuiltPath::toJSON(const StoreDirConfig & store) const
{
return std::visit([&](const auto & buildable) {
return buildable.toJSON(store);
}, raw());
return std::visit([&](const auto & buildable) { return buildable.toJSON(store); }, raw());
}
nlohmann::json BuiltPath::toJSON(const StoreDirConfig & store) const
{
return std::visit([&](const auto & buildable) {
return buildable.toJSON(store);
}, raw());
return std::visit([&](const auto & buildable) { return buildable.toJSON(store); }, raw());
}
RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
@ -116,20 +98,18 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
overloaded{
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
[&](const BuiltPath::Built & p) {
auto drvHashes =
staticOutputHashes(store, store.readDerivation(p.drvPath->outPath()));
for (auto& [outputName, outputPath] : p.outputs) {
if (experimentalFeatureSettings.isEnabled(
Xp::CaDerivations)) {
auto drvHashes = staticOutputHashes(store, store.readDerivation(p.drvPath->outPath()));
for (auto & [outputName, outputPath] : p.outputs) {
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
auto drvOutput = get(drvHashes, outputName);
if (!drvOutput)
throw Error(
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
store.printStorePath(p.drvPath->outPath()), outputName);
auto thisRealisation = store.queryRealisation(
DrvOutput{*drvOutput, outputName});
assert(thisRealisation); // Weve built it, so we must
// have the realisation
store.printStorePath(p.drvPath->outPath()),
outputName);
auto thisRealisation = store.queryRealisation(DrvOutput{*drvOutput, outputName});
assert(thisRealisation); // Weve built it, so we must
// have the realisation
res.insert(*thisRealisation);
} else {
res.insert(outputPath);
@ -141,4 +121,4 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
return res;
}
}
} // namespace nix

View file

@ -8,4 +8,4 @@ void InstallableValueCommand::run(ref<Store> store, ref<Installable> installable
run(store, installableValue);
}
}
} // namespace nix

View file

@ -402,4 +402,4 @@ void MixOutLinkBase::createOutLinksMaybe(const std::vector<BuiltPathWithResult>
createOutLinks(outLink, toBuiltPaths(buildables), *store2);
}
}
} // namespace nix

View file

@ -18,12 +18,11 @@
namespace nix {
fetchers::Settings fetchSettings;
static GlobalConfig::Register rFetchSettings(&fetchSettings);
EvalSettings evalSettings {
EvalSettings evalSettings{
settings.readOnlyMode,
{
{
@ -31,7 +30,7 @@ EvalSettings evalSettings {
[](EvalState & state, std::string_view rest) {
experimentalFeatureSettings.require(Xp::Flakes);
// FIXME `parseFlakeRef` should take a `std::string_view`.
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
auto flakeRef = parseFlakeRef(fetchSettings, std::string{rest}, {}, true, false);
debug("fetching flake search path element '%s''", rest);
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
auto storePath = nix::fetchToStore(
@ -49,17 +48,14 @@ EvalSettings evalSettings {
static GlobalConfig::Register rEvalSettings(&evalSettings);
flake::Settings flakeSettings;
static GlobalConfig::Register rFlakeSettings(&flakeSettings);
CompatibilitySettings compatibilitySettings {};
CompatibilitySettings compatibilitySettings{};
static GlobalConfig::Register rCompatibilitySettings(&compatibilitySettings);
MixEvalArgs::MixEvalArgs()
{
addFlag({
@ -67,7 +63,9 @@ MixEvalArgs::MixEvalArgs()
.description = "Pass the value *expr* as the argument *name* to Nix functions.",
.category = category,
.labels = {"name", "expr"},
.handler = {[&](std::string name, std::string expr) { autoArgs.insert_or_assign(name, AutoArg{AutoArgExpr{expr}}); }},
.handler = {[&](std::string name, std::string expr) {
autoArgs.insert_or_assign(name, AutoArg{AutoArgExpr{expr}});
}},
});
addFlag({
@ -75,7 +73,9 @@ MixEvalArgs::MixEvalArgs()
.description = "Pass the string *string* as the argument *name* to Nix functions.",
.category = category,
.labels = {"name", "string"},
.handler = {[&](std::string name, std::string s) { autoArgs.insert_or_assign(name, AutoArg{AutoArgString{s}}); }},
.handler = {[&](std::string name, std::string s) {
autoArgs.insert_or_assign(name, AutoArg{AutoArgString{s}});
}},
});
addFlag({
@ -83,7 +83,9 @@ MixEvalArgs::MixEvalArgs()
.description = "Pass the contents of file *path* as the argument *name* to Nix functions.",
.category = category,
.labels = {"name", "path"},
.handler = {[&](std::string name, std::string path) { autoArgs.insert_or_assign(name, AutoArg{AutoArgFile{path}}); }},
.handler = {[&](std::string name, std::string path) {
autoArgs.insert_or_assign(name, AutoArg{AutoArgFile{path}});
}},
.completer = completePath,
});
@ -107,18 +109,14 @@ MixEvalArgs::MixEvalArgs()
)",
.category = category,
.labels = {"path"},
.handler = {[&](std::string s) {
lookupPath.elements.emplace_back(LookupPath::Elem::parse(s));
}},
.handler = {[&](std::string s) { lookupPath.elements.emplace_back(LookupPath::Elem::parse(s)); }},
});
addFlag({
.longName = "impure",
.description = "Allow access to mutable paths and repositories.",
.category = category,
.handler = {[&]() {
evalSettings.pureEval = false;
}},
.handler = {[&]() { evalSettings.pureEval = false; }},
});
addFlag({
@ -130,7 +128,8 @@ MixEvalArgs::MixEvalArgs()
auto from = parseFlakeRef(fetchSettings, _from, std::filesystem::current_path().string());
auto to = parseFlakeRef(fetchSettings, _to, std::filesystem::current_path().string());
fetchers::Attrs extraAttrs;
if (to.subdir != "") extraAttrs["dir"] = to.subdir;
if (to.subdir != "")
extraAttrs["dir"] = to.subdir;
fetchers::overrideRegistry(from.input, to.input, extraAttrs);
}},
.completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
@ -141,7 +140,7 @@ MixEvalArgs::MixEvalArgs()
addFlag({
.longName = "eval-store",
.description =
R"(
R"(
The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format)
to use for evaluation, i.e. to store derivations (`.drv` files) and inputs referenced by them.
)",
@ -156,20 +155,21 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
auto res = state.buildBindings(autoArgs.size());
for (auto & [name, arg] : autoArgs) {
auto v = state.allocValue();
std::visit(overloaded {
[&](const AutoArgExpr & arg) {
state.mkThunk_(*v, state.parseExprFromString(arg.expr, compatibilitySettings.nixShellShebangArgumentsRelativeToScript ? state.rootPath(absPath(getCommandBaseDir())) : state.rootPath(".")));
},
[&](const AutoArgString & arg) {
v->mkString(arg.s);
},
[&](const AutoArgFile & arg) {
v->mkString(readFile(arg.path.string()));
},
[&](const AutoArgStdin & arg) {
v->mkString(readFile(STDIN_FILENO));
}
}, arg);
std::visit(
overloaded{
[&](const AutoArgExpr & arg) {
state.mkThunk_(
*v,
state.parseExprFromString(
arg.expr,
compatibilitySettings.nixShellShebangArgumentsRelativeToScript
? state.rootPath(absPath(getCommandBaseDir()))
: state.rootPath(".")));
},
[&](const AutoArgString & arg) { v->mkString(arg.s); },
[&](const AutoArgFile & arg) { v->mkString(readFile(arg.path.string())); },
[&](const AutoArgStdin & arg) { v->mkString(readFile(STDIN_FILENO)); }},
arg);
res.insert(state.symbols.create(name), v);
}
return res.finish();
@ -178,15 +178,8 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir)
{
if (EvalSettings::isPseudoUrl(s)) {
auto accessor = fetchers::downloadTarball(
state.store,
state.fetchSettings,
EvalSettings::resolvePseudoUrl(s));
auto storePath = fetchToStore(
state.fetchSettings,
*state.store,
SourcePath(accessor),
FetchMode::Copy);
auto accessor = fetchers::downloadTarball(state.store, state.fetchSettings, EvalSettings::resolvePseudoUrl(s));
auto storePath = fetchToStore(state.fetchSettings, *state.store, SourcePath(accessor), FetchMode::Copy);
return state.storePath(storePath);
}
@ -195,11 +188,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
auto flakeRef = parseFlakeRef(fetchSettings, std::string(s.substr(6)), {}, true, false);
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
auto storePath = nix::fetchToStore(
state.fetchSettings,
*state.store,
SourcePath(accessor),
FetchMode::Copy,
lockedRef.input.getName());
state.fetchSettings, *state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
state.allowPath(storePath);
return state.storePath(storePath);
}
@ -213,4 +202,4 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
return state.rootPath(baseDir ? absPath(s, *baseDir) : absPath(s));
}
}
} // namespace nix

View file

@ -11,14 +11,12 @@ Strings editorFor(const SourcePath & file, uint32_t line)
throw Error("cannot open '%s' in an editor because it has no physical path", file);
auto editor = getEnv("EDITOR").value_or("cat");
auto args = tokenizeString<Strings>(editor);
if (line > 0 && (
editor.find("emacs") != std::string::npos ||
editor.find("nano") != std::string::npos ||
editor.find("vim") != std::string::npos ||
editor.find("kak") != std::string::npos))
if (line > 0
&& (editor.find("emacs") != std::string::npos || editor.find("nano") != std::string::npos
|| editor.find("vim") != std::string::npos || editor.find("kak") != std::string::npos))
args.push_back(fmt("+%d", line));
args.push_back(path->string());
return args;
}
}
} // namespace nix

View file

@ -8,7 +8,8 @@ namespace nix {
struct SingleBuiltPath;
struct SingleBuiltPathBuilt {
struct SingleBuiltPathBuilt
{
ref<SingleBuiltPath> drvPath;
std::pair<std::string, StorePath> output;
@ -18,26 +19,25 @@ struct SingleBuiltPathBuilt {
static SingleBuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
nlohmann::json toJSON(const StoreDirConfig & store) const;
bool operator ==(const SingleBuiltPathBuilt &) const noexcept;
std::strong_ordering operator <=>(const SingleBuiltPathBuilt &) const noexcept;
bool operator==(const SingleBuiltPathBuilt &) const noexcept;
std::strong_ordering operator<=>(const SingleBuiltPathBuilt &) const noexcept;
};
using _SingleBuiltPathRaw = std::variant<
DerivedPathOpaque,
SingleBuiltPathBuilt
>;
using _SingleBuiltPathRaw = std::variant<DerivedPathOpaque, SingleBuiltPathBuilt>;
struct SingleBuiltPath : _SingleBuiltPathRaw {
struct SingleBuiltPath : _SingleBuiltPathRaw
{
using Raw = _SingleBuiltPathRaw;
using Raw::Raw;
using Opaque = DerivedPathOpaque;
using Built = SingleBuiltPathBuilt;
bool operator == (const SingleBuiltPath &) const = default;
auto operator <=> (const SingleBuiltPath &) const = default;
bool operator==(const SingleBuiltPath &) const = default;
auto operator<=>(const SingleBuiltPath &) const = default;
inline const Raw & raw() const {
inline const Raw & raw() const
{
return static_cast<const Raw &>(*this);
}
@ -51,7 +51,7 @@ struct SingleBuiltPath : _SingleBuiltPathRaw {
static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
{
return make_ref<SingleBuiltPath>(SingleBuiltPath::Opaque { drvPath });
return make_ref<SingleBuiltPath>(SingleBuiltPath::Opaque{drvPath});
}
/**
@ -59,40 +59,41 @@ static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
*
* See 'BuiltPath' for more an explanation.
*/
struct BuiltPathBuilt {
struct BuiltPathBuilt
{
ref<SingleBuiltPath> drvPath;
std::map<std::string, StorePath> outputs;
bool operator == (const BuiltPathBuilt &) const noexcept;
bool operator==(const BuiltPathBuilt &) const noexcept;
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
//std::strong_ordering operator <=> (const BuiltPathBuilt &) const noexcept;
// std::strong_ordering operator <=> (const BuiltPathBuilt &) const noexcept;
std::string to_string(const StoreDirConfig & store) const;
static BuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
nlohmann::json toJSON(const StoreDirConfig & store) const;
};
using _BuiltPathRaw = std::variant<
DerivedPath::Opaque,
BuiltPathBuilt
>;
using _BuiltPathRaw = std::variant<DerivedPath::Opaque, BuiltPathBuilt>;
/**
* A built path. Similar to a DerivedPath, but enriched with the corresponding
* output path(s).
*/
struct BuiltPath : _BuiltPathRaw {
struct BuiltPath : _BuiltPathRaw
{
using Raw = _BuiltPathRaw;
using Raw::Raw;
using Opaque = DerivedPathOpaque;
using Built = BuiltPathBuilt;
bool operator == (const BuiltPath &) const = default;
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
//auto operator <=> (const BuiltPath &) const = default;
bool operator==(const BuiltPath &) const = default;
inline const Raw & raw() const {
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
// auto operator <=> (const BuiltPath &) const = default;
inline const Raw & raw() const
{
return static_cast<const Raw &>(*this);
}
@ -104,4 +105,4 @@ struct BuiltPath : _BuiltPathRaw {
typedef std::vector<BuiltPath> BuiltPaths;
}
} // namespace nix

View file

@ -20,4 +20,4 @@ struct InstallableValueCommand : InstallableCommand
void run(ref<Store> store, ref<Installable> installable) override;
};
}
} // namespace nix

View file

@ -13,13 +13,17 @@ namespace nix {
class Store;
namespace fetchers { struct Settings; }
namespace fetchers {
struct Settings;
}
class EvalState;
struct CompatibilitySettings;
class Bindings;
namespace flake { struct Settings; }
namespace flake {
struct Settings;
}
/**
* @todo Get rid of global settings variables
@ -54,10 +58,23 @@ struct MixEvalArgs : virtual Args, virtual MixRepair
std::optional<std::string> evalStoreUrl;
private:
struct AutoArgExpr { std::string expr; };
struct AutoArgString { std::string s; };
struct AutoArgFile { std::filesystem::path path; };
struct AutoArgStdin { };
struct AutoArgExpr
{
std::string expr;
};
struct AutoArgString
{
std::string s;
};
struct AutoArgFile
{
std::filesystem::path path;
};
struct AutoArgStdin
{};
using AutoArg = std::variant<AutoArgExpr, AutoArgString, AutoArgFile, AutoArgStdin>;
@ -69,4 +86,4 @@ private:
*/
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr);
}
} // namespace nix

View file

@ -33,4 +33,4 @@ struct CompatibilitySettings : public Config
)"};
};
};
}; // namespace nix

View file

@ -12,4 +12,4 @@ namespace nix {
*/
Strings editorFor(const SourcePath & file, uint32_t line);
}
} // namespace nix

View file

@ -39,7 +39,10 @@ class InstallableAttrPath : public InstallableValue
const std::string & attrPath,
ExtendedOutputsSpec extendedOutputsSpec);
std::string what() const override { return attrPath; };
std::string what() const override
{
return attrPath;
};
std::pair<Value *, PosIdx> toValue(EvalState & state) override;
@ -55,4 +58,4 @@ public:
ExtendedOutputsSpec extendedOutputsSpec);
};
}
} // namespace nix

View file

@ -11,8 +11,10 @@ struct InstallableDerivedPath : Installable
DerivedPath derivedPath;
InstallableDerivedPath(ref<Store> store, DerivedPath && derivedPath)
: store(store), derivedPath(std::move(derivedPath))
{ }
: store(store)
, derivedPath(std::move(derivedPath))
{
}
std::string what() const override;
@ -20,10 +22,8 @@ struct InstallableDerivedPath : Installable
std::optional<StorePath> getStorePath() override;
static InstallableDerivedPath parse(
ref<Store> store,
std::string_view prefix,
ExtendedOutputsSpec extendedOutputsSpec);
static InstallableDerivedPath
parse(ref<Store> store, std::string_view prefix, ExtendedOutputsSpec extendedOutputsSpec);
};
}
} // namespace nix

View file

@ -18,7 +18,8 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
/**
* Extra struct to get around C++ designated initializer limitations
*/
struct Flake {
struct Flake
{
FlakeRef originalRef;
FlakeRef lockedRef;
};
@ -26,8 +27,10 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
Flake flake;
ExtraPathInfoFlake(Value && v, Flake && f)
: ExtraPathInfoValue(std::move(v)), flake(std::move(f))
{ }
: ExtraPathInfoValue(std::move(v))
, flake(std::move(f))
{
}
};
struct InstallableFlake : InstallableValue
@ -49,7 +52,10 @@ struct InstallableFlake : InstallableValue
Strings prefixes,
const flake::LockFlags & lockFlags);
std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
std::string what() const override
{
return flakeRef.to_string() + "#" + *attrPaths.begin();
}
std::vector<std::string> getActualAttrPaths();
@ -61,8 +67,7 @@ struct InstallableFlake : InstallableValue
* Get a cursor to every attrpath in getActualAttrPaths() that
* exists. However if none exists, throw an exception.
*/
std::vector<ref<eval_cache::AttrCursor>>
getCursors(EvalState & state) override;
std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state) override;
std::shared_ptr<flake::LockedFlake> getLockedFlake() const;
@ -79,11 +84,9 @@ struct InstallableFlake : InstallableValue
*/
static inline FlakeRef defaultNixpkgsFlakeRef()
{
return FlakeRef::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", "nixpkgs"}});
return FlakeRef::fromAttrs(fetchSettings, {{"type", "indirect"}, {"id", "nixpkgs"}});
}
ref<eval_cache::EvalCache> openEvalCache(
EvalState & state,
std::shared_ptr<flake::LockedFlake> lockedFlake);
ref<eval_cache::EvalCache> openEvalCache(EvalState & state, std::shared_ptr<flake::LockedFlake> lockedFlake);
}
} // namespace nix

View file

@ -9,7 +9,10 @@ namespace nix {
struct PackageInfo;
struct SourceExprCommand;
namespace eval_cache { class EvalCache; class AttrCursor; }
namespace eval_cache {
class EvalCache;
class AttrCursor;
} // namespace eval_cache
struct App
{
@ -37,7 +40,8 @@ struct ExtraPathInfoValue : ExtraPathInfo
/**
* Extra struct to get around C++ designated initializer limitations
*/
struct Value {
struct Value
{
/**
* An optional priority for use with "build envs". See Package
*/
@ -61,7 +65,8 @@ struct ExtraPathInfoValue : ExtraPathInfo
ExtraPathInfoValue(Value && v)
: value(std::move(v))
{ }
{
}
virtual ~ExtraPathInfoValue() = default;
};
@ -74,9 +79,12 @@ struct InstallableValue : Installable
{
ref<EvalState> state;
InstallableValue(ref<EvalState> state) : state(state) {}
InstallableValue(ref<EvalState> state)
: state(state)
{
}
virtual ~InstallableValue() { }
virtual ~InstallableValue() {}
virtual std::pair<Value *, PosIdx> toValue(EvalState & state) = 0;
@ -85,15 +93,13 @@ struct InstallableValue : Installable
* However if none exists, throw exception instead of returning
* empty vector.
*/
virtual std::vector<ref<eval_cache::AttrCursor>>
getCursors(EvalState & state);
virtual std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state);
/**
* Get the first and most preferred cursor this Installable could
* refer to, or throw an exception if none exists.
*/
virtual ref<eval_cache::AttrCursor>
getCursor(EvalState & state);
virtual ref<eval_cache::AttrCursor> getCursor(EvalState & state);
UnresolvedApp toApp(EvalState & state);
@ -116,7 +122,8 @@ protected:
* @result A derived path (with empty info, for now) if the value
* matched the above criteria.
*/
std::optional<DerivedPathWithInfo> trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx);
std::optional<DerivedPathWithInfo>
trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx);
};
}
} // namespace nix

View file

@ -112,7 +112,7 @@ typedef std::vector<ref<Installable>> Installables;
*/
struct Installable
{
virtual ~Installable() { }
virtual ~Installable() {}
/**
* What Installable is this?
@ -168,37 +168,19 @@ struct Installable
BuildMode bMode = bmNormal);
static std::set<StorePath> toStorePathSet(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables);
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
static std::vector<StorePath> toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables);
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
static StorePath toStorePath(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
ref<Installable> installable);
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, ref<Installable> installable);
static std::set<StorePath> toDerivations(
ref<Store> store,
const Installables & installables,
bool useDeriver = false);
static std::set<StorePath>
toDerivations(ref<Store> store, const Installables & installables, bool useDeriver = false);
static BuiltPaths toBuiltPaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables);
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
};
}
} // namespace nix

View file

@ -7,13 +7,14 @@
namespace nix {
typedef std::function<void(int, char * *)> MainFunction;
typedef std::function<void(int, char **)> MainFunction;
struct RegisterLegacyCommand
{
typedef std::map<std::string, MainFunction> Commands;
static Commands & commands() {
static Commands & commands()
{
static Commands commands;
return commands;
}
@ -24,4 +25,4 @@ struct RegisterLegacyCommand
}
};
}
} // namespace nix

View file

@ -14,4 +14,4 @@ namespace nix {
*/
std::string renderMarkdownToTerminal(std::string_view markdown);
}
} // namespace nix

View file

@ -4,18 +4,22 @@
namespace nix::flag {
Args::Flag hashAlgo(std::string && longName, HashAlgorithm * ha);
static inline Args::Flag hashAlgo(HashAlgorithm * ha)
{
return hashAlgo("hash-algo", ha);
}
Args::Flag hashAlgoOpt(std::string && longName, std::optional<HashAlgorithm> * oha);
Args::Flag hashFormatWithDefault(std::string && longName, HashFormat * hf);
Args::Flag hashFormatOpt(std::string && longName, std::optional<HashFormat> * ohf);
static inline Args::Flag hashAlgoOpt(std::optional<HashAlgorithm> * oha)
{
return hashAlgoOpt("hash-algo", oha);
}
Args::Flag fileIngestionMethod(FileIngestionMethod * method);
Args::Flag contentAddressMethod(ContentAddressMethod * method);
}
} // namespace nix::flag

View file

@ -19,4 +19,4 @@ extern const StringSet networkProxyVariables;
*/
bool haveNetworkProxyConnection();
}
} // namespace nix

View file

@ -11,10 +11,11 @@ namespace nix {
namespace detail {
/** Provides the completion hooks for the repl, without exposing its complete
* internals. */
struct ReplCompleterMixin {
struct ReplCompleterMixin
{
virtual StringSet completePrefix(const std::string & prefix) = 0;
};
};
}; // namespace detail
enum class ReplPromptType {
ReplPrompt,
@ -29,7 +30,7 @@ public:
virtual Guard init(detail::ReplCompleterMixin * repl) = 0;
/** Returns a boolean of whether the interacter got EOF */
virtual bool getLine(std::string & input, ReplPromptType promptType) = 0;
virtual ~ReplInteracter(){};
virtual ~ReplInteracter() {};
};
class ReadlineLikeInteracter : public virtual ReplInteracter
@ -40,9 +41,10 @@ public:
: historyFile(historyFile)
{
}
virtual Guard init(detail::ReplCompleterMixin * repl) override;
virtual bool getLine(std::string & input, ReplPromptType promptType) override;
virtual ~ReadlineLikeInteracter() override;
};
};
}; // namespace nix

View file

@ -12,12 +12,12 @@ struct AbstractNixRepl
AbstractNixRepl(ref<EvalState> state)
: state(state)
{ }
{
}
virtual ~AbstractNixRepl()
{ }
virtual ~AbstractNixRepl() {}
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
typedef std::vector<std::pair<Value *, std::string>> AnnotatedValues;
using RunNix = void(Path program, const Strings & args, const std::optional<std::string> & input);
@ -33,13 +33,11 @@ struct AbstractNixRepl
std::function<AnnotatedValues()> getValues,
RunNix * runNix = nullptr);
static ReplExitStatus runSimple(
ref<EvalState> evalState,
const ValMap & extraEnv);
static ReplExitStatus runSimple(ref<EvalState> evalState, const ValMap & extraEnv);
virtual void initEnv() = 0;
virtual ReplExitStatus mainLoop() = 0;
};
}
} // namespace nix

View file

@ -35,7 +35,8 @@ InstallableAttrPath::InstallableAttrPath(
, v(allocRootValue(v))
, attrPath(attrPath)
, extendedOutputsSpec(std::move(extendedOutputsSpec))
{ }
{
}
std::pair<Value *, PosIdx> InstallableAttrPath::toValue(EvalState & state)
{
@ -48,12 +49,9 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
{
auto [v, pos] = toValue(*state);
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
*v,
pos,
fmt("while evaluating the attribute '%s'", attrPath)))
{
return { *derivedPathWithInfo };
if (std::optional derivedPathWithInfo =
trySinglePathToDerivedPaths(*v, pos, fmt("while evaluating the attribute '%s'", attrPath))) {
return {*derivedPathWithInfo};
}
Bindings & autoArgs = *cmd.getAutoArgs(*state);
@ -70,19 +68,19 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
if (!drvPath)
throw Error("'%s' is not a derivation", what());
auto newOutputs = std::visit(overloaded {
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
StringSet outputsToInstall;
for (auto & output : packageInfo.queryOutputs(false, true))
outputsToInstall.insert(output.first);
if (outputsToInstall.empty())
outputsToInstall.insert("out");
return OutputsSpec::Names { std::move(outputsToInstall) };
auto newOutputs = std::visit(
overloaded{
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
StringSet outputsToInstall;
for (auto & output : packageInfo.queryOutputs(false, true))
outputsToInstall.insert(output.first);
if (outputsToInstall.empty())
outputsToInstall.insert("out");
return OutputsSpec::Names{std::move(outputsToInstall)};
},
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec { return e; },
},
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
return e;
},
}, extendedOutputsSpec.raw);
extendedOutputsSpec.raw);
auto [iter, didInsert] = byDrvPath.emplace(*drvPath, newOutputs);
@ -93,11 +91,12 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
DerivedPathsWithInfo res;
for (auto & [drvPath, outputs] : byDrvPath)
res.push_back({
.path = DerivedPath::Built {
.drvPath = makeConstantStorePathRef(drvPath),
.outputs = outputs,
},
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value {
.path =
DerivedPath::Built{
.drvPath = makeConstantStorePathRef(drvPath),
.outputs = outputs,
},
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value{
.extendedOutputsSpec = outputs,
/* FIXME: reconsider backwards compatibility above
so we can fill in this info. */
@ -115,10 +114,12 @@ InstallableAttrPath InstallableAttrPath::parse(
ExtendedOutputsSpec extendedOutputsSpec)
{
return {
state, cmd, v,
prefix == "." ? "" : std::string { prefix },
state,
cmd,
v,
prefix == "." ? "" : std::string{prefix},
std::move(extendedOutputsSpec),
};
}
}
} // namespace nix

View file

@ -21,35 +21,35 @@ std::optional<StorePath> InstallableDerivedPath::getStorePath()
return derivedPath.getBaseStorePath();
}
InstallableDerivedPath InstallableDerivedPath::parse(
ref<Store> store,
std::string_view prefix,
ExtendedOutputsSpec extendedOutputsSpec)
InstallableDerivedPath
InstallableDerivedPath::parse(ref<Store> store, std::string_view prefix, ExtendedOutputsSpec extendedOutputsSpec)
{
auto derivedPath = std::visit(overloaded {
// If the user did not use ^, we treat the output more
// liberally: we accept a symlink chain or an actual
// store path.
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
auto storePath = store->followLinksToStorePath(prefix);
return DerivedPath::Opaque {
.path = std::move(storePath),
};
auto derivedPath = std::visit(
overloaded{
// If the user did not use ^, we treat the output more
// liberally: we accept a symlink chain or an actual
// store path.
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
auto storePath = store->followLinksToStorePath(prefix);
return DerivedPath::Opaque{
.path = std::move(storePath),
};
},
// If the user did use ^, we just do exactly what is written.
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
auto drv = make_ref<SingleDerivedPath>(SingleDerivedPath::parse(*store, prefix));
drvRequireExperiment(*drv);
return DerivedPath::Built{
.drvPath = std::move(drv),
.outputs = outputSpec,
};
},
},
// If the user did use ^, we just do exactly what is written.
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
auto drv = make_ref<SingleDerivedPath>(SingleDerivedPath::parse(*store, prefix));
drvRequireExperiment(*drv);
return DerivedPath::Built {
.drvPath = std::move(drv),
.outputs = outputSpec,
};
},
}, extendedOutputsSpec.raw);
return InstallableDerivedPath {
extendedOutputsSpec.raw);
return InstallableDerivedPath{
store,
std::move(derivedPath),
};
}
}
} // namespace nix

View file

@ -28,8 +28,8 @@ namespace nix {
std::vector<std::string> InstallableFlake::getActualAttrPaths()
{
std::vector<std::string> res;
if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")){
attrPaths.front().erase(0,1);
if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")) {
attrPaths.front().erase(0, 1);
res.push_back(attrPaths.front());
return res;
}
@ -47,8 +47,11 @@ static std::string showAttrPaths(const std::vector<std::string> & paths)
{
std::string s;
for (const auto & [n, i] : enumerate(paths)) {
if (n > 0) s += n + 1 == paths.size() ? " or " : ", ";
s += '\''; s += i; s += '\'';
if (n > 0)
s += n + 1 == paths.size() ? " or " : ", ";
s += '\'';
s += i;
s += '\'';
}
return s;
}
@ -62,12 +65,12 @@ InstallableFlake::InstallableFlake(
Strings attrPaths,
Strings prefixes,
const flake::LockFlags & lockFlags)
: InstallableValue(state),
flakeRef(flakeRef),
attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}),
prefixes(fragment == "" ? Strings{} : prefixes),
extendedOutputsSpec(std::move(extendedOutputsSpec)),
lockFlags(lockFlags)
: InstallableValue(state)
, flakeRef(flakeRef)
, attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment})
, prefixes(fragment == "" ? Strings{} : prefixes)
, extendedOutputsSpec(std::move(extendedOutputsSpec))
, lockFlags(lockFlags)
{
if (cmd && cmd->getAutoArgs(*state)->size())
throw UsageError("'--arg' and '--argstr' are incompatible with flakes");
@ -87,18 +90,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
auto v = attr->forceValue();
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
v,
noPos,
fmt("while evaluating the flake output attribute '%s'", attrPath)))
{
return { *derivedPathWithInfo };
v, noPos, fmt("while evaluating the flake output attribute '%s'", attrPath))) {
return {*derivedPathWithInfo};
} else {
throw Error(
"expected flake output attribute '%s' to be a derivation or path but found %s: %s",
attrPath,
showType(v),
ValuePrinter(*this->state, v, errorPrintOptions)
);
ValuePrinter(*this->state, v, errorPrintOptions));
}
}
@ -113,39 +112,40 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
}
return {{
.path = DerivedPath::Built {
.drvPath = makeConstantStorePathRef(std::move(drvPath)),
.outputs = std::visit(overloaded {
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
StringSet outputsToInstall;
if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) {
if (aOutputSpecified->getBool()) {
if (auto aOutputName = attr->maybeGetAttr("outputName"))
outputsToInstall = { aOutputName->getString() };
}
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings())
outputsToInstall.insert(s);
}
.path =
DerivedPath::Built{
.drvPath = makeConstantStorePathRef(std::move(drvPath)),
.outputs = std::visit(
overloaded{
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
StringSet outputsToInstall;
if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) {
if (aOutputSpecified->getBool()) {
if (auto aOutputName = attr->maybeGetAttr("outputName"))
outputsToInstall = {aOutputName->getString()};
}
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings())
outputsToInstall.insert(s);
}
if (outputsToInstall.empty())
outputsToInstall.insert("out");
if (outputsToInstall.empty())
outputsToInstall.insert("out");
return OutputsSpec::Names { std::move(outputsToInstall) };
},
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
return e;
},
}, extendedOutputsSpec.raw),
},
return OutputsSpec::Names{std::move(outputsToInstall)};
},
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec { return e; },
},
extendedOutputsSpec.raw),
},
.info = make_ref<ExtraPathInfoFlake>(
ExtraPathInfoValue::Value {
ExtraPathInfoValue::Value{
.priority = priority,
.attrPath = attrPath,
.extendedOutputsSpec = extendedOutputsSpec,
},
ExtraPathInfoFlake::Flake {
ExtraPathInfoFlake::Flake{
.originalRef = flakeRef,
.lockedRef = getLockedFlake()->flake.lockedRef,
}),
@ -157,8 +157,7 @@ std::pair<Value *, PosIdx> InstallableFlake::toValue(EvalState & state)
return {&getCursor(state)->forceValue(), noPos};
}
std::vector<ref<eval_cache::AttrCursor>>
InstallableFlake::getCursors(EvalState & state)
std::vector<ref<eval_cache::AttrCursor>> InstallableFlake::getCursors(EvalState & state)
{
auto evalCache = openEvalCache(state, getLockedFlake());
@ -181,11 +180,7 @@ InstallableFlake::getCursors(EvalState & state)
}
if (res.size() == 0)
throw Error(
suggestions,
"flake '%s' does not provide attribute %s",
flakeRef,
showAttrPaths(attrPaths));
throw Error(suggestions, "flake '%s' does not provide attribute %s", flakeRef, showAttrPaths(attrPaths));
return res;
}
@ -196,8 +191,8 @@ std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
flake::LockFlags lockFlagsApplyConfig = lockFlags;
// FIXME why this side effect?
lockFlagsApplyConfig.applyNixConfig = true;
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(
flakeSettings, *state, flakeRef, lockFlagsApplyConfig));
_lockedFlake =
std::make_shared<flake::LockedFlake>(lockFlake(flakeSettings, *state, flakeRef, lockFlagsApplyConfig));
}
return _lockedFlake;
}
@ -216,4 +211,4 @@ FlakeRef InstallableFlake::nixpkgsFlakeRef() const
return defaultNixpkgsFlakeRef();
}
}
} // namespace nix

View file

@ -4,17 +4,14 @@
namespace nix {
std::vector<ref<eval_cache::AttrCursor>>
InstallableValue::getCursors(EvalState & state)
std::vector<ref<eval_cache::AttrCursor>> InstallableValue::getCursors(EvalState & state)
{
auto evalCache =
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
[&]() { return toValue(state).first; });
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state, [&]() { return toValue(state).first; });
return {evalCache->getRoot()};
}
ref<eval_cache::AttrCursor>
InstallableValue::getCursor(EvalState & state)
ref<eval_cache::AttrCursor> InstallableValue::getCursor(EvalState & state)
{
/* Although getCursors should return at least one element, in case it doesn't,
bound check to avoid an undefined behavior for vector[0] */
@ -39,30 +36,32 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
auto castedInstallable = installable.dynamic_pointer_cast<InstallableValue>();
if (!castedInstallable)
throw nonValueInstallable(*installable);
return ref { castedInstallable };
return ref{castedInstallable};
}
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
std::optional<DerivedPathWithInfo>
InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
{
if (v.type() == nPath) {
auto storePath = fetchToStore(state->fetchSettings, *state->store, v.path(), FetchMode::Copy);
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
},
.path =
DerivedPath::Opaque{
.path = std::move(storePath),
},
.info = make_ref<ExtraPathInfo>(),
}};
}
else if (v.type() == nString) {
return {{
.path = DerivedPath::fromSingle(
state->coerceToSingleDerivedPath(pos, v, errorCtx)),
.path = DerivedPath::fromSingle(state->coerceToSingleDerivedPath(pos, v, errorCtx)),
.info = make_ref<ExtraPathInfo>(),
}};
}
else return std::nullopt;
else
return std::nullopt;
}
}
} // namespace nix

View file

@ -61,7 +61,8 @@ MixFlakeOptions::MixFlakeOptions()
.category = category,
.handler = {[&]() {
lockFlags.recreateLockFile = true;
warn("'--recreate-lock-file' is deprecated and will be removed in a future version; use 'nix flake update' instead.");
warn(
"'--recreate-lock-file' is deprecated and will be removed in a future version; use 'nix flake update' instead.");
}},
});
@ -158,9 +159,7 @@ MixFlakeOptions::MixFlakeOptions()
.description = "Write the given lock file instead of `flake.lock` within the top-level flake.",
.category = category,
.labels = {"flake-lock-path"},
.handler = {[&](std::string lockFilePath) {
lockFlags.outputLockFilePath = lockFilePath;
}},
.handler = {[&](std::string lockFilePath) { lockFlags.outputLockFilePath = lockFilePath; }},
.completer = completePath,
});
@ -175,12 +174,12 @@ MixFlakeOptions::MixFlakeOptions()
flakeSettings,
*evalState,
parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir())),
{ .writeLockFile = false });
{.writeLockFile = false});
for (auto & [inputName, input] : flake.lockFile.root->inputs) {
auto input2 = flake.lockFile.findInput({inputName}); // resolve 'follows' nodes
if (auto input3 = std::dynamic_pointer_cast<const flake::LockedNode>(input2)) {
overrideRegistry(
fetchers::Input::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", inputName}}),
fetchers::Input::fromAttrs(fetchSettings, {{"type", "indirect"}, {"id", inputName}}),
input3->lockedRef.input,
{});
}
@ -209,7 +208,8 @@ SourceExprCommand::SourceExprCommand()
addFlag({
.longName = "expr",
.description = "Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression *expr*.",
.description =
"Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression *expr*.",
.category = installablesCategory,
.labels = {"expr"},
.handler = {&expr},
@ -220,32 +220,26 @@ MixReadOnlyOption::MixReadOnlyOption()
{
addFlag({
.longName = "read-only",
.description =
"Do not instantiate each evaluated derivation. "
"This improves performance, but can cause errors when accessing "
"store paths of derivations during evaluation.",
.description = "Do not instantiate each evaluated derivation. "
"This improves performance, but can cause errors when accessing "
"store paths of derivations during evaluation.",
.handler = {&settings.readOnlyMode, true},
});
}
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
{
return {
"packages." + settings.thisSystem.get() + ".default",
"defaultPackage." + settings.thisSystem.get()
};
return {"packages." + settings.thisSystem.get() + ".default", "defaultPackage." + settings.thisSystem.get()};
}
Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
{
return {
// As a convenience, look for the attribute in
// 'outputs.packages'.
"packages." + settings.thisSystem.get() + ".",
// As a temporary hack until Nixpkgs is properly converted
// to provide a clean 'packages' set, look in 'legacyPackages'.
"legacyPackages." + settings.thisSystem.get() + "."
};
return {// As a convenience, look for the attribute in
// 'outputs.packages'.
"packages." + settings.thisSystem.get() + ".",
// As a temporary hack until Nixpkgs is properly converted
// to provide a clean 'packages' set, look in 'legacyPackages'.
"legacyPackages." + settings.thisSystem.get() + "."};
}
Args::CompleterClosure SourceExprCommand::getCompleteInstallable()
@ -263,10 +257,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
evalSettings.pureEval = false;
auto state = getEvalState();
auto e =
state->parseExprFromFile(
resolveExprPath(
lookupFileArg(*state, *file)));
auto e = state->parseExprFromFile(resolveExprPath(lookupFileArg(*state, *file)));
Value root;
state->eval(e, root);
@ -285,7 +276,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
}
auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root);
Value &v1(*v);
Value & v1(*v);
state->forceValue(v1, pos);
Value v2;
state->autoCallFunction(*autoArgs, v1, v2);
@ -310,7 +301,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
getDefaultFlakeAttrPaths(),
prefix);
}
} catch (EvalError&) {
} catch (EvalError &) {
// Don't want eval errors to mess-up with the completion engine, so let's just swallow them
}
}
@ -334,22 +325,23 @@ void completeFlakeRefWithFragment(
auto fragment = prefix.substr(hash + 1);
std::string prefixRoot = "";
if (fragment.starts_with(".")){
if (fragment.starts_with(".")) {
fragment = fragment.substr(1);
prefixRoot = ".";
}
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), std::filesystem::current_path().string());
auto flakeRef =
parseFlakeRef(fetchSettings, expandTilde(flakeRefS), std::filesystem::current_path().string());
auto evalCache = openEvalCache(*evalState,
std::make_shared<flake::LockedFlake>(lockFlake(
flakeSettings, *evalState, flakeRef, lockFlags)));
auto evalCache = openEvalCache(
*evalState,
std::make_shared<flake::LockedFlake>(lockFlake(flakeSettings, *evalState, flakeRef, lockFlags)));
auto root = evalCache->getRoot();
if (prefixRoot == "."){
if (prefixRoot == ".") {
attrPathPrefixes.clear();
}
/* Complete 'fragment' relative to all the
@ -369,7 +361,8 @@ void completeFlakeRefWithFragment(
}
auto attr = root->findAlongAttrPath(attrPath);
if (!attr) continue;
if (!attr)
continue;
for (auto & attr2 : (*attr)->getAttrs()) {
if (hasPrefix(evalState->symbols[attr2], lastAttr)) {
@ -377,7 +370,9 @@ void completeFlakeRefWithFragment(
/* Strip the attrpath prefix. */
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
// FIXME: handle names with dots
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
completions.add(
flakeRefS + "#" + prefixRoot
+ concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
}
}
}
@ -387,7 +382,8 @@ void completeFlakeRefWithFragment(
if (fragment.empty()) {
for (auto & attrPath : defaultFlakeAttrPaths) {
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
if (!attr) continue;
if (!attr)
continue;
completions.add(flakeRefS + "#" + prefixRoot);
}
}
@ -427,14 +423,12 @@ DerivedPathWithInfo Installable::toDerivedPath()
{
auto buildables = toDerivedPaths();
if (buildables.size() != 1)
throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
throw Error(
"installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
return std::move(buildables[0]);
}
static StorePath getDeriver(
ref<Store> store,
const Installable & i,
const StorePath & drvPath)
static StorePath getDeriver(ref<Store> store, const Installable & i, const StorePath & drvPath)
{
auto derivers = store->queryValidDerivers(drvPath);
if (derivers.empty())
@ -443,35 +437,35 @@ static StorePath getDeriver(
return *derivers.begin();
}
ref<eval_cache::EvalCache> openEvalCache(
EvalState & state,
std::shared_ptr<flake::LockedFlake> lockedFlake)
ref<eval_cache::EvalCache> openEvalCache(EvalState & state, std::shared_ptr<flake::LockedFlake> lockedFlake)
{
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
: std::nullopt;
auto rootLoader = [&state, lockedFlake]()
{
/* For testing whether the evaluation cache is
complete. */
if (getEnv("NIX_ALLOW_EVAL").value_or("1") == "0")
throw Error("not everything is cached, but evaluation is not allowed");
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
: std::nullopt;
auto rootLoader = [&state, lockedFlake]() {
/* For testing whether the evaluation cache is
complete. */
if (getEnv("NIX_ALLOW_EVAL").value_or("1") == "0")
throw Error("not everything is cached, but evaluation is not allowed");
auto vFlake = state.allocValue();
flake::callFlake(state, *lockedFlake, *vFlake);
auto vFlake = state.allocValue();
flake::callFlake(state, *lockedFlake, *vFlake);
state.forceAttrs(*vFlake, noPos, "while parsing cached flake data");
state.forceAttrs(*vFlake, noPos, "while parsing cached flake data");
auto aOutputs = vFlake->attrs()->get(state.symbols.create("outputs"));
assert(aOutputs);
auto aOutputs = vFlake->attrs()->get(state.symbols.create("outputs"));
assert(aOutputs);
return aOutputs->value;
};
return aOutputs->value;
};
if (fingerprint) {
auto search = state.evalCaches.find(fingerprint.value());
if (search == state.evalCaches.end()) {
search = state.evalCaches.emplace(fingerprint.value(), make_ref<nix::eval_cache::EvalCache>(fingerprint, state, rootLoader)).first;
search =
state.evalCaches
.emplace(fingerprint.value(), make_ref<nix::eval_cache::EvalCache>(fingerprint, state, rootLoader))
.first;
}
return search->second;
} else {
@ -479,8 +473,7 @@ ref<eval_cache::EvalCache> openEvalCache(
}
}
Installables SourceExprCommand::parseInstallables(
ref<Store> store, std::vector<std::string> ss)
Installables SourceExprCommand::parseInstallables(ref<Store> store, std::vector<std::string> ss)
{
Installables result;
@ -501,12 +494,10 @@ Installables SourceExprCommand::parseInstallables(
if (file == "-") {
auto e = state->parseStdin();
state->eval(e, *vFile);
}
else if (file) {
} else if (file) {
auto dir = absPath(getCommandBaseDir());
state->evalFile(lookupFileArg(*state, *file, &dir), *vFile);
}
else {
} else {
Path dir = absPath(getCommandBaseDir());
auto e = state->parseExprFromString(*expr, state->rootPath(dir));
state->eval(e, *vFile);
@ -515,9 +506,8 @@ Installables SourceExprCommand::parseInstallables(
for (auto & s : ss) {
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s);
result.push_back(
make_ref<InstallableAttrPath>(
InstallableAttrPath::parse(
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
make_ref<InstallableAttrPath>(InstallableAttrPath::parse(
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
}
} else {
@ -532,8 +522,9 @@ Installables SourceExprCommand::parseInstallables(
if (prefix.find('/') != std::string::npos) {
try {
result.push_back(make_ref<InstallableDerivedPath>(
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec.raw)));
result.push_back(
make_ref<InstallableDerivedPath>(
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec.raw)));
continue;
} catch (BadStorePath &) {
} catch (...) {
@ -543,9 +534,10 @@ Installables SourceExprCommand::parseInstallables(
}
try {
auto [flakeRef, fragment] = parseFlakeRefWithFragment(
fetchSettings, std::string { prefix }, absPath(getCommandBaseDir()));
result.push_back(make_ref<InstallableFlake>(
auto [flakeRef, fragment] =
parseFlakeRefWithFragment(fetchSettings, std::string{prefix}, absPath(getCommandBaseDir()));
result.push_back(
make_ref<InstallableFlake>(
this,
getEvalState(),
std::move(flakeRef),
@ -566,8 +558,7 @@ Installables SourceExprCommand::parseInstallables(
return result;
}
ref<Installable> SourceExprCommand::parseInstallable(
ref<Store> store, const std::string & installable)
ref<Installable> SourceExprCommand::parseInstallable(ref<Store> store, const std::string & installable)
{
auto installables = parseInstallables(store, {installable});
assert(installables.size() == 1);
@ -578,20 +569,18 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
{
return std::visit(
overloaded{
[&](const SingleDerivedPath::Opaque & bo) -> SingleBuiltPath {
return SingleBuiltPath::Opaque { bo.path };
},
[&](const SingleDerivedPath::Opaque & bo) -> SingleBuiltPath { return SingleBuiltPath::Opaque{bo.path}; },
[&](const SingleDerivedPath::Built & bfd) -> SingleBuiltPath {
auto drvPath = getBuiltPath(evalStore, store, *bfd.drvPath);
// Resolving this instead of `bfd` will yield the same result, but avoid duplicative work.
SingleDerivedPath::Built truncatedBfd {
SingleDerivedPath::Built truncatedBfd{
.drvPath = makeConstantStorePathRef(drvPath.outPath()),
.output = bfd.output,
};
auto outputPath = resolveDerivedPath(*store, truncatedBfd, &*evalStore);
return SingleBuiltPath::Built {
return SingleBuiltPath::Built{
.drvPath = make_ref<SingleBuiltPath>(std::move(drvPath)),
.output = { bfd.output, outputPath },
.output = {bfd.output, outputPath},
};
},
},
@ -599,11 +588,7 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
}
std::vector<BuiltPathWithResult> Installable::build(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
const Installables & installables,
BuildMode bMode)
ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
{
std::vector<BuiltPathWithResult> res;
for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
@ -611,9 +596,7 @@ std::vector<BuiltPathWithResult> Installable::build(
return res;
}
static void throwBuildErrors(
std::vector<KeyedBuildResult> & buildResults,
const Store & store)
static void throwBuildErrors(std::vector<KeyedBuildResult> & buildResults, const Store & store)
{
std::vector<KeyedBuildResult> failed;
for (auto & buildResult : buildResults) {
@ -630,10 +613,11 @@ static void throwBuildErrors(
StringSet failedPaths;
for (; failedResult != failed.end(); failedResult++) {
if (!failedResult->errorMsg.empty()) {
logError(ErrorInfo{
.level = lvlError,
.msg = failedResult->errorMsg,
});
logError(
ErrorInfo{
.level = lvlError,
.msg = failedResult->errorMsg,
});
}
failedPaths.insert(failedResult->path.to_string(store));
}
@ -643,11 +627,7 @@ static void throwBuildErrors(
}
std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
const Installables & installables,
BuildMode bMode)
ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
{
if (mode == Realise::Nothing)
settings.readOnlyMode = true;
@ -678,22 +658,25 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
for (auto & path : pathsToBuild) {
for (auto & aux : backmap[path]) {
std::visit(overloaded {
[&](const DerivedPath::Built & bfd) {
auto outputs = resolveDerivedPath(*store, bfd, &*evalStore);
res.push_back({aux.installable, {
.path = BuiltPath::Built {
.drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
.outputs = outputs,
},
.info = aux.info}});
std::visit(
overloaded{
[&](const DerivedPath::Built & bfd) {
auto outputs = resolveDerivedPath(*store, bfd, &*evalStore);
res.push_back(
{aux.installable,
{.path =
BuiltPath::Built{
.drvPath =
make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
.outputs = outputs,
},
.info = aux.info}});
},
[&](const DerivedPath::Opaque & bo) {
res.push_back({aux.installable, {.path = BuiltPath::Opaque{bo.path}, .info = aux.info}});
},
},
[&](const DerivedPath::Opaque & bo) {
res.push_back({aux.installable, {
.path = BuiltPath::Opaque { bo.path },
.info = aux.info}});
},
}, path.raw());
path.raw());
}
}
@ -707,26 +690,30 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
throwBuildErrors(buildResults, *store);
for (auto & buildResult : buildResults) {
for (auto & aux : backmap[buildResult.path]) {
std::visit(overloaded {
[&](const DerivedPath::Built & bfd) {
std::map<std::string, StorePath> outputs;
for (auto & [outputName, realisation] : buildResult.builtOutputs)
outputs.emplace(outputName, realisation.outPath);
res.push_back({aux.installable, {
.path = BuiltPath::Built {
.drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
.outputs = outputs,
},
.info = aux.info,
.result = buildResult}});
std::visit(
overloaded{
[&](const DerivedPath::Built & bfd) {
std::map<std::string, StorePath> outputs;
for (auto & [outputName, realisation] : buildResult.builtOutputs)
outputs.emplace(outputName, realisation.outPath);
res.push_back(
{aux.installable,
{.path =
BuiltPath::Built{
.drvPath =
make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
.outputs = outputs,
},
.info = aux.info,
.result = buildResult}});
},
[&](const DerivedPath::Opaque & bo) {
res.push_back(
{aux.installable,
{.path = BuiltPath::Opaque{bo.path}, .info = aux.info, .result = buildResult}});
},
},
[&](const DerivedPath::Opaque & bo) {
res.push_back({aux.installable, {
.path = BuiltPath::Opaque { bo.path },
.info = aux.info,
.result = buildResult}});
},
}, buildResult.path.raw());
buildResult.path.raw());
}
}
@ -741,11 +728,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
}
BuiltPaths Installable::toBuiltPaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables)
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
{
if (operateOn == OperateOn::Output) {
BuiltPaths res;
@ -764,10 +747,7 @@ BuiltPaths Installable::toBuiltPaths(
}
StorePathSet Installable::toStorePathSet(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
{
StorePathSet outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
@ -778,10 +758,7 @@ StorePathSet Installable::toStorePathSet(
}
StorePaths Installable::toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
{
StorePaths outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
@ -792,10 +769,7 @@ StorePaths Installable::toStorePaths(
}
StorePath Installable::toStorePath(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
ref<Installable> installable)
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, ref<Installable> installable)
{
auto paths = toStorePathSet(evalStore, store, mode, operateOn, {installable});
@ -805,28 +779,23 @@ StorePath Installable::toStorePath(
return *paths.begin();
}
StorePathSet Installable::toDerivations(
ref<Store> store,
const Installables & installables,
bool useDeriver)
StorePathSet Installable::toDerivations(ref<Store> store, const Installables & installables, bool useDeriver)
{
StorePathSet drvPaths;
for (const auto & i : installables)
for (const auto & b : i->toDerivedPaths())
std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) {
drvPaths.insert(
bo.path.isDerivation()
? bo.path
: useDeriver
? getDeriver(store, *i, bo.path)
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
std::visit(
overloaded{
[&](const DerivedPath::Opaque & bo) {
drvPaths.insert(
bo.path.isDerivation() ? bo.path
: useDeriver ? getDeriver(store, *i, bo.path)
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
},
[&](const DerivedPath::Built & bfd) { drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath)); },
},
[&](const DerivedPath::Built & bfd) {
drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath));
},
}, b.path.raw());
b.path.raw());
return drvPaths;
}
@ -861,10 +830,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
std::vector<FlakeRef> res;
res.reserve(rawInstallables.size());
for (const auto & i : rawInstallables)
res.push_back(parseFlakeRefWithFragment(
fetchSettings,
expandTilde(i),
absPath(getCommandBaseDir())).first);
res.push_back(parseFlakeRefWithFragment(fetchSettings, expandTilde(i), absPath(getCommandBaseDir())).first);
return res;
}
@ -883,12 +849,7 @@ void RawInstallablesCommand::run(ref<Store> store)
std::vector<FlakeRef> InstallableCommand::getFlakeRefsForCompletion()
{
return {
parseFlakeRefWithFragment(
fetchSettings,
expandTilde(_installable),
absPath(getCommandBaseDir())).first
};
return {parseFlakeRefWithFragment(fetchSettings, expandTilde(_installable), absPath(getCommandBaseDir())).first};
}
void InstallablesCommand::run(ref<Store> store, std::vector<std::string> && rawInstallables)
@ -928,4 +889,4 @@ BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithR
return res;
}
}
} // namespace nix

View file

@ -18,25 +18,24 @@ static std::string doRenderMarkdownToTerminal(std::string_view markdown)
{
int windowWidth = getWindowSize().second;
#if HAVE_LOWDOWN_1_4
struct lowdown_opts_term opts_term {
# 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
{
# endif
struct lowdown_opts opts{
.type = LOWDOWN_TERM,
#if HAVE_LOWDOWN_1_4
# if HAVE_LOWDOWN_1_4
.term = opts_term,
#endif
# endif
.maxdepth = 20,
#if !HAVE_LOWDOWN_1_4
# if !HAVE_LOWDOWN_1_4
.cols = (size_t) std::max(windowWidth - 5, 60),
.hmargin = 0,
.vmargin = 0,
#endif
# endif
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
.oflags = LOWDOWN_TERM_NOLINK,
};

View file

@ -1,7 +1,6 @@
#include "nix/cmd/misc-store-flags.hh"
namespace nix::flag
{
namespace nix::flag {
static void hashFormatCompleter(AddCompletions & completions, size_t index, std::string_view prefix)
{
@ -15,27 +14,23 @@ static void hashFormatCompleter(AddCompletions & completions, size_t index, std:
Args::Flag hashFormatWithDefault(std::string && longName, HashFormat * hf)
{
assert(*hf == nix::HashFormat::SRI);
return Args::Flag {
.longName = std::move(longName),
.description = "Hash format (`base16`, `nix32`, `base64`, `sri`). Default: `sri`.",
.labels = {"hash-format"},
.handler = {[hf](std::string s) {
*hf = parseHashFormat(s);
}},
.completer = hashFormatCompleter,
return Args::Flag{
.longName = std::move(longName),
.description = "Hash format (`base16`, `nix32`, `base64`, `sri`). Default: `sri`.",
.labels = {"hash-format"},
.handler = {[hf](std::string s) { *hf = parseHashFormat(s); }},
.completer = hashFormatCompleter,
};
}
Args::Flag hashFormatOpt(std::string && longName, std::optional<HashFormat> * ohf)
{
return Args::Flag {
.longName = std::move(longName),
.description = "Hash format (`base16`, `nix32`, `base64`, `sri`).",
.labels = {"hash-format"},
.handler = {[ohf](std::string s) {
*ohf = std::optional<HashFormat>{parseHashFormat(s)};
}},
.completer = hashFormatCompleter,
return Args::Flag{
.longName = std::move(longName),
.description = "Hash format (`base16`, `nix32`, `base64`, `sri`).",
.labels = {"hash-format"},
.handler = {[ohf](std::string s) { *ohf = std::optional<HashFormat>{parseHashFormat(s)}; }},
.completer = hashFormatCompleter,
};
}
@ -48,34 +43,31 @@ static void hashAlgoCompleter(AddCompletions & completions, size_t index, std::s
Args::Flag hashAlgo(std::string && longName, HashAlgorithm * ha)
{
return Args::Flag {
.longName = std::move(longName),
.description = "Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`).",
.labels = {"hash-algo"},
.handler = {[ha](std::string s) {
*ha = parseHashAlgo(s);
}},
.completer = hashAlgoCompleter,
return Args::Flag{
.longName = std::move(longName),
.description = "Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`).",
.labels = {"hash-algo"},
.handler = {[ha](std::string s) { *ha = parseHashAlgo(s); }},
.completer = hashAlgoCompleter,
};
}
Args::Flag hashAlgoOpt(std::string && longName, std::optional<HashAlgorithm> * oha)
{
return Args::Flag {
.longName = std::move(longName),
.description = "Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`). Can be omitted for SRI hashes.",
.labels = {"hash-algo"},
.handler = {[oha](std::string s) {
*oha = std::optional<HashAlgorithm>{parseHashAlgo(s)};
}},
.completer = hashAlgoCompleter,
return Args::Flag{
.longName = std::move(longName),
.description =
"Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`). Can be omitted for SRI hashes.",
.labels = {"hash-algo"},
.handler = {[oha](std::string s) { *oha = std::optional<HashAlgorithm>{parseHashAlgo(s)}; }},
.completer = hashAlgoCompleter,
};
}
Args::Flag fileIngestionMethod(FileIngestionMethod * method)
{
return Args::Flag {
.longName = "mode",
return Args::Flag{
.longName = "mode",
// FIXME indentation carefully made for context, this is messed up.
.description = R"(
How to compute the hash of the input.
@ -92,16 +84,14 @@ Args::Flag fileIngestionMethod(FileIngestionMethod * method)
it to the hash function.
)",
.labels = {"file-ingestion-method"},
.handler = {[method](std::string s) {
*method = parseFileIngestionMethod(s);
}},
.handler = {[method](std::string s) { *method = parseFileIngestionMethod(s); }},
};
}
Args::Flag contentAddressMethod(ContentAddressMethod * method)
{
return Args::Flag {
.longName = "mode",
return Args::Flag{
.longName = "mode",
// FIXME indentation carefully made for context, this is messed up.
.description = R"(
How to compute the content-address of the store object.
@ -126,10 +116,8 @@ Args::Flag contentAddressMethod(ContentAddressMethod * method)
for regular usage prefer `nar` and `flat`.
)",
.labels = {"content-address-method"},
.handler = {[method](std::string s) {
*method = ContentAddressMethod::parse(s);
}},
.handler = {[method](std::string s) { *method = ContentAddressMethod::parse(s); }},
};
}
}
} // namespace nix::flag

View file

@ -47,4 +47,4 @@ bool haveNetworkProxyConnection()
return false;
}
}
} // namespace nix

View file

@ -5,8 +5,8 @@
#include <signal.h>
#if USE_READLINE
#include <readline/history.h>
#include <readline/readline.h>
# include <readline/history.h>
# include <readline/readline.h>
#else
// editline < 1.15.2 don't wrap their API for C++ usage
// (added in https://github.com/troglobit/editline/commit/91398ceb3427b730995357e9d120539fb9bb7461).
@ -14,7 +14,7 @@
// For compatibility with these versions, we wrap the API here
// (wrapping multiple times on newer versions is no problem).
extern "C" {
#include <editline.h>
# include <editline.h>
}
#endif
@ -35,7 +35,7 @@ void sigintHandler(int signo)
{
g_signal_received = signo;
}
};
}; // namespace
static detail::ReplCompleterMixin * curRepl; // ugly
@ -185,8 +185,7 @@ bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptT
// editline doesn't echo the input to the output when non-interactive, unlike readline
// this results in a different behavior when running tests. The echoing is
// quite useful for reading the test output, so we add it here.
if (auto e = getEnv("_NIX_TEST_REPL_ECHO"); s && e && *e == "1")
{
if (auto e = getEnv("_NIX_TEST_REPL_ECHO"); s && e && *e == "1") {
#if !USE_READLINE
// This is probably not right for multi-line input, but we don't use that
// in the characterisation tests, so it's fine.
@ -207,4 +206,4 @@ ReadlineLikeInteracter::~ReadlineLikeInteracter()
write_history(historyFile.c_str());
}
};
}; // namespace nix

View file

@ -54,10 +54,7 @@ enum class ProcessLineResult {
PromptAgain,
};
struct NixRepl
: AbstractNixRepl
, detail::ReplCompleterMixin
, gc
struct NixRepl : AbstractNixRepl, detail::ReplCompleterMixin, gc
{
size_t debugTraceIndex;
@ -80,8 +77,12 @@ struct NixRepl
std::unique_ptr<ReplInteracter> interacter;
NixRepl(const LookupPath & lookupPath, nix::ref<Store> store,ref<EvalState> state,
std::function<AnnotatedValues()> getValues, RunNix * runNix);
NixRepl(
const LookupPath & lookupPath,
nix::ref<Store> store,
ref<EvalState> state,
std::function<AnnotatedValues()> getValues,
RunNix * runNix);
virtual ~NixRepl() = default;
ReplExitStatus mainLoop() override;
@ -103,20 +104,22 @@ struct NixRepl
void evalString(std::string s, Value & v);
void loadDebugTraceEnv(DebugTrace & dt);
void printValue(std::ostream & str,
Value & v,
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
void printValue(std::ostream & str, Value & v, unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
{
// Hide the progress bar during printing because it might interfere
auto suspension = logger->suspend();
::nix::printValue(*state, str, v, PrintOptions {
.ansiColors = true,
.force = true,
.derivationPaths = true,
.maxDepth = maxDepth,
.prettyIndent = 2,
.errors = ErrorPrintBehavior::ThrowTopLevel,
});
::nix::printValue(
*state,
str,
v,
PrintOptions{
.ansiColors = true,
.force = true,
.derivationPaths = true,
.maxDepth = maxDepth,
.prettyIndent = 2,
.errors = ErrorPrintBehavior::ThrowTopLevel,
});
}
};
@ -124,13 +127,17 @@ std::string removeWhitespace(std::string s)
{
s = chomp(s);
size_t n = s.find_first_not_of(" \n\r\t");
if (n != std::string::npos) s = std::string(s, n);
if (n != std::string::npos)
s = std::string(s, n);
return s;
}
NixRepl::NixRepl(const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
std::function<NixRepl::AnnotatedValues()> getValues, RunNix * runNix)
NixRepl::NixRepl(
const LookupPath & lookupPath,
nix::ref<Store> store,
ref<EvalState> state,
std::function<NixRepl::AnnotatedValues()> getValues,
RunNix * runNix)
: AbstractNixRepl(state)
, debugTraceIndex(0)
, getValues(getValues)
@ -188,7 +195,8 @@ ReplExitStatus NixRepl::mainLoop()
auto suspension = logger->suspend();
// When continuing input from previous lines, don't print a prompt, just align to the same
// number of chars as the prompt.
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
if (!interacter->getLine(
input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
// Ctrl-D should exit the debugger.
state->debugStop = false;
logger->cout("");
@ -200,14 +208,14 @@ ReplExitStatus NixRepl::mainLoop()
}
try {
switch (processLine(input)) {
case ProcessLineResult::Quit:
return ReplExitStatus::QuitAll;
case ProcessLineResult::Continue:
return ReplExitStatus::Continue;
case ProcessLineResult::PromptAgain:
break;
default:
unreachable();
case ProcessLineResult::Quit:
return ReplExitStatus::QuitAll;
case ProcessLineResult::Continue:
return ReplExitStatus::Continue;
case ProcessLineResult::PromptAgain:
break;
default:
unreachable();
}
} catch (IncompleteReplExpr &) {
continue;
@ -256,7 +264,8 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
/* This is a variable name; look it up in the current scope. */
StringSet::iterator i = varNames.lower_bound(cur);
while (i != varNames.end()) {
if (i->substr(0, cur.size()) != cur) break;
if (i->substr(0, cur.size()) != cur)
break;
completions.insert(prev + *i);
i++;
}
@ -275,11 +284,15 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
Expr * e = parseString(expr);
Value v;
e->eval(*state, *env, v);
state->forceAttrs(v, noPos, "while evaluating an attrset for the purpose of completion (this error should not be displayed; file an issue?)");
state->forceAttrs(
v,
noPos,
"while evaluating an attrset for the purpose of completion (this error should not be displayed; file an issue?)");
for (auto & i : *v.attrs()) {
std::string_view name = state->symbols[i.name];
if (name.substr(0, cur2.size()) != cur2) continue;
if (name.substr(0, cur2.size()) != cur2)
continue;
completions.insert(concatStrings(prev, expr, ".", name));
}
@ -297,24 +310,23 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
return completions;
}
// FIXME: DRY and match or use the parser
static bool isVarName(std::string_view s)
{
if (s.size() == 0) return false;
if (s.size() == 0)
return false;
char c = s[0];
if ((c >= '0' && c <= '9') || c == '-' || c == '\'') return false;
if ((c >= '0' && c <= '9') || c == '-' || c == '\'')
return false;
for (auto & i : s)
if (!((i >= 'a' && i <= 'z') ||
(i >= 'A' && i <= 'Z') ||
(i >= '0' && i <= '9') ||
i == '_' || i == '-' || i == '\''))
if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || (i >= '0' && i <= '9') || i == '_' || i == '-'
|| i == '\''))
return false;
return true;
}
StorePath NixRepl::getDerivationPath(Value & v) {
StorePath NixRepl::getDerivationPath(Value & v)
{
auto packageInfo = getDerivation(*state, v, false);
if (!packageInfo)
throw Error("expression does not evaluate to a derivation, so I can't build it");
@ -353,53 +365,50 @@ ProcessLineResult NixRepl::processLine(std::string line)
if (line[0] == ':') {
size_t p = line.find_first_of(" \n\r\t");
command = line.substr(0, p);
if (p != std::string::npos) arg = removeWhitespace(line.substr(p));
if (p != std::string::npos)
arg = removeWhitespace(line.substr(p));
} else {
arg = line;
}
if (command == ":?" || command == ":help") {
// FIXME: convert to Markdown, include in the 'nix repl' manpage.
std::cout
<< "The following commands are available:\n"
<< "\n"
<< " <expr> Evaluate and print expression\n"
<< " <x> = <expr> Bind expression to variable\n"
<< " :a, :add <expr> Add attributes from resulting set to scope\n"
<< " :b <expr> Build a derivation\n"
<< " :bl <expr> Build a derivation, creating GC roots in the\n"
<< " working directory\n"
<< " :e, :edit <expr> Open package or function in $EDITOR\n"
<< " :i <expr> Build derivation, then install result into\n"
<< " current profile\n"
<< " :l, :load <path> Load Nix expression and add it to scope\n"
<< " :lf, :load-flake <ref> Load Nix flake and add it to scope\n"
<< " :ll, :last-loaded Show most recently loaded variables added to scope\n"
<< " :p, :print <expr> Evaluate and print expression recursively\n"
<< " Strings are printed directly, without escaping.\n"
<< " :q, :quit Exit nix-repl\n"
<< " :r, :reload Reload all files\n"
<< " :sh <expr> Build dependencies of derivation, then start\n"
<< " nix-shell\n"
<< " :t <expr> Describe result of evaluation\n"
<< " :u <expr> Build derivation, then start nix-shell\n"
<< " :doc <expr> Show documentation of a builtin function\n"
<< " :log <expr> Show logs for a derivation\n"
<< " :te, :trace-enable [bool] Enable, disable or toggle showing traces for\n"
<< " errors\n"
<< " :?, :help Brings up this help menu\n"
;
std::cout << "The following commands are available:\n"
<< "\n"
<< " <expr> Evaluate and print expression\n"
<< " <x> = <expr> Bind expression to variable\n"
<< " :a, :add <expr> Add attributes from resulting set to scope\n"
<< " :b <expr> Build a derivation\n"
<< " :bl <expr> Build a derivation, creating GC roots in the\n"
<< " working directory\n"
<< " :e, :edit <expr> Open package or function in $EDITOR\n"
<< " :i <expr> Build derivation, then install result into\n"
<< " current profile\n"
<< " :l, :load <path> Load Nix expression and add it to scope\n"
<< " :lf, :load-flake <ref> Load Nix flake and add it to scope\n"
<< " :ll, :last-loaded Show most recently loaded variables added to scope\n"
<< " :p, :print <expr> Evaluate and print expression recursively\n"
<< " Strings are printed directly, without escaping.\n"
<< " :q, :quit Exit nix-repl\n"
<< " :r, :reload Reload all files\n"
<< " :sh <expr> Build dependencies of derivation, then start\n"
<< " nix-shell\n"
<< " :t <expr> Describe result of evaluation\n"
<< " :u <expr> Build derivation, then start nix-shell\n"
<< " :doc <expr> Show documentation of a builtin function\n"
<< " :log <expr> Show logs for a derivation\n"
<< " :te, :trace-enable [bool] Enable, disable or toggle showing traces for\n"
<< " errors\n"
<< " :?, :help Brings up this help menu\n";
if (state->debugRepl) {
std::cout
<< "\n"
<< " Debug mode commands\n"
<< " :env Show env stack\n"
<< " :bt, :backtrace Show trace stack\n"
<< " :st Show current trace\n"
<< " :st <idx> Change to another trace in the stack\n"
<< " :c, :continue Go until end of program, exception, or builtins.break\n"
<< " :s, :step Go one step\n"
;
std::cout << "\n"
<< " Debug mode commands\n"
<< " :env Show env stack\n"
<< " :bt, :backtrace Show trace stack\n"
<< " :st Show current trace\n"
<< " :st <idx> Change to another trace in the stack\n"
<< " :c, :continue Go until end of program, exception, or builtins.break\n"
<< " :s, :step Go one step\n";
}
}
@ -424,17 +433,18 @@ ProcessLineResult NixRepl::processLine(std::string line)
try {
// change the DebugTrace index.
debugTraceIndex = stoi(arg);
} catch (...) { }
} catch (...) {
}
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
if (idx == debugTraceIndex) {
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
showDebugTrace(std::cout, state->positions, i);
std::cout << std::endl;
printEnvBindings(*state, i.expr, i.env);
loadDebugTraceEnv(i);
break;
}
if (idx == debugTraceIndex) {
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
showDebugTrace(std::cout, state->positions, i);
std::cout << std::endl;
printEnvBindings(*state, i.expr, i.env);
loadDebugTraceEnv(i);
break;
}
}
}
@ -478,7 +488,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
Value v;
evalString(arg, v);
const auto [path, line] = [&] () -> std::pair<SourcePath, uint32_t> {
const auto [path, line] = [&]() -> std::pair<SourcePath, uint32_t> {
if (v.type() == nPath || v.type() == nString) {
NixStringContext context;
auto path = state->coerceToPath(noPos, v, context, "while evaluating the filename to edit");
@ -502,7 +512,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
// runProgram redirects stdout to a StringSink,
// using runProgram2 to allow editors to display their UI
runProgram2(RunOptions { .program = editor, .lookupPath = true, .args = args , .isInteractive = true });
runProgram2(RunOptions{.program = editor, .lookupPath = true, .args = args, .isInteractive = true});
// Reload right after exiting the editor
state->resetFileCache();
@ -533,9 +543,9 @@ ProcessLineResult NixRepl::processLine(std::string line)
if (command == ":b" || command == ":bl") {
state->store->buildPaths({
DerivedPath::Built {
DerivedPath::Built{
.drvPath = makeConstantStorePathRef(drvPath),
.outputs = OutputsSpec::All { },
.outputs = OutputsSpec::All{},
},
});
auto drv = state->store->readDerivation(drvPath);
@ -554,9 +564,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
runNix("nix-env", {"-i", drvPathRaw});
} else if (command == ":log") {
settings.readOnlyMode = true;
Finally roModeReset([&]() {
settings.readOnlyMode = false;
});
Finally roModeReset([&]() { settings.readOnlyMode = false; });
auto subs = getDefaultSubstituters();
subs.push_front(state->store);
@ -579,7 +587,8 @@ ProcessLineResult NixRepl::processLine(std::string line)
break;
}
}
if (!foundLog) throw Error("build log of '%s' is not available", drvPathRaw);
if (!foundLog)
throw Error("build log of '%s' is not available", drvPathRaw);
} else {
runNix("nix-shell", {drvPathRaw});
}
@ -642,9 +651,8 @@ ProcessLineResult NixRepl::processLine(std::string line)
for (auto & arg : args)
arg = "*" + arg + "*";
markdown +=
"**Synopsis:** `builtins." + (std::string) (*doc->name) + "` "
+ concatStringsSep(" ", args) + "\n\n";
markdown += "**Synopsis:** `builtins." + (std::string) (*doc->name) + "` " + concatStringsSep(" ", args)
+ "\n\n";
}
markdown += stripIndentation(doc->doc);
@ -685,11 +693,8 @@ ProcessLineResult NixRepl::processLine(std::string line)
else {
size_t p = line.find('=');
std::string name;
if (p != std::string::npos &&
p < line.size() &&
line[p + 1] != '=' &&
isVarName(name = removeWhitespace(line.substr(0, p))))
{
if (p != std::string::npos && p < line.size() && line[p + 1] != '='
&& isVarName(name = removeWhitespace(line.substr(0, p)))) {
Expr * e = parseString(line.substr(p + 1));
Value & v(*state->allocValue());
v.mkThunk(env, e);
@ -737,9 +742,13 @@ void NixRepl::loadFlake(const std::string & flakeRefS)
Value v;
flake::callFlake(*state,
flake::lockFlake(flakeSettings, *state, flakeRef,
flake::LockFlags {
flake::callFlake(
*state,
flake::lockFlake(
flakeSettings,
*state,
flakeRef,
flake::LockFlags{
.updateLockFile = false,
.useRegistries = !evalSettings.pureEval,
.allowUnlocked = !evalSettings.pureEval,
@ -748,7 +757,6 @@ void NixRepl::loadFlake(const std::string & flakeRefS)
addAttrsToScope(v);
}
void NixRepl::initEnv()
{
env = &state->allocEnv(envSize);
@ -771,7 +779,6 @@ void NixRepl::showLastLoaded()
}
}
void NixRepl::reloadFilesAndFlakes()
{
initEnv();
@ -780,7 +787,6 @@ void NixRepl::reloadFilesAndFlakes()
loadFlakes();
}
void NixRepl::loadFiles()
{
Strings old = loadedFiles;
@ -797,7 +803,6 @@ void NixRepl::loadFiles()
}
}
void NixRepl::loadFlakes()
{
Strings old = loadedFlakes;
@ -809,10 +814,12 @@ void NixRepl::loadFlakes()
}
}
void NixRepl::addAttrsToScope(Value & attrs)
{
state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }, "while evaluating an attribute set to be merged in the global scope");
state->forceAttrs(
attrs,
[&]() { return attrs.determinePos(noPos); },
"while evaluating an attribute set to be merged in the global scope");
if (displ + attrs.attrs()->size() >= envSize)
throw Error("environment full; cannot add more variables");
@ -847,7 +854,6 @@ void NixRepl::addAttrsToScope(Value & attrs)
notice("... and %1% more; view with :ll", attrs.attrs()->size() - max_print);
}
void NixRepl::addVarToScope(const Symbol name, Value & v)
{
if (displ >= envSize)
@ -860,13 +866,11 @@ void NixRepl::addVarToScope(const Symbol name, Value & v)
varNames.emplace(state->symbols[name]);
}
Expr * NixRepl::parseString(std::string s)
{
return state->parseExprFromString(std::move(s), state->rootPath("."), staticEnv);
}
void NixRepl::evalString(std::string s, Value & v)
{
Expr * e;
@ -884,46 +888,39 @@ void NixRepl::evalString(std::string s, Value & v)
state->forceValue(v, v.determinePos(noPos));
}
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);
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, RunNix * runNix)
const LookupPath & lookupPath,
nix::ref<Store> store,
ref<EvalState> state,
std::function<AnnotatedValues()> getValues,
RunNix * runNix)
{
return std::make_unique<NixRepl>(
lookupPath,
std::move(store),
state,
getValues,
runNix
);
return std::make_unique<NixRepl>(lookupPath, std::move(store), state, getValues, runNix);
}
ReplExitStatus AbstractNixRepl::runSimple(
ref<EvalState> evalState,
const ValMap & extraEnv)
ReplExitStatus AbstractNixRepl::runSimple(ref<EvalState> evalState, const ValMap & extraEnv)
{
auto getValues = [&]()->NixRepl::AnnotatedValues{
auto getValues = [&]() -> NixRepl::AnnotatedValues {
NixRepl::AnnotatedValues values;
return values;
};
LookupPath lookupPath = {};
auto repl = std::make_unique<NixRepl>(
lookupPath,
openStore(),
evalState,
getValues,
/*runNix=*/nullptr
);
lookupPath,
openStore(),
evalState,
getValues,
/*runNix=*/nullptr);
repl->initEnv();
@ -934,4 +931,4 @@ ReplExitStatus AbstractNixRepl::runSimple(
return repl->mainLoop();
}
}
} // namespace nix