nix dev-shell: Make it possible to enter a profile

For example:

  $ nix dev-shell --profile /tmp/my-shell dwarffs
  (later)
  $ nix dev-shell /tmp/my-shell
This commit is contained in:
Eelco Dolstra 2019-07-12 16:28:39 +02:00
parent 731bc65ec0
commit aa82f8b2d2
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 36 additions and 10 deletions

View file

@ -64,6 +64,13 @@ struct Installable
{ {
throw Error("argument '%s' cannot be evaluated", what()); throw Error("argument '%s' cannot be evaluated", what());
} }
/* Return a value only if this installable is a store path or a
symlink to it. */
virtual std::optional<Path> getStorePath()
{
return {};
}
}; };
struct EvalCommand : virtual StoreCommand, MixEvalArgs struct EvalCommand : virtual StoreCommand, MixEvalArgs

View file

@ -102,6 +102,11 @@ struct InstallableStorePath : Installable
{ {
return {{isDerivation(storePath) ? storePath : "", {{"out", storePath}}}}; return {{isDerivation(storePath) ? storePath : "", {{"out", storePath}}}};
} }
std::optional<Path> getStorePath() override
{
return storePath;
}
}; };
struct InstallableValue : Installable struct InstallableValue : Installable

View file

@ -174,17 +174,27 @@ struct Common : InstallableCommand, MixProfile
return {"devShell", "defaultPackage"}; return {"devShell", "defaultPackage"};
} }
Path getShellOutPath(ref<Store> store)
{
auto path = installable->getStorePath();
if (path && hasSuffix(*path, "-env"))
return *path;
else {
auto drvs = toDerivations(store, {installable});
if (drvs.size() != 1)
throw Error("'%s' needs to evaluate to a single derivation, but it evaluated to %d derivations",
installable->what(), drvs.size());
auto & drvPath = *drvs.begin();
return getDerivationEnvironment(store, store->derivationFromPath(drvPath));
}
}
BuildEnvironment getBuildEnvironment(ref<Store> store) BuildEnvironment getBuildEnvironment(ref<Store> store)
{ {
auto drvs = toDerivations(store, {installable}); auto shellOutPath = getShellOutPath(store);
if (drvs.size() != 1)
throw Error("'%s' needs to evaluate to a single derivation, but it evaluated to %d derivations",
installable->what(), drvs.size());
auto & drvPath = *drvs.begin();
auto shellOutPath = getDerivationEnvironment(store, store->derivationFromPath(drvPath));
updateProfile(shellOutPath); updateProfile(shellOutPath);
@ -212,7 +222,11 @@ struct CmdDevShell : Common
}, },
Example{ Example{
"To store the build environment in a profile:", "To store the build environment in a profile:",
"nix dev-shell --profile /tmp/my-shell" "nix dev-shell --profile /tmp/my-shell nixpkgs:hello"
},
Example{
"To use a build environment previously recorded in a profile:",
"nix dev-shell /tmp/my-shell"
}, },
}; };
} }