mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-28 16:46:16 +02:00
nix-env: Use SourcePath
This commit is contained in:
parent
7617d15458
commit
65e1e49cf7
1 changed files with 36 additions and 33 deletions
|
@ -44,7 +44,7 @@ typedef enum {
|
||||||
struct InstallSourceInfo
|
struct InstallSourceInfo
|
||||||
{
|
{
|
||||||
InstallSourceType type;
|
InstallSourceType type;
|
||||||
Path nixExprPath; /* for srcNixExprDrvs, srcNixExprs */
|
std::shared_ptr<SourcePath> nixExprPath; /* for srcNixExprDrvs, srcNixExprs */
|
||||||
Path profile; /* for srcProfile */
|
Path profile; /* for srcProfile */
|
||||||
std::string systemFilter; /* for srcNixExprDrvs */
|
std::string systemFilter; /* for srcNixExprDrvs */
|
||||||
Bindings * autoArgs;
|
Bindings * autoArgs;
|
||||||
|
@ -92,9 +92,11 @@ static bool parseInstallSourceOptions(Globals & globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool isNixExpr(const Path & path, struct stat & st)
|
static bool isNixExpr(const SourcePath & path, struct InputAccessor::Stat & st)
|
||||||
{
|
{
|
||||||
return S_ISREG(st.st_mode) || (S_ISDIR(st.st_mode) && pathExists(path + "/default.nix"));
|
return
|
||||||
|
st.type == InputAccessor::tRegular
|
||||||
|
|| (st.type == InputAccessor::tDirectory && (path + "default.nix").pathExists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,10 +104,10 @@ static constexpr size_t maxAttrs = 1024;
|
||||||
|
|
||||||
|
|
||||||
static void getAllExprs(EvalState & state,
|
static void getAllExprs(EvalState & state,
|
||||||
const Path & path, StringSet & seen, BindingsBuilder & attrs)
|
const SourcePath & path, StringSet & seen, BindingsBuilder & attrs)
|
||||||
{
|
{
|
||||||
StringSet namesSorted;
|
StringSet namesSorted;
|
||||||
for (auto & i : readDirectory(path)) namesSorted.insert(i.name);
|
for (auto & [name, _] : path.readDirectory()) namesSorted.insert(name);
|
||||||
|
|
||||||
for (auto & i : namesSorted) {
|
for (auto & i : namesSorted) {
|
||||||
/* Ignore the manifest.nix used by profiles. This is
|
/* Ignore the manifest.nix used by profiles. This is
|
||||||
|
@ -113,13 +115,16 @@ static void getAllExprs(EvalState & state,
|
||||||
are implemented using profiles). */
|
are implemented using profiles). */
|
||||||
if (i == "manifest.nix") continue;
|
if (i == "manifest.nix") continue;
|
||||||
|
|
||||||
Path path2 = path + "/" + i;
|
SourcePath path2 = path + i;
|
||||||
|
|
||||||
struct stat st;
|
InputAccessor::Stat st;
|
||||||
if (stat(path2.c_str(), &st) == -1)
|
try {
|
||||||
|
st = path2.accessor.lstat(path2.path.resolveSymlinks());
|
||||||
|
} catch (Error &) {
|
||||||
continue; // ignore dangling symlinks in ~/.nix-defexpr
|
continue; // ignore dangling symlinks in ~/.nix-defexpr
|
||||||
|
}
|
||||||
|
|
||||||
if (isNixExpr(path2, st) && (!S_ISREG(st.st_mode) || hasSuffix(path2, ".nix"))) {
|
if (isNixExpr(path2, st) && (st.type != InputAccessor::tRegular || hasSuffix(path2.baseName(), ".nix"))) {
|
||||||
/* Strip off the `.nix' filename suffix (if applicable),
|
/* Strip off the `.nix' filename suffix (if applicable),
|
||||||
otherwise the attribute cannot be selected with the
|
otherwise the attribute cannot be selected with the
|
||||||
`-A' option. Useful if you want to stick a Nix
|
`-A' option. Useful if you want to stick a Nix
|
||||||
|
@ -129,21 +134,20 @@ static void getAllExprs(EvalState & state,
|
||||||
attrName = std::string(attrName, 0, attrName.size() - 4);
|
attrName = std::string(attrName, 0, attrName.size() - 4);
|
||||||
if (!seen.insert(attrName).second) {
|
if (!seen.insert(attrName).second) {
|
||||||
std::string suggestionMessage = "";
|
std::string suggestionMessage = "";
|
||||||
if (path2.find("channels") != std::string::npos && path.find("channels") != std::string::npos) {
|
if (path2.path.abs().find("channels") != std::string::npos && path.path.abs().find("channels") != std::string::npos)
|
||||||
suggestionMessage = fmt("\nsuggestion: remove '%s' from either the root channels or the user channels", attrName);
|
suggestionMessage = fmt("\nsuggestion: remove '%s' from either the root channels or the user channels", attrName);
|
||||||
}
|
|
||||||
printError("warning: name collision in input Nix expressions, skipping '%1%'"
|
printError("warning: name collision in input Nix expressions, skipping '%1%'"
|
||||||
"%2%", path2, suggestionMessage);
|
"%2%", path2, suggestionMessage);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Load the expression on demand. */
|
/* Load the expression on demand. */
|
||||||
auto vArg = state.allocValue();
|
auto vArg = state.allocValue();
|
||||||
vArg->mkString(path2);
|
vArg->mkPath(path2);
|
||||||
if (seen.size() == maxAttrs)
|
if (seen.size() == maxAttrs)
|
||||||
throw Error("too many Nix expressions in directory '%1%'", path);
|
throw Error("too many Nix expressions in directory '%1%'", path);
|
||||||
attrs.alloc(attrName).mkApp(&state.getBuiltin("import"), vArg);
|
attrs.alloc(attrName).mkApp(&state.getBuiltin("import"), vArg);
|
||||||
}
|
}
|
||||||
else if (S_ISDIR(st.st_mode))
|
else if (st.type == InputAccessor::tDirectory)
|
||||||
/* `path2' is a directory (with no default.nix in it);
|
/* `path2' is a directory (with no default.nix in it);
|
||||||
recurse into it. */
|
recurse into it. */
|
||||||
getAllExprs(state, path2, seen, attrs);
|
getAllExprs(state, path2, seen, attrs);
|
||||||
|
@ -152,14 +156,12 @@ static void getAllExprs(EvalState & state,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
static void loadSourceExpr(EvalState & state, const SourcePath & path, Value & v)
|
||||||
{
|
{
|
||||||
struct stat st;
|
auto st = path.accessor.lstat(path.path.resolveSymlinks());
|
||||||
if (stat(path.c_str(), &st) == -1)
|
|
||||||
throw SysError("getting information about '%1%'", path);
|
|
||||||
|
|
||||||
if (isNixExpr(path, st))
|
if (isNixExpr(path, st))
|
||||||
state.evalFile(state.rootPath(path), v);
|
state.evalFile(path, v);
|
||||||
|
|
||||||
/* The path is a directory. Put the Nix expressions in the
|
/* The path is a directory. Put the Nix expressions in the
|
||||||
directory in a set, with the file name of each expression as
|
directory in a set, with the file name of each expression as
|
||||||
|
@ -167,7 +169,7 @@ static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
||||||
set flat, not nested, to make it easier for a user to have a
|
set flat, not nested, to make it easier for a user to have a
|
||||||
~/.nix-defexpr directory that includes some system-wide
|
~/.nix-defexpr directory that includes some system-wide
|
||||||
directory). */
|
directory). */
|
||||||
else if (S_ISDIR(st.st_mode)) {
|
else if (st.type == InputAccessor::tDirectory) {
|
||||||
auto attrs = state.buildBindings(maxAttrs);
|
auto attrs = state.buildBindings(maxAttrs);
|
||||||
attrs.alloc("_combineChannels").mkList(0);
|
attrs.alloc("_combineChannels").mkList(0);
|
||||||
StringSet seen;
|
StringSet seen;
|
||||||
|
@ -179,7 +181,7 @@ static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void loadDerivations(EvalState & state, Path nixExprPath,
|
static void loadDerivations(EvalState & state, const SourcePath & nixExprPath,
|
||||||
std::string systemFilter, Bindings & autoArgs,
|
std::string systemFilter, Bindings & autoArgs,
|
||||||
const std::string & pathPrefix, DrvInfos & elems)
|
const std::string & pathPrefix, DrvInfos & elems)
|
||||||
{
|
{
|
||||||
|
@ -390,7 +392,7 @@ static void queryInstSources(EvalState & state,
|
||||||
/* Load the derivations from the (default or specified)
|
/* Load the derivations from the (default or specified)
|
||||||
Nix expression. */
|
Nix expression. */
|
||||||
DrvInfos allElems;
|
DrvInfos allElems;
|
||||||
loadDerivations(state, instSource.nixExprPath,
|
loadDerivations(state, *instSource.nixExprPath,
|
||||||
instSource.systemFilter, *instSource.autoArgs, "", allElems);
|
instSource.systemFilter, *instSource.autoArgs, "", allElems);
|
||||||
|
|
||||||
elems = filterBySelector(state, allElems, args, newestOnly);
|
elems = filterBySelector(state, allElems, args, newestOnly);
|
||||||
|
@ -407,7 +409,7 @@ static void queryInstSources(EvalState & state,
|
||||||
case srcNixExprs: {
|
case srcNixExprs: {
|
||||||
|
|
||||||
Value vArg;
|
Value vArg;
|
||||||
loadSourceExpr(state, instSource.nixExprPath, vArg);
|
loadSourceExpr(state, *instSource.nixExprPath, vArg);
|
||||||
|
|
||||||
for (auto & i : args) {
|
for (auto & i : args) {
|
||||||
Expr * eFun = state.parseExprFromString(i, state.rootPath(absPath(".")));
|
Expr * eFun = state.parseExprFromString(i, state.rootPath(absPath(".")));
|
||||||
|
@ -462,7 +464,7 @@ static void queryInstSources(EvalState & state,
|
||||||
|
|
||||||
case srcAttrPath: {
|
case srcAttrPath: {
|
||||||
Value vRoot;
|
Value vRoot;
|
||||||
loadSourceExpr(state, instSource.nixExprPath, vRoot);
|
loadSourceExpr(state, *instSource.nixExprPath, vRoot);
|
||||||
for (auto & i : args) {
|
for (auto & i : args) {
|
||||||
Value & v(*findAlongAttrPath(state, i, *instSource.autoArgs, vRoot).first);
|
Value & v(*findAlongAttrPath(state, i, *instSource.autoArgs, vRoot).first);
|
||||||
getDerivations(state, v, "", *instSource.autoArgs, elems, true);
|
getDerivations(state, v, "", *instSource.autoArgs, elems, true);
|
||||||
|
@ -1015,7 +1017,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
installedElems = queryInstalled(*globals.state, globals.profile);
|
installedElems = queryInstalled(*globals.state, globals.profile);
|
||||||
|
|
||||||
if (source == sAvailable || compareVersions)
|
if (source == sAvailable || compareVersions)
|
||||||
loadDerivations(*globals.state, globals.instSource.nixExprPath,
|
loadDerivations(*globals.state, *globals.instSource.nixExprPath,
|
||||||
globals.instSource.systemFilter, *globals.instSource.autoArgs,
|
globals.instSource.systemFilter, *globals.instSource.autoArgs,
|
||||||
attrPath, availElems);
|
attrPath, availElems);
|
||||||
|
|
||||||
|
@ -1374,23 +1376,24 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
Operation op = 0;
|
Operation op = 0;
|
||||||
RepairFlag repair = NoRepair;
|
RepairFlag repair = NoRepair;
|
||||||
std::string file;
|
std::string file;
|
||||||
|
Path nixExprPath;
|
||||||
|
|
||||||
Globals globals;
|
Globals globals;
|
||||||
|
|
||||||
globals.instSource.type = srcUnknown;
|
globals.instSource.type = srcUnknown;
|
||||||
globals.instSource.nixExprPath = getHome() + "/.nix-defexpr";
|
nixExprPath = getHome() + "/.nix-defexpr";
|
||||||
globals.instSource.systemFilter = "*";
|
globals.instSource.systemFilter = "*";
|
||||||
|
|
||||||
if (!pathExists(globals.instSource.nixExprPath)) {
|
if (!pathExists(nixExprPath)) {
|
||||||
try {
|
try {
|
||||||
createDirs(globals.instSource.nixExprPath);
|
createDirs(nixExprPath);
|
||||||
replaceSymlink(
|
replaceSymlink(
|
||||||
fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()),
|
fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()),
|
||||||
globals.instSource.nixExprPath + "/channels");
|
nixExprPath + "/channels");
|
||||||
if (getuid() != 0)
|
if (getuid() != 0)
|
||||||
replaceSymlink(
|
replaceSymlink(
|
||||||
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir),
|
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir),
|
||||||
globals.instSource.nixExprPath + "/channels_root");
|
nixExprPath + "/channels_root");
|
||||||
} catch (Error &) { }
|
} catch (Error &) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,10 +1477,10 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.searchPath, store));
|
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.searchPath, store));
|
||||||
globals.state->repair = repair;
|
globals.state->repair = repair;
|
||||||
|
|
||||||
if (file != "")
|
globals.instSource.nixExprPath = std::make_shared<SourcePath>(
|
||||||
// FIXME: check that the accessor returned by
|
file != ""
|
||||||
// lookupFileArg() is the root FS.
|
? lookupFileArg(*globals.state, file)
|
||||||
globals.instSource.nixExprPath = lookupFileArg(*globals.state, file).path.abs();
|
: globals.state->rootPath(nixExprPath));
|
||||||
|
|
||||||
globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state);
|
globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue