From c8cb60b8a15c90b2bbc416c182532620602edb48 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Sun, 26 Feb 2023 23:10:06 +0100 Subject: [PATCH] home-manager: add `init` command to main tool The init command is essentially the old install script but integrated into the home-manager tool. This simplifies things slightly since we can use the existing code infrastructure. The init command is Nix flake aware in the sense that, if we detect that the user's Nix setup supports flakes, then we also create an initial `flake.nix` file. Finally, we update the installation instructions for the Nix flakes standalone setup to use the new init command. Zsh completion update provided by Anund . --- docs/man-home-manager.xml | 33 ++++++ docs/nix-flakes.adoc | 79 +++++++++++-- docs/release-notes/rl-2305.adoc | 12 +- home-manager/completion.bash | 75 +++++++----- home-manager/completion.zsh | 6 + home-manager/home-manager | 192 +++++++++++++++++++++++++++++- home-manager/install.nix | 71 +---------- home-manager/po/home-manager.pot | 195 ++++++++++++++++--------------- modules/po/hm-modules.pot | 2 +- 9 files changed, 460 insertions(+), 205 deletions(-) diff --git a/docs/man-home-manager.xml b/docs/man-home-manager.xml index 49c8ac61..71c34b0f 100644 --- a/docs/man-home-manager.xml +++ b/docs/man-home-manager.xml @@ -17,6 +17,10 @@ build + + init --switch dir + + instantiate @@ -218,6 +222,35 @@ + + + [] [dir] + + + + Generates an initial home.nix file for the + current user. If Nix flakes are enabled, then this command also + generates a flake.nix file. + + + If a path dir is given then the + configuration will be generated in that directory. Otherwise, the + configuration will be generated in + ~/.config/home-manager. The output directory will + be created if it does not exist. + + + If the option is given, then the generated + configuration is activated. + + + Note, this command will not overwrite any existing files. It is + therefore safe to initialize a configuration, edit it, and then re-run + the command with + enabled to activate the configuration. + + + diff --git a/docs/nix-flakes.adoc b/docs/nix-flakes.adoc index 73556d93..ded9e750 100644 --- a/docs/nix-flakes.adoc +++ b/docs/nix-flakes.adoc @@ -70,6 +70,71 @@ writing a Home Manager configuration. [[sec-flakes-standalone]] === Standalone setup +The installation procedure for the standalone version of Home Manager +is currently different for the unstable and stable branch. +Therefore, if you are tracking the Nixpkgs or NixOS unstable please go to +<>, +and if you track Nixpkgs or NixOS version 22.11 please go to +<>. + +[[sec-flakes-standalone-unstable]] +==== Unstable Version + +To prepare an initial Home Manager configuration for your logged in user, +you can run the Home Manager `init` command directly from its flake. + +For example, to generate and activate a basic configuration run the command + +[source,console] +$ nix run home-manager/master -- init --switch + +This will generate a `flake.nix` and a `home.nix` file in +`~/.config/home-manager`, creating the directory if it does not exist. + +If you omit the `--switch` option then the activation will not happen. +This is useful if you want to inspect and edit the configuration before activating it. + +[source,console] +---- +$ nix run home-manager/master -- init +$ # Edit files in ~/.config/home-manager +$ nix run home-manager/master -- init --switch +---- + +After the initial activation has completed successfully then building +and activating your flake-based configuration is as simple as + +[source,console] +$ home-manager switch + +It is possible to override the default configuration directory, if you want. +For example, + +[source,console] +---- +$ nix run home-manager/master -- init --switch ~/hmconf +$ # And after the initial activation. +$ home-manager switch --flake ~/hmconf +---- + +[NOTE] +==== +The flake inputs are not automatically updated by Home Manager. +You need to use the standard `nix flake update` command for that. + +If you only want to update a single flake input, +then the command `nix flake lock --update-input ` can be used. + +You can also pass flake-related options +such as `--recreate-lock-file` or `--update-input ` +to `home-manager` when building or switching, +and these options will be forwarded to `nix build`. +See the {nixos-wiki-flakes}[NixOS Wiki page] for details. +==== + +[[sec-flakes-standalone-stable]] +==== Version 22.11 + 1. Set up a flake with a `flake.nix` as follows: + [source,nix] @@ -79,9 +144,9 @@ writing a Home Manager configuration. inputs = { # Specify the source of Home Manager and Nixpkgs. - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11"; home-manager = { - url = "github:nix-community/home-manager"; + url = "github:nix-community/home-manager/release-22.11"; inputs.nixpkgs.follows = "nixpkgs"; }; }; @@ -109,16 +174,10 @@ writing a Home Manager configuration. + [NOTE] ==== -* The above example tracks the master branch of Home Manager -and nixos-unstable branch of Nixpkgs. -If you would like to use the `release-22.11` branch, -change the `home-manager` input url to `github:nix-community/home-manager/release-22.11` -and `nixpkgs` url to `github:NixOS/nixpkgs/nixos-22.11`. - -* The Home Manager library is exported by the flake under -`lib.hm`. +* The Home Manager library is exported by the flake under `lib.hm`. * You can use the above `flake.nix` as a template in `~/.config/home-manager` by ++ [source,console] $ nix flake new ~/.config/home-manager -t github:nix-community/home-manager ==== diff --git a/docs/release-notes/rl-2305.adoc b/docs/release-notes/rl-2305.adoc index b2156e9c..5df99d17 100644 --- a/docs/release-notes/rl-2305.adoc +++ b/docs/release-notes/rl-2305.adoc @@ -30,6 +30,14 @@ The old location will continue to work but using it will trigger a warning messa We changed the default configuration location to avoid confusion about which files belong to Home Manager and which belong to Nixpkgs. +* The `home-manager` tool now offers an `init` command. +This command can be used to generate an initial Home Manager configuration, +and optionally also activate it. +The recommended installation method for a standalone Home Manager setup +with Nix flakes uses this new command. +The standard installation method remains the same but uses the new command internally. +See <> for more. + [[sec-release-23.05-state-version-changes]] === State Version Changes @@ -45,5 +53,5 @@ These changes are only active if the `home.stateVersion` option is set to "23.05 - <> -- + -now default to `true` which is consistent with the default values -for those options used by `i3` and `sway`. +now default to `true` which is consistent with the default values for +those options used by `i3` and `sway`. diff --git a/home-manager/completion.bash b/home-manager/completion.bash index 152f8c32..de780451 100644 --- a/home-manager/completion.bash +++ b/home-manager/completion.bash @@ -276,19 +276,26 @@ _home-manager_xdg-get-cache-home () { ################################################## +_hm_subcommands=( "help" "edit" "option" "build" "init" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" ) +declare -ra _hm_subcommands + +# Finds the active sub-command, if any. +_home-manager_subcommand() { + local subcommand='' i= + for ((i = 1; i < ${#COMP_WORDS[@]}; i++)); do + local word="${COMP_WORDS[i]}" + if [[ " ${_hm_subcommands[*]} " == *" ${word} "* ]]; then + subcommand="$word" + break + fi + done + + echo "$subcommand" +} + # shellcheck disable=SC2207 _home-manager_completions () { - - #--------------------------# - - local Subcommands - Subcommands=( "help" "edit" "option" "build" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" ) - - # ^ « home-manager »'s subcommands. - - #--------------------------# - local Options Options=( "-f" "--file" "-b" "-A" "-I" "-h" "--help" "-n" "--dry-run" "-v" \ "--verbose" "--cores" "--debug" "--impure" "--keep-failed" \ @@ -322,39 +329,53 @@ _home-manager_completions () # PreviousWord="-f" # CurrentWord="./" + local CurrentCommand + CurrentCommand="$(_home-manager_subcommand)" + #--------------------------# COMPREPLY=() - case "$PreviousWord" in - - "-f"|"--file") - - COMPREPLY+=( $( compgen -A file -- "$CurrentWord") ) - ;; - - "-I") + case "$CurrentCommand" in + "init") + COMPREPLY+=( $( compgen -W "--switch" -- "$CurrentWord" ) ) COMPREPLY+=( $( compgen -A directory -- "$CurrentWord") ) ;; - "-A") - - # shellcheck disable=SC2119 - COMPREPLY+=( $( compgen -W "$(_home-manager_list-nix-attributes)" -- "$CurrentWord") ) - ;; - "remove-generations") COMPREPLY+=( $( compgen -W "$(_home-manager_list-generation-identifiers)" -- "$CurrentWord" ) ) ;; *) + case "$PreviousWord" in - COMPREPLY+=( $( compgen -W "${Subcommands[*]}" -- "$CurrentWord" ) ) - COMPREPLY+=( $( compgen -W "${Options[*]}" -- "$CurrentWord" ) ) + "-f"|"--file") + + COMPREPLY+=( $( compgen -A file -- "$CurrentWord") ) + ;; + + "-I") + + COMPREPLY+=( $( compgen -A directory -- "$CurrentWord") ) + ;; + + "-A") + + # shellcheck disable=SC2119 + COMPREPLY+=( $( compgen -W "$(_home-manager_list-nix-attributes)" -- "$CurrentWord") ) + ;; + *) + + if [[ ! $CurrentCommand ]]; then + COMPREPLY+=( $( compgen -W "${_hm_subcommands[*]}" -- "$CurrentWord" ) ) + fi + COMPREPLY+=( $( compgen -W "${Options[*]}" -- "$CurrentWord" ) ) + ;; + + esac ;; - esac #--------------------------# diff --git a/home-manager/completion.zsh b/home-manager/completion.zsh index c5d3b493..52bcce90 100644 --- a/home-manager/completion.zsh +++ b/home-manager/completion.zsh @@ -35,6 +35,7 @@ case "$state" in 'edit[edit]' \ 'option[inspect option]' \ 'build[build]' \ + 'init[init]' \ 'switch[switch]' \ 'generations[list generations]' \ 'remove-generations[remove generations]' \ @@ -69,6 +70,11 @@ case "$state" in '--experimental-features[set experimental Nix features]:VALUE:()' \ '--extra-experimental-features:[append to experimental Nix features]:VALUE:()' ;; + init) + _arguments \ + '--switch[switch]' \ + ':PATH:_files -/' + ;; esac esac diff --git a/home-manager/home-manager b/home-manager/home-manager index eaa1287d..fd8ae718 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -50,6 +50,15 @@ function setWorkDir() { fi } +# Checks whether the 'flakes' and 'nix-command' Nix options are enabled. +function hasFlakeSupport() { + type -p nix > /dev/null \ + && nix show-config \ + | grep experimental-features \ + | grep flakes \ + | grep -q nix-command +} + # Attempts to set the HOME_MANAGER_CONFIG global variable. # # If no configuration file can be found then this function will print @@ -207,6 +216,174 @@ function doInspectOption() { "${PASSTHROUGH_OPTS[@]}" } +function doInit() { + # The directory where we should place the initial configuration. + local confDir + + # Whether we should immediate activate the configuration. + local switch + + # Whether we should create a flake file. + local withFlake + + if hasFlakeSupport; then + withFlake=1 + fi + + while (( $# > 0 )); do + local opt="$1" + shift + + case $opt in + --no-flake) + unset withFlake + ;; + --switch) + switch=1 + ;; + -*) + _iError "%s: unknown option '%s'" "$0" "$opt" >&2 + exit 1 + ;; + *) + if [[ -v confDir ]]; then + _i "Run '%s --help' for usage help" "$0" >&2 + exit 1 + else + confDir="$opt" + fi + ;; + esac + done + + if [[ ! -v confDir ]]; then + confDir="${XDG_CONFIG_HOME:-$HOME/.config}/home-manager" + fi + + if [[ ! -e $confDir ]]; then + mkdir -p "$confDir" + fi + + if [[ ! -d $confDir ]]; then + _iError "%s: unknown option '%s'" "$0" "$opt" >&2 + exit 1 + fi + + local confFile="$confDir/home.nix" + local flakeFile="$confDir/flake.nix" + + if [[ -e $confFile ]]; then + _i 'The file %s already exists, leaving it unchanged...' "$confFile" + else + _i 'Creating %s...' "$confFile" + local nl=$'\n' + local xdgVars="" + if [[ -v XDG_CACHE_HOME && $XDG_CACHE_HOME != "$HOME/.cache" ]]; then + xdgVars="$xdgVars xdg.cacheHome = \"$XDG_CACHE_HOME\";$nl" + fi + if [[ -v XDG_CONFIG_HOME && $XDG_CONFIG_HOME != "$HOME/.config" ]]; then + xdgVars="$xdgVars xdg.configHome = \"$XDG_CONFIG_HOME\";$nl" + fi + if [[ -v XDG_DATA_HOME && $XDG_DATA_HOME != "$HOME/.local/share" ]]; then + xdgVars="$xdgVars xdg.dataHome = \"$XDG_DATA_HOME\";$nl" + fi + if [[ -v XDG_STATE_HOME && $XDG_STATE_HOME != "$HOME/.local/state" ]]; then + xdgVars="$xdgVars xdg.stateHome = \"$XDG_STATE_HOME\";$nl" + fi + + mkdir -p "$confDir" + cat > "$confFile" < "$flakeFile" < $confFile <\n" "Language-Team: LANGUAGE \n" @@ -18,128 +18,50 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: home-manager/home-manager:62 +#: home-manager/home-manager:71 msgid "No configuration file found at %s" msgstr "" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:79 home-manager/home-manager:83 -#: home-manager/home-manager:138 +#: home-manager/home-manager:88 home-manager/home-manager:92 +#: home-manager/home-manager:147 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" msgstr "" -#: home-manager/home-manager:90 +#: home-manager/home-manager:99 msgid "No configuration file found. Please create one at %s" msgstr "" -#: home-manager/home-manager:174 +#: home-manager/home-manager:183 msgid "Can't inspect options of a flake configuration" msgstr "" -#: home-manager/home-manager:213 -msgid "Can't instantiate a flake configuration" -msgstr "" - -#: home-manager/home-manager:286 -msgid "" -"There is %d unread and relevant news item.\n" -"Read it by running the command \"%s news\"." -msgid_plural "" -"There are %d unread and relevant news items.\n" -"Read them by running the command \"%s news\"." -msgstr[0] "" -msgstr[1] "" - -#: home-manager/home-manager:300 -msgid "Unknown \"news.display\" setting \"%s\"." -msgstr "" - -#: home-manager/home-manager:307 -#, sh-format -msgid "Please set the $EDITOR environment variable" -msgstr "" - -#: home-manager/home-manager:322 -msgid "Cannot run build in read-only directory" -msgstr "" - -#: home-manager/home-manager:406 -msgid "No generation with ID %s" -msgstr "" - -#: home-manager/home-manager:408 -msgid "Cannot remove the current generation %s" -msgstr "" - -#: home-manager/home-manager:410 -msgid "Removing generation %s" -msgstr "" - -#: home-manager/home-manager:429 -msgid "No generations to expire" -msgstr "" - -#: home-manager/home-manager:440 -msgid "No home-manager packages seem to be installed." -msgstr "" - -#: home-manager/home-manager:497 -msgid "Unknown argument %s" -msgstr "" - -#: home-manager/home-manager:513 -msgid "This will remove Home Manager from your system." -msgstr "" - -#: home-manager/home-manager:516 -msgid "This is a dry run, nothing will actually be uninstalled." -msgstr "" - -#: home-manager/home-manager:520 -msgid "Really uninstall Home Manager?" -msgstr "" - -#: home-manager/home-manager:526 -msgid "Switching to empty Home Manager configuration..." -msgstr "" - -#: home-manager/home-manager:553 -msgid "Yay!" -msgstr "" - -#: home-manager/home-manager:558 -msgid "Home Manager is uninstalled but your home.nix is left untouched." -msgstr "" - -#: home-manager/home-manager:723 +#: home-manager/home-manager:245 home-manager/home-manager:268 +#: home-manager/home-manager:907 msgid "%s: unknown option '%s'" msgstr "" -#: home-manager/home-manager:724 +#: home-manager/home-manager:250 home-manager/home-manager:908 msgid "Run '%s --help' for usage help" msgstr "" -#: home-manager/home-manager:758 -msgid "expire-generations expects one argument, got %d." +#: home-manager/home-manager:276 home-manager/home-manager:326 +msgid "The file %s already exists, leaving it unchanged..." msgstr "" -#: home-manager/home-manager:780 -msgid "Unknown command: %s" +#: home-manager/home-manager:278 home-manager/home-manager:328 +msgid "Creating %s..." msgstr "" -#: home-manager/install.nix:22 -msgid "Creating initial Home Manager configuration..." -msgstr "" - -#: home-manager/install.nix:66 +#: home-manager/home-manager:370 msgid "Creating initial Home Manager generation..." msgstr "" #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/install.nix:71 +#: home-manager/home-manager:375 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -150,7 +72,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/install.nix:76 +#: home-manager/home-manager:380 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -159,6 +81,89 @@ msgid "" "if the error seems to be the fault of Home Manager." msgstr "" -#: home-manager/install.nix:83 +#: home-manager/home-manager:390 +msgid "Can't instantiate a flake configuration" +msgstr "" + +#: home-manager/home-manager:463 +msgid "" +"There is %d unread and relevant news item.\n" +"Read it by running the command \"%s news\"." +msgid_plural "" +"There are %d unread and relevant news items.\n" +"Read them by running the command \"%s news\"." +msgstr[0] "" +msgstr[1] "" + +#: home-manager/home-manager:477 +msgid "Unknown \"news.display\" setting \"%s\"." +msgstr "" + +#: home-manager/home-manager:484 +#, sh-format +msgid "Please set the $EDITOR environment variable" +msgstr "" + +#: home-manager/home-manager:499 +msgid "Cannot run build in read-only directory" +msgstr "" + +#: home-manager/home-manager:583 +msgid "No generation with ID %s" +msgstr "" + +#: home-manager/home-manager:585 +msgid "Cannot remove the current generation %s" +msgstr "" + +#: home-manager/home-manager:587 +msgid "Removing generation %s" +msgstr "" + +#: home-manager/home-manager:606 +msgid "No generations to expire" +msgstr "" + +#: home-manager/home-manager:617 +msgid "No home-manager packages seem to be installed." +msgstr "" + +#: home-manager/home-manager:674 +msgid "Unknown argument %s" +msgstr "" + +#: home-manager/home-manager:690 +msgid "This will remove Home Manager from your system." +msgstr "" + +#: home-manager/home-manager:693 +msgid "This is a dry run, nothing will actually be uninstalled." +msgstr "" + +#: home-manager/home-manager:697 +msgid "Really uninstall Home Manager?" +msgstr "" + +#: home-manager/home-manager:703 +msgid "Switching to empty Home Manager configuration..." +msgstr "" + +#: home-manager/home-manager:730 +msgid "Yay!" +msgstr "" + +#: home-manager/home-manager:735 +msgid "Home Manager is uninstalled but your home.nix is left untouched." +msgstr "" + +#: home-manager/home-manager:945 +msgid "expire-generations expects one argument, got %d." +msgstr "" + +#: home-manager/home-manager:967 +msgid "Unknown command: %s" +msgstr "" + +#: home-manager/install.nix:18 msgid "This derivation is not buildable, please run it using nix-shell." msgstr "" diff --git a/modules/po/hm-modules.pot b/modules/po/hm-modules.pot index 5c9a7078..79687ded 100644 --- a/modules/po/hm-modules.pot +++ b/modules/po/hm-modules.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2023-03-14 23:10+0100\n" +"POT-Creation-Date: 2023-03-15 20:11+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n"