on master help sign in
Auto-add the host shell package so container.nix needn't list it
commit686fc14a9879b2c0f433f440c4b7d38ed0e408a3 authoriko <mail@iko.soy> dateSat 27 Jun 2026, 21:40 (3 months ago) parentbd3aac1
3 files changed+22−12
README.md+2−1 c+8−8 flake.nix+12−3
README.md+2−1
@@ -32,7 +32,6 @@ is **required**; there is no default set.
3232```nix
3333# ./container.nix
3434{ pkgs, nur }: with pkgs; [
35− fish # `init` runs your host shell — include it (here, fish)
3635 coreutils
3736 git
3837 go
@@ -40,6 +39,8 @@ is **required**; there is no default set.
4039]
4140```
4241
42+Your host shell (`$SHELL`) is added and run automatically — no need to list it.
43+
4344Point at a different file with `-c`/`--config`:
4445
4546```sh
c+8−8
@@ -27,12 +27,17 @@ switch $argv[1]
2727 exit 1
2828 end
2929
30− # Build an image with exactly the packages from $config, into a temp
31− # dir, load it, then clean up.
30+ # Host login shell (by name): run as the container cmd and added to the
31+ # image automatically, so it needn't be listed in container.nix.
32+ set -l shell fish
33+ test -n "$SHELL"; and set shell (path basename $SHELL)
34+
35+ # Build an image with the packages from $config (plus the shell) into a
36+ # temp dir, load it, then clean up.
3237 set -l tmp (mktemp -d)
3338 set -l archive $tmp/image.tar.gz
3439 set -lx NIX_CONTAINER_PKGS (path resolve $config)
35− set -l expr "(builtins.getFlake \"$flake\").lib.\${builtins.currentSystem}.copyWith (import (/. + builtins.getEnv \"NIX_CONTAINER_PKGS\"))"
40+ set -l expr "(builtins.getFlake \"$flake\").lib.\${builtins.currentSystem}.copyWithShell \"$shell\" (import (/. + builtins.getEnv \"NIX_CONTAINER_PKGS\"))"
3641 set -l copyer (nix build --impure --no-link --print-out-paths --expr "$expr")
3742 set -l rc $status
3843 if test $rc -eq 0
@@ -51,11 +56,6 @@ switch $argv[1]
5156 set -l mounts -v "$PWD:/workspace"
5257 test -d $HOME/.config; and set -a mounts -v "$HOME/.config:/root/.config"
5358
54− # Run the host's login shell (by name) instead of the image's default
55− # cmd. The shell must be in the package set.
56− set -l shell fish
57− test -n "$SHELL"; and set shell (path basename $SHELL)
58−
5959 # Replace any existing container of the same name.
6060 container rm --force $name 2>/dev/null
6161 container create --name $name --ssh -it --cwd /workspace $mounts $argv $image /bin/$shell
flake.nix+12−3
@@ -77,9 +77,9 @@
7777 imageTag = "latest";
7878
7979 # Build the OCI image from a `{ pkgs, nur }: [ ... ]` package function.
80− # The default `cmd` is /bin/fish, but `c init` runs your host login
81− # shell instead — so include that shell in the package set (a missing
82− # shell is warned about below).
80+ # The default `cmd` is /bin/fish; `c init` runs your host login shell
81+ # instead and adds it automatically (see `copyWithShell`). The warning
82+ # below only catches an image left with no shell at all.
8383 mkImage =
8484 packages:
8585 let
@@ -153,6 +153,15 @@
153153 # skopeo copy app (`skopeo copy nix:<image> "$@"`) for an image built
154154 # from a `{ pkgs, nur }: [ ... ]` function.
155155 copyWith = packages: (mkImage packages).copyTo;
156+ # Like `copyWith`, but also adds the named shell package (when it
157+ # exists in nixpkgs) so `c init` can run the host shell without it
158+ # being listed in `container.nix`.
159+ copyWithShell =
160+ shell: packages:
161+ (mkImage (
162+ { pkgs, nur }:
163+ packages { inherit pkgs nur; } ++ pkgs.lib.optional (pkgs ? ${shell}) pkgs.${shell}
164+ )).copyTo;
156165 };
157166 }
158167 );