forked from lix-project/lix
nix: Make -f work for compatibility
This commit is contained in:
parent
9b7eac332b
commit
101d964a59
|
@ -74,23 +74,20 @@ struct Installable
|
||||||
struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs
|
struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs
|
||||||
{
|
{
|
||||||
std::optional<Path> file;
|
std::optional<Path> file;
|
||||||
std::optional<std::string> flakeUri;
|
|
||||||
|
|
||||||
SourceExprCommand();
|
SourceExprCommand();
|
||||||
|
|
||||||
/* Return a value representing the Nix expression from which we
|
|
||||||
are installing. This is either the file specified by ‘--file’,
|
|
||||||
or an attribute set constructed from $NIX_PATH, e.g. ‘{ nixpkgs
|
|
||||||
= import ...; bla = import ...; }’. */
|
|
||||||
Value * getSourceExpr(EvalState & state);
|
|
||||||
|
|
||||||
ref<EvalState> getEvalState();
|
ref<EvalState> getEvalState();
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Installable>> parseInstallables(
|
||||||
|
ref<Store> store, std::vector<std::string> ss);
|
||||||
|
|
||||||
|
std::shared_ptr<Installable> parseInstallable(
|
||||||
|
ref<Store> store, const std::string & installable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<EvalState> evalState;
|
std::shared_ptr<EvalState> evalState;
|
||||||
|
|
||||||
Value * vSourceExpr = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RealiseMode { Build, NoBuild, DryRun };
|
enum RealiseMode { Build, NoBuild, DryRun };
|
||||||
|
@ -108,8 +105,6 @@ struct InstallablesCommand : virtual Args, SourceExprCommand
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
|
||||||
virtual bool useDefaultInstallables() { return true; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector<std::string> _installables;
|
std::vector<std::string> _installables;
|
||||||
|
@ -148,8 +143,6 @@ public:
|
||||||
virtual void run(ref<Store> store, Paths storePaths) = 0;
|
virtual void run(ref<Store> store, Paths storePaths) = 0;
|
||||||
|
|
||||||
void run(ref<Store> store) override;
|
void run(ref<Store> store) override;
|
||||||
|
|
||||||
bool useDefaultInstallables() override { return !all; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A command that operates on exactly one store path. */
|
/* A command that operates on exactly one store path. */
|
||||||
|
@ -174,10 +167,6 @@ struct RegisterCommand
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Installable> parseInstallable(
|
|
||||||
SourceExprCommand & cmd, ref<Store> store, const std::string & installable,
|
|
||||||
bool useDefaultInstallables);
|
|
||||||
|
|
||||||
Buildables build(ref<Store> store, RealiseMode mode,
|
Buildables build(ref<Store> store, RealiseMode mode,
|
||||||
std::vector<std::shared_ptr<Installable>> installables);
|
std::vector<std::shared_ptr<Installable>> installables);
|
||||||
|
|
||||||
|
|
|
@ -19,33 +19,10 @@ SourceExprCommand::SourceExprCommand()
|
||||||
.shortName('f')
|
.shortName('f')
|
||||||
.longName("file")
|
.longName("file")
|
||||||
.label("file")
|
.label("file")
|
||||||
.description("evaluate FILE rather than use the default installation source")
|
.description("evaluate a set of attributes from FILE (deprecated)")
|
||||||
.dest(&file);
|
.dest(&file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value * SourceExprCommand::getSourceExpr(EvalState & state)
|
|
||||||
{
|
|
||||||
if (vSourceExpr) return vSourceExpr;
|
|
||||||
|
|
||||||
vSourceExpr = state.allocValue();
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
state.evalFile(lookupFileArg(state, *file), *vSourceExpr);
|
|
||||||
else {
|
|
||||||
// FIXME: remove "impure" hack, call some non-user-accessible
|
|
||||||
// variant of getFlake instead.
|
|
||||||
auto fun = state.parseExprFromString(
|
|
||||||
"builtins.mapAttrs (flakeName: flakeInfo:"
|
|
||||||
" (getFlake (\"impure:\" + flakeInfo.uri)).${flakeName}.provides.packages or {})", "/");
|
|
||||||
auto vFun = state.allocValue();
|
|
||||||
state.eval(fun, *vFun);
|
|
||||||
auto vRegistry = makeFlakeRegistryValue(state);
|
|
||||||
mkApp(*vSourceExpr, *vFun, *vRegistry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vSourceExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref<EvalState> SourceExprCommand::getEvalState()
|
ref<EvalState> SourceExprCommand::getEvalState()
|
||||||
{
|
{
|
||||||
if (!evalState)
|
if (!evalState)
|
||||||
|
@ -140,24 +117,20 @@ struct InstallableExpr : InstallableValue
|
||||||
|
|
||||||
struct InstallableAttrPath : InstallableValue
|
struct InstallableAttrPath : InstallableValue
|
||||||
{
|
{
|
||||||
|
Value * v;
|
||||||
std::string attrPath;
|
std::string attrPath;
|
||||||
|
|
||||||
InstallableAttrPath(SourceExprCommand & cmd, const std::string & attrPath)
|
InstallableAttrPath(SourceExprCommand & cmd, Value * v, const std::string & attrPath)
|
||||||
: InstallableValue(cmd), attrPath(attrPath)
|
: InstallableValue(cmd), v(v), attrPath(attrPath)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::string what() override { return attrPath; }
|
std::string what() override { return attrPath; }
|
||||||
|
|
||||||
Value * toValue(EvalState & state) override
|
Value * toValue(EvalState & state) override
|
||||||
{
|
{
|
||||||
auto source = cmd.getSourceExpr(state);
|
auto vRes = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), *v);
|
||||||
|
state.forceValue(*vRes);
|
||||||
Bindings & autoArgs = *cmd.getAutoArgs(state);
|
return vRes;
|
||||||
|
|
||||||
Value * v = findAlongAttrPath(state, attrPath, autoArgs, *source);
|
|
||||||
state.forceValue(*v);
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,41 +175,47 @@ struct InstallableFlake : InstallableValue
|
||||||
std::string attrRegex = R"([A-Za-z_][A-Za-z0-9-_+]*)";
|
std::string attrRegex = R"([A-Za-z_][A-Za-z0-9-_+]*)";
|
||||||
static std::regex attrPathRegex(fmt(R"(%1%(\.%1%)*)", attrRegex));
|
static std::regex attrPathRegex(fmt(R"(%1%(\.%1%)*)", attrRegex));
|
||||||
|
|
||||||
static std::vector<std::shared_ptr<Installable>> parseInstallables(
|
std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
|
||||||
SourceExprCommand & cmd, ref<Store> store, std::vector<std::string> ss, bool useDefaultInstallables)
|
ref<Store> store, std::vector<std::string> ss)
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<Installable>> result;
|
std::vector<std::shared_ptr<Installable>> result;
|
||||||
|
|
||||||
if (ss.empty() && useDefaultInstallables) {
|
if (file) {
|
||||||
if (cmd.file == "")
|
// FIXME: backward compatibility hack
|
||||||
cmd.file = ".";
|
evalSettings.pureEval = false;
|
||||||
|
|
||||||
|
auto state = getEvalState();
|
||||||
|
auto vFile = state->allocValue();
|
||||||
|
state->evalFile(lookupFileArg(*state, *file), *vFile);
|
||||||
|
|
||||||
|
if (ss.empty())
|
||||||
ss = {""};
|
ss = {""};
|
||||||
}
|
|
||||||
|
for (auto & s : ss)
|
||||||
|
result.push_back(std::make_shared<InstallableAttrPath>(*this, vFile, s));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
for (auto & s : ss) {
|
for (auto & s : ss) {
|
||||||
|
|
||||||
|
size_t colon;
|
||||||
|
|
||||||
if (s.compare(0, 1, "(") == 0)
|
if (s.compare(0, 1, "(") == 0)
|
||||||
result.push_back(std::make_shared<InstallableExpr>(cmd, s));
|
result.push_back(std::make_shared<InstallableExpr>(*this, s));
|
||||||
|
|
||||||
/*
|
else if ((colon = s.rfind(':')) != std::string::npos) {
|
||||||
else if (s.find('/') != std::string::npos) {
|
|
||||||
|
|
||||||
auto path = store->toStorePath(store->followLinksToStore(s));
|
|
||||||
|
|
||||||
if (store->isStorePath(path))
|
|
||||||
result.push_back(std::make_shared<InstallableStorePath>(path));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
else {
|
|
||||||
auto colon = s.rfind(':');
|
|
||||||
if (colon != std::string::npos) {
|
|
||||||
auto flakeRef = std::string(s, 0, colon);
|
auto flakeRef = std::string(s, 0, colon);
|
||||||
auto attrPath = std::string(s, colon + 1);
|
auto attrPath = std::string(s, colon + 1);
|
||||||
result.push_back(std::make_shared<InstallableFlake>(cmd, FlakeRef(flakeRef), attrPath));
|
result.push_back(std::make_shared<InstallableFlake>(*this, FlakeRef(flakeRef), attrPath));
|
||||||
} else {
|
|
||||||
result.push_back(std::make_shared<InstallableFlake>(cmd, FlakeRef("nixpkgs"), s));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (s.find('/') != std::string::npos) {
|
||||||
|
auto path = store->toStorePath(store->followLinksToStore(s));
|
||||||
|
result.push_back(std::make_shared<InstallableStorePath>(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
result.push_back(std::make_shared<InstallableFlake>(*this, FlakeRef("nixpkgs"), s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -247,15 +226,15 @@ static std::vector<std::shared_ptr<Installable>> parseInstallables(
|
||||||
throw UsageError("don't know what to do with argument '%s'", s);
|
throw UsageError("don't know what to do with argument '%s'", s);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Installable> parseInstallable(
|
std::shared_ptr<Installable> SourceExprCommand::parseInstallable(
|
||||||
SourceExprCommand & cmd, ref<Store> store, const std::string & installable,
|
ref<Store> store, const std::string & installable)
|
||||||
bool useDefaultInstallables)
|
|
||||||
{
|
{
|
||||||
auto installables = parseInstallables(cmd, store, {installable}, false);
|
auto installables = parseInstallables(store, {installable});
|
||||||
assert(installables.size() == 1);
|
assert(installables.size() == 1);
|
||||||
return installables.front();
|
return installables.front();
|
||||||
}
|
}
|
||||||
|
@ -342,12 +321,12 @@ PathSet toDerivations(ref<Store> store,
|
||||||
|
|
||||||
void InstallablesCommand::prepare()
|
void InstallablesCommand::prepare()
|
||||||
{
|
{
|
||||||
installables = parseInstallables(*this, getStore(), _installables, useDefaultInstallables());
|
installables = parseInstallables(getStore(), _installables);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallableCommand::prepare()
|
void InstallableCommand::prepare()
|
||||||
{
|
{
|
||||||
installable = parseInstallable(*this, getStore(), _installable, false);
|
installable = parseInstallable(getStore(), _installable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,9 @@ struct CmdSearch : SourceExprCommand, MixJSON
|
||||||
|
|
||||||
auto cache = writeCache ? std::make_unique<JSONObject>(jsonCacheFile, false) : nullptr;
|
auto cache = writeCache ? std::make_unique<JSONObject>(jsonCacheFile, false) : nullptr;
|
||||||
|
|
||||||
doExpr(getSourceExpr(*state), "", true, cache.get());
|
// FIXME
|
||||||
|
throw Error("NOT IMPLEMENTED");
|
||||||
|
//doExpr(getSourceExpr(*state), "", true, cache.get());
|
||||||
|
|
||||||
} catch (std::exception &) {
|
} catch (std::exception &) {
|
||||||
/* Fun fact: catching std::ios::failure does not work
|
/* Fun fact: catching std::ios::failure does not work
|
||||||
|
|
|
@ -74,9 +74,9 @@ struct CmdWhyDepends : SourceExprCommand
|
||||||
|
|
||||||
void run(ref<Store> store) override
|
void run(ref<Store> store) override
|
||||||
{
|
{
|
||||||
auto package = parseInstallable(*this, store, _package, false);
|
auto package = parseInstallable(store, _package);
|
||||||
auto packagePath = toStorePath(store, Build, package);
|
auto packagePath = toStorePath(store, Build, package);
|
||||||
auto dependency = parseInstallable(*this, store, _dependency, false);
|
auto dependency = parseInstallable(store, _dependency);
|
||||||
auto dependencyPath = toStorePath(store, NoBuild, dependency);
|
auto dependencyPath = toStorePath(store, NoBuild, dependency);
|
||||||
auto dependencyPathHash = storePathToHash(dependencyPath);
|
auto dependencyPathHash = storePathToHash(dependencyPath);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue