forked from lix-project/lix
nix develop: Add --redirect flag to redirect dependencies
This is primarily useful if you're hacking simultaneously on a package and one of its dependencies. E.g. if you're hacking on Hydra and Nix, you would start a dev shell for Nix, and then a dev shell for Hydra as follows: $ nix develop \ --redirect .#hydraJobs.build.x86_64-linux.nix ~/Dev/nix/outputs/out \ --redirect .#hydraJobs.build.x86_64-linux.nix.dev ~/Dev/nix/outputs/dev (This assumes hydraJobs.build.x86_64-linux has a passthru.nix attribute. You can also use a store path.) This causes all references in the environment to those store paths to be rewritten to ~/Dev/nix/outputs/{out,dev}. Note: unfortunately, you may need to set LD_LIBRARY_PATH=~/Dev/nix/outputs/out/lib because Nixpkgs' ld-wrapper only adds -rpath entries for -L flags that point to the Nix store.
This commit is contained in:
parent
21830cb044
commit
f9438fb64a
|
@ -185,7 +185,22 @@ struct Common : InstallableCommand, MixProfile
|
||||||
"UID",
|
"UID",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> redirects;
|
||||||
|
|
||||||
|
Common()
|
||||||
|
{
|
||||||
|
addFlag({
|
||||||
|
.longName = "redirect",
|
||||||
|
.description = "redirect a store path to a mutable location",
|
||||||
|
.labels = {"installable", "outputs-dir"},
|
||||||
|
.handler = {[&](std::string installable, std::string outputsDir) {
|
||||||
|
redirects.push_back({installable, outputsDir});
|
||||||
|
}}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::string makeRcScript(
|
std::string makeRcScript(
|
||||||
|
ref<Store> store,
|
||||||
const BuildEnvironment & buildEnvironment,
|
const BuildEnvironment & buildEnvironment,
|
||||||
const Path & outputsDir = absPath(".") + "/outputs")
|
const Path & outputsDir = absPath(".") + "/outputs")
|
||||||
{
|
{
|
||||||
|
@ -217,6 +232,8 @@ struct Common : InstallableCommand, MixProfile
|
||||||
|
|
||||||
out << "eval \"$shellHook\"\n";
|
out << "eval \"$shellHook\"\n";
|
||||||
|
|
||||||
|
auto script = out.str();
|
||||||
|
|
||||||
/* Substitute occurrences of output paths. */
|
/* Substitute occurrences of output paths. */
|
||||||
auto outputs = buildEnvironment.env.find("outputs");
|
auto outputs = buildEnvironment.env.find("outputs");
|
||||||
assert(outputs != buildEnvironment.env.end());
|
assert(outputs != buildEnvironment.env.end());
|
||||||
|
@ -230,7 +247,33 @@ struct Common : InstallableCommand, MixProfile
|
||||||
rewrites.insert({from->second.quoted, outputsDir + "/" + outputName});
|
rewrites.insert({from->second.quoted, outputsDir + "/" + outputName});
|
||||||
}
|
}
|
||||||
|
|
||||||
return rewriteStrings(out.str(), rewrites);
|
/* Substitute redirects. */
|
||||||
|
for (auto & [installableS, dir] : redirects) {
|
||||||
|
dir = absPath(dir);
|
||||||
|
auto installable = parseInstallable(store, installableS);
|
||||||
|
auto buildable = installable->toBuildable();
|
||||||
|
auto doRedirect = [&](const StorePath & path)
|
||||||
|
{
|
||||||
|
auto from = store->printStorePath(path);
|
||||||
|
if (script.find(from) == std::string::npos)
|
||||||
|
warn("'%s' (path '%s') is not used by this build environment", installable->what(), from);
|
||||||
|
else {
|
||||||
|
printInfo("redirecting '%s' to '%s'", from, dir);
|
||||||
|
rewrites.insert({from, dir});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::visit(overloaded {
|
||||||
|
[&](const BuildableOpaque & bo) {
|
||||||
|
doRedirect(bo.path);
|
||||||
|
},
|
||||||
|
[&](const BuildableFromDrv & bfd) {
|
||||||
|
for (auto & [outputName, path] : bfd.outputs)
|
||||||
|
if (path) doRedirect(*path);
|
||||||
|
},
|
||||||
|
}, buildable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewriteStrings(script, rewrites);
|
||||||
}
|
}
|
||||||
|
|
||||||
Strings getDefaultFlakeAttrPaths() override
|
Strings getDefaultFlakeAttrPaths() override
|
||||||
|
@ -348,6 +391,10 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
"To use a build environment previously recorded in a profile:",
|
"To use a build environment previously recorded in a profile:",
|
||||||
"nix develop /tmp/my-shell"
|
"nix develop /tmp/my-shell"
|
||||||
},
|
},
|
||||||
|
Example{
|
||||||
|
"To replace all occurences of a store path with a writable directory:",
|
||||||
|
"nix develop --redirect nixpkgs#glibc.dev ~/my-glibc/outputs/dev"
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +404,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
|
|
||||||
auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");
|
auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");
|
||||||
|
|
||||||
auto script = makeRcScript(buildEnvironment);
|
auto script = makeRcScript(store, buildEnvironment);
|
||||||
|
|
||||||
if (verbosity >= lvlDebug)
|
if (verbosity >= lvlDebug)
|
||||||
script += "set -x\n";
|
script += "set -x\n";
|
||||||
|
@ -449,7 +496,7 @@ struct CmdPrintDevEnv : Common
|
||||||
|
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
|
|
||||||
std::cout << makeRcScript(buildEnvironment);
|
std::cout << makeRcScript(store, buildEnvironment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue