Hi Peter,
On Mon, Dec 8, 2025 at 1:51 PM Peter Polidoro <[email protected]> wrote:
> Hi Guix,
>
> I’d like to float an idea for a new subcommand I have been
> thinking of
> developing, guix session, and get feedback on whether this is
> something
> that would make sense in Guix proper, or should live as an
> external
> tool.
>
> The basic motivation: many projects end up with long guix
> time-machine /
> guix shell incantations stashed in a README or Makefile. These are
> powerful, but they can be hard to remember and type, be slightly
> different in every project, are not easily introspectable from
> Scheme,
> and rarely produce any reusable “provenance artifact” of what was
> actually run.
>
> The proposal is to give that pattern a first-class, Scheme-native
> representation in Guix, in the same spirit as manifest.scm and
> channels.scm.
>
This has come up periodically over the years. I've wanted this for a decade
at this point. I started a prototype or two but didn't have the time/energy
to make it usable. 'guix environment' (the precursor to 'guix shell') and
call-with-container were my contributions toward this eventual goal. The
general idea was to make a better 'docker compose'.
> Today a project might say:
>
> guix time-machine -C channels.scm -- shell \
> -m manifest-dev.scm \
> --container --no-cwd \
> --share="$PWD=/workspace" \
> --preserve='^TERM$' \
> --preserve='^LANG$' \
> --preserve='^EDITOR$' \
> -- /bin/sh -lc 'cd /workspace && exec "$SHELL"'
>
> This pins Guix, sets up a container, mounts the project at
> /workspace,
> preserves a few useful environment variables, and then drops you
> into a
> shell in the right directory.
>
> With guix session, the same environment could be entered with:
>
> guix session shell dev
> or
> guix session shell -f session.scm -s dev
It's a bikeshed, but I think some other name would be better.
> Where dev is the name of a session defined in a project-local
> session.scm file.
>
> Here is a minimal example of such a file:
>
> ;; session.scm
> ;;
> ;; Evaluates to a list of session records.
> ;; Module names and record names here are illustrative.
>
> (use-modules
> (guix session)) ; hypothetical module
>
> (list
> (session
> (name "dev")
>
> ;; guix time-machine -C channels.scm
> (channels-file "channels.scm")
>
> ;; shell -m manifest-dev.scm
> (manifests '("manifest-dev.scm"))
>
>
We shouldn't be referring to file names here. These should be lists of
channel and manifest objects, respectively.
> ;; shell --container
> (container? #t)
>
> ;; --share="$PWD=/workspace"
> (mounts
> (list
> (mount
> (host ".") ; project root
> (target "/workspace")
> (writable? #t))))
>
> ;; where to land inside the session
> ;; (implemented with cd/exec or a future --chdir flag)
> (workdir "/workspace")
>
> ;; env-allow/env-set translate to environment + --preserve=…
> flags
> (env-allow '("TERM" "LANG"))
> (env-set '(("EDITOR" . "emacs")))))
>
> The intent is that guix session shell dev is equivalent to the
> long guix
> time-machine ... shell command above, but expressed as Scheme data
> instead of ad-hoc shell.
>
> The session file can contain multiple such sessions, e.g. "dev",
> "ci",
> "release", etc., all in one place.
>
> Why not just use a Makefile? It’s true that a Makefile can get you
> quite
> far:
>
> dev:
> guix time-machine -C channels.scm -- \
> shell -m manifest-dev.scm --container --no-cwd \
> --share="$PWD=/workspace" \
> --preserve='^TERM$$' --preserve='^LANG$$'
> --preserve='^EDITOR$$' \
> -- /bin/sh -lc 'cd /workspace && exec "$$SHELL"'
>
> A session.scm file, however, is declarative. Guix and other tools
> can
> inspect and manipulate it from Scheme. With session.scm and guix
> session
> there is a standard entry point:
>
> guix session shell # use default session
>
I think the subcommand alone should "do the right thing" for the default
case, so just 'guix session'.
> guix session shell dev
> guix session run ci -- make test
> guix session inspect
>
> A newcomer doesn’t have to guess whether the target is dev, shell,
> env,
> etc. across projects; the interface is the same.
I'm unsure about the usefulness of having named environments.
> One nice consequence of having a structured session is the ability
> to
> record a session snapshot each time you run: the original (session
> ...)
> record, the resolved channels commit used by time-machine, the
> final
> command, exit code, timestamp, etc.
>
> Such a snapshot could itself be a Scheme record, and be re-usable:
>
> guix session run --file=session-snapshot-2025-02-01.scm
Being able to save state and resume later, even if you did a 'guix pull' in
between, is a good thing to have. However, I don't think this is an
ergonomic way to do it. Running 'guix session' should just load a saved
session automatically, if there is one. Let the user run a command to
update when they want to do that.
> Before I spend time turning this into working code, I’d really
> appreciate any feedback.
>
> Is this something you would consider in-scope for Guix? Or does it
> feel
> like it should live as an external, Guile-based helper script
> instead?
>
This tool should be part of Guix. 100%
> Is the name session the best choice with session.scm as the
> conventional
> filename in a project root (analogous to manifest.scm and
> channels.scm)?
>
Don't worry about a name for now. Save that bikeshed for another day.
> Are the fields above the right level of abstraction?
>
> Any obvious things missing or that should be left out?
Services. Imagine you are developing a web application. You'd probably want
'guix session' to at least launch a database server. This would be
accomplished by starting a Shepherd daemon with a (perhaps containerized)
database service that keeps all of its state local to the project root
directory. The unfortunate thing here is that neither system nor home
services are the right fit. There would need to be a new service layer for
this tool. This is something I could rant about, but I will refrain. :)
> Do people already do something very similar that I should be aware
> of?
>
> If there’s interest, I’d plan to prototype this as an out-of-tree
> Guile
> script first (guix-session), and only then discuss integrating it
> properly as (guix scripts session) / (guix session) with tests and
> documentation.
>
> I’d be grateful for any comments, design criticism, or “this is a
> bad
> idea because…” feedback.
It's a great initiative! I'd be an enthusiastic early adopter.
- Dave