Commit 0e062cb6 authored by Robert Hensing's avatar Robert Hensing
Browse files

nixos-rebuild: Add nixos-rebuild repl

Apologies to the non-flake users; your repl isn't quite as fancy,
but at least evaluates your config exactly as you would expect,
unlike flakes which are only evaluated impurely for now.
parent 584463c7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -55,6 +55,14 @@ which causes the new configuration (and previous ones created using
This can be useful to separate test configurations from "stable"
configurations.

A repl, or read-eval-print loop, is also available. You can inspect your configuration and use the Nix language with

```ShellSession
# nixos-rebuild repl
```

Your configuration is loaded into the `config` variable. Use tab for autocompletion, use the `:r` command to reload the configuration files. See `:?` or [`nix repl` in the Nix manual](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-repl.html) to learn more.

Finally, you can do

```ShellSession
+5 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
.Sh SYNOPSIS
.Nm
.Bro
.Cm switch | boot | test | build | dry-build | dry-activate | edit | build-vm | build-vm-with-bootloader | list-generations Op Fl -json
.Cm switch | boot | test | build | dry-build | dry-activate | edit | repl | build-vm | build-vm-with-bootloader | list-generations Op Fl -json
.Brc
.br
.Op Fl -upgrade | -upgrade-all
@@ -143,6 +143,10 @@ Opens
.Pa configuration.nix
in the default editor.
.
.It Cm repl
Opens the configuration in
.Ic nix repl Ns .
.
.It Cm build-vm
Build a script that starts a NixOS virtual machine with the desired
configuration. It leaves a symlink
+63 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ while [ "$#" -gt 0 ]; do
      --help)
        showSyntax
        ;;
      switch|boot|test|build|edit|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader|list-generations)
      switch|boot|test|build|edit|repl|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader|list-generations)
        if [ "$i" = dry-run ]; then i=dry-build; fi
        # exactly one action mandatory, bail out if multiple are given
        if [ -n "$action" ]; then showSyntax; fi
@@ -511,6 +511,68 @@ if [ "$action" = dry-build ]; then
    extraBuildFlags+=(--dry-run)
fi

if [ "$action" = repl ]; then
    # This is a very end user command, implemented using sub-optimal means.
    # You should feel free to improve its behavior, as well as resolve tech
    # debt in "breaking" ways. Humans adapt quite well.
    if [[ -z $flake ]]; then
        exec nix repl '<nixpkgs/nixos>' "${extraBuildFlags[@]}"
    else
        if [[ -n "${lockFlags[0]}" ]]; then
            # nix repl itself does not support locking flags
            log "nixos-rebuild repl does not support locking flags yet"
            exit 1
        fi
        d='$'
        q='"'
        bold="$(echo -e '\033[1m')"
        blue="$(echo -e '\033[34;1m')"
        attention="$(echo -e '\033[35;1m')"
        reset="$(echo -e '\033[0m')"
        # This nix repl invocation is impure, because usually the flakeref is.
        # For a solution that preserves the motd and custom scope, we need
        # something like https://github.com/NixOS/nix/issues/8679.
        exec nix repl --impure --expr "
          let flake = builtins.getFlake ''$flake'';
              configuration = flake.$flakeAttr;
              motd = ''
                $d{$q\n$q}
                Hello and welcome to the NixOS configuration
                    $flakeAttr
                    in $flake

                The following is loaded into nix repl's scope:

                    - ${blue}config${reset}   All option values
                    - ${blue}options${reset}  Option data and metadata
                    - ${blue}pkgs${reset}     Nixpkgs package set
                    - other module arguments

                    - ${blue}flake${reset}    Flake outputs, inputs and source info of $flake

                Use tab completion to browse around ${blue}config${reset}.

                Use ${bold}:r${reset} to ${bold}reload${reset} everything after making a change in the flake.
                  (assuming $flake is a mutable flake ref)

                See ${bold}:?${reset} for more repl commands.

                ${attention}warning:${reset} nixos-rebuild repl does not currently enforce pure evaluation.
              '';
              scope =
                assert configuration._type or null == ''configuration'';
                assert configuration.class or ''nixos'' == ''nixos'';
                configuration._module.args //
                configuration._module.specialArgs //
                {
                  inherit (configuration) config options;
                  inherit flake;
                };
          in builtins.seq scope builtins.trace motd scope
        " "${extraBuildFlags[@]}"
    fi
fi

if [ "$action" = list-generations ]; then
    if [ ! -L "$profile" ]; then
        log "No profile \`$(basename "$profile")' found"