mirror of
https://github.com/numtide/devshell.git
synced 2024-09-11 13:45:25 +03:00
init compatibility with: nix bundle, nix run, lib.getExe (#306)
This makes all devshells compatible with `lib.getExe`, `nix run`and `nix bundle` by setting `meta.mainProgram` and creating an executable under `$out/bin/${meta.mainProgram}` Also remove the now unnecessary flakeApp workaround from the docs and replace it with updated instructions. My main motivation behind this is to create portable executable devshells via `nix bundle`. For example, to bundle the devShell of devshell itself into a static executable: ```sh nix bundle --bundler github:DavHau/nix-portable github:numtide/devshell#devShells.x86_64-linux.default ```
This commit is contained in:
parent
2d45b54ca4
commit
2c8e04e5c2
@ -118,9 +118,7 @@ nix-build shell.nix | cachix push <mycache>
|
||||
|
||||
### Runnable as a Nix application
|
||||
|
||||
Devshells are runnable as Nix applications (via `nix run`). This makes it
|
||||
possible to run commands defined in your devshell without entering a
|
||||
`nix-shell` or `nix develop` session:
|
||||
Devshells are runnable (via `nix run`). This makes it possible to run commands defined in your devshell without entering a `nix-shell` or `nix develop` session:
|
||||
|
||||
```sh
|
||||
nix run '.#<myapp>' -- <devshell-command> <and-args>
|
||||
@ -132,7 +130,7 @@ This project itself exposes a Nix application; you can try it out with:
|
||||
nix run 'github:numtide/devshell' -- hello
|
||||
```
|
||||
|
||||
See [here](docs/flake-app.md) for how to export your devshell as a flake app.
|
||||
See [here](docs/src/flake-app.md) for more details.
|
||||
|
||||
## TODO
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
# Using a devshell as a Nix application
|
||||
# Using a devshell as a Nix package
|
||||
|
||||
Devshells provide the attribute `flakeApp`, which contains an attribute set
|
||||
suitable for use as an entry in the `apps` flake output structure. Export this
|
||||
attribute under `apps.<system>.<myapp>`, and then you can run commands within
|
||||
your devshell as follows:
|
||||
Devshells can be treated as executable packages. This allows running commands inside a devshell's environment without having to enter it first via `nix-shell` or `nix develop`.
|
||||
|
||||
Each devshell in a flake can be executed using nix run:
|
||||
```sh
|
||||
nix run '.#devShells.<system>.<myshell>' -- <devshell-command> <and-args>
|
||||
```
|
||||
|
||||
To simplify this command further, re-expose the devshell under `packages.<system>.<myshell>`. This allows running it like this:
|
||||
|
||||
```sh
|
||||
nix run '.#<myapp>' -- <devshell-command> <and-args>
|
||||
nix run '.#<myshell>' -- <devshell-command> <and-args>
|
||||
```
|
||||
|
||||
For example, given the following `flake.nix`:
|
||||
@ -18,7 +22,7 @@ For example, given the following `flake.nix`:
|
||||
|
||||
outputs = { self, flake-utils, devshell, nixpkgs }:
|
||||
flake-utils.lib.eachDefaultSystem (system: {
|
||||
apps.devshell = self.outputs.devShells.${system}.default.flakeApp;
|
||||
packages.devshell = self.outputs.devShells.${system}.default;
|
||||
|
||||
devShells.default =
|
||||
let
|
||||
|
@ -36,6 +36,8 @@
|
||||
'nix-instantiate ./nixpkgs-mkshell.nix'
|
||||
'';
|
||||
};
|
||||
# expose devshell as an executable package
|
||||
default = devShells.default;
|
||||
};
|
||||
|
||||
devShells.default = devshell.fromTOML ./devshell.toml;
|
||||
@ -46,8 +48,6 @@
|
||||
nixpkgs = pkgs;
|
||||
};
|
||||
|
||||
apps.default = devShells.default.flakeApp;
|
||||
|
||||
checks =
|
||||
with pkgs.lib;
|
||||
pipe (import ./tests { inherit pkgs; }) [
|
||||
|
@ -2,6 +2,7 @@
|
||||
with lib;
|
||||
let
|
||||
cfg = config.devshell;
|
||||
sanitizedName = strings.sanitizeDerivationName cfg.name;
|
||||
|
||||
ansi = import ../nix/ansi.nix;
|
||||
|
||||
@ -186,14 +187,31 @@ let
|
||||
'';
|
||||
|
||||
# Builds the DEVSHELL_DIR with all the dependencies
|
||||
devshell_dir = pkgs.buildEnv {
|
||||
name = "devshell-dir";
|
||||
devshell_dir = pkgs.buildEnv rec {
|
||||
name = "${sanitizedName}-dir";
|
||||
paths = cfg.packages;
|
||||
postBuild = ''
|
||||
substitute ${envBash} $out/env.bash --subst-var-by DEVSHELL_DIR $out
|
||||
substitute ${entrypoint} $out/entrypoint --subst-var-by DEVSHELL_DIR $out
|
||||
chmod +x $out/entrypoint
|
||||
|
||||
mainProgram="${meta.mainProgram}"
|
||||
# ensure mainProgram doesn't collide
|
||||
if [ -e "$out/bin/$mainProgram" ]; then
|
||||
echo "Warning: Cannot create entry point for this devshell at '\$out/bin/$mainProgram' because an executable with that name already exists." >&2
|
||||
echo "Set meta.mainProgram to something else than '$mainProgram'." >&2
|
||||
else
|
||||
# if $out/bin is a single symlink, transform it into a directory tree
|
||||
# (buildEnv does that when there is only one package in the environment)
|
||||
if [ -L "$out/bin" ]; then
|
||||
mv "$out/bin" bin-tmp
|
||||
mkdir "$out/bin"
|
||||
ln -s bin-tmp/* "$out/bin/"
|
||||
fi
|
||||
ln -s $out/entrypoint "$out/bin/$mainProgram"
|
||||
fi
|
||||
'';
|
||||
meta.mainProgram = config.meta.mainProgram or sanitizedName;
|
||||
};
|
||||
|
||||
# Returns a list of all the input derivation ... for a derivation.
|
||||
@ -421,11 +439,16 @@ in
|
||||
|
||||
# Use a naked derivation to limit the amount of noise passed to nix-shell.
|
||||
shell = mkNakedShell {
|
||||
name = strings.sanitizeDerivationName cfg.name;
|
||||
inherit (cfg) meta;
|
||||
name = sanitizedName;
|
||||
meta =
|
||||
# set default for meta.mainProgram here to gain compatibility with:
|
||||
# `lib.getExe`, `nix run`, `nix bundle`, etc.
|
||||
{mainProgram = cfg.package.meta.mainProgram;}
|
||||
// cfg.meta;
|
||||
profile = cfg.package;
|
||||
passthru = {
|
||||
inherit config;
|
||||
# keep flakeApp attribute for backward compatibility
|
||||
flakeApp = mkFlakeApp "${devshell_dir}/entrypoint";
|
||||
hook = mkSetupHook "${devshell_dir}/env.bash";
|
||||
inherit (config._module.args) pkgs;
|
||||
|
@ -80,4 +80,20 @@
|
||||
# Packages available through entrypoint in pure mode
|
||||
entrypoint_clean --pure --env-bin env --prj-root . /bin/sh -c 'type -p git'
|
||||
'';
|
||||
|
||||
# Use devshell as executable
|
||||
devshell-executable-1 =
|
||||
let
|
||||
shell = devshell.mkShell {
|
||||
devshell.name = "devshell-executable-1";
|
||||
devshell.packages = [ pkgs.hello ];
|
||||
};
|
||||
in
|
||||
runTest "devshell-executable-1" { } ''
|
||||
# Devshell is executable
|
||||
assert -x ${pkgs.lib.getExe shell}
|
||||
|
||||
# Packages inside the devshell are executable
|
||||
${pkgs.lib.getExe shell} hello
|
||||
'';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user