diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-10-18 21:06:36 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-10-22 13:40:30 +0200 |
commit | f9438fb64a223c05ebcfffa9706e1ca811a87d70 (patch) | |
tree | 87ca9a2190f46985a8ee795a62e558ef498b0f15 /src/nix/develop.cc | |
parent | 21830cb0447f2ad3d436a8b9df43222a787bb80e (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.cc | 53 |
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); } }; |