libcmd: add --call-package flag

This commit is contained in:
Max Headroom 2023-06-28 19:06:25 +02:00
parent 5e5b43ed22
commit 11e229be73
2 changed files with 22 additions and 5 deletions

View file

@ -100,6 +100,7 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
{
std::optional<Path> file;
std::optional<std::string> expr;
std::optional<Path> callPackageFile;
std::optional<std::string> applyToInstallable;
std::optional<std::string> installableOverrideAttrs;
std::optional<std::string> installableWithPackages;

View file

@ -207,6 +207,19 @@ SourceExprCommand::SourceExprCommand()
.handler = {&expr}
});
addFlag({
.longName = "call-package",
.shortName = 'C',
.description =
"Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the callPackageable Nix expression stored in *file*. "
"The `callPackage` function is taken from `<nixpkgs>`. "
"Implies `--impure`.",
.category = installablesCategory,
.labels = {"file"},
.handler = {&callPackageFile},
.completer = completePath
});
addFlag({
.longName = "apply-to-installable",
.description = "Apply the function *expr* to each installable.",
@ -542,12 +555,12 @@ Installables SourceExprCommand::parseInstallables(
auto doModifyInstallable = applyOverrides && ( applyToInstallable
|| installableOverrideAttrs || installableWithPackages || overrideArgs.size() > 0 );
if (nestedIsExprOk && (file || expr)) {
if (file && expr)
throw UsageError("'--file' and '--expr' are exclusive");
if (nestedIsExprOk && (file || expr || callPackageFile)) {
if ((file && expr) || (file && callPackageFile) || (expr && callPackageFile))
throw UsageError("'--file', '--expr' and '--call-package' are exclusive");
// FIXME: backward compatibility hack
if (file) evalSettings.pureEval = false;
if (file || callPackageFile) evalSettings.pureEval = false;
auto state = getEvalState();
auto vFile = state->allocValue();
@ -558,7 +571,10 @@ Installables SourceExprCommand::parseInstallables(
}
else if (file)
state->evalFile(lookupFileArg(*state, *file), *vFile);
else {
else if (callPackageFile) {
auto e = state->parseExprFromString(fmt("(import <nixpkgs> {}).callPackage %s {}", CanonPath::fromCwd(*callPackageFile)), state->rootPath(CanonPath::fromCwd()));
state->eval(e, *vFile);
} else {
auto e = state->parseExprFromString(*expr, state->rootPath(CanonPath::fromCwd()));
state->eval(e, *vFile);
}