aboutsummaryrefslogtreecommitdiff
path: root/src/nix/develop.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-10-18 21:06:36 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-10-22 13:40:30 +0200
commitf9438fb64a223c05ebcfffa9706e1ca811a87d70 (patch)
tree87ca9a2190f46985a8ee795a62e558ef498b0f15 /src/nix/develop.cc
parent21830cb0447f2ad3d436a8b9df43222a787bb80e (diff)
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.
Diffstat (limited to 'src/nix/develop.cc')
-rw-r--r--src/nix/develop.cc53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 32669414b..7a5f7e218 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -185,7 +185,22 @@ struct Common : InstallableCommand, MixProfile
"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(
+ ref<Store> store,
const BuildEnvironment & buildEnvironment,
const Path & outputsDir = absPath(".") + "/outputs")
{
@@ -217,6 +232,8 @@ struct Common : InstallableCommand, MixProfile
out << "eval \"$shellHook\"\n";
+ auto script = out.str();
+
/* Substitute occurrences of output paths. */
auto outputs = buildEnvironment.env.find("outputs");
assert(outputs != buildEnvironment.env.end());
@@ -230,7 +247,33 @@ struct Common : InstallableCommand, MixProfile
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
@@ -348,6 +391,10 @@ struct CmdDevelop : Common, MixEnvironment
"To use a build environment previously recorded in a profile:",
"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 script = makeRcScript(buildEnvironment);
+ auto script = makeRcScript(store, buildEnvironment);
if (verbosity >= lvlDebug)
script += "set -x\n";
@@ -449,7 +496,7 @@ struct CmdPrintDevEnv : Common
stopProgressBar();
- std::cout << makeRcScript(buildEnvironment);
+ std::cout << makeRcScript(store, buildEnvironment);
}
};