twpayne/chezmoi

`chezmoi cd` and `chezmoi doctor` doesn't honour `chezmoi init --source /path` when initialising

Opened this issue · 9 comments

Describe the bug

As a first time chezmoi user
I want to be able to set the source path when initialising
So that when I run chezmoi cd and chezmoi doctor I can see that my source-dir is set to the path at init time

To reproduce

❯ brew install chezmoi

❯ chezmoi init --source /Users/david/dotfiles

❯ chezmoi cd
.local/share/chezmoi

❯ exit

❯ chezmoi doctor
RESULT   CHECK                       MESSAGE
ok       version                     v2.47.1, commit 1ce6b2eeb0caf75bd91883e5a968e713a26e7be2, built at 2024-03-03T00:47:52Z, built by Homebrew
ok       latest-version              v2.47.1
ok       os-arch                     darwin/amd64
ok       uname                       Darwin mbp.local 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:54:10 PST 2023; root:xnu-10002.61.3~2/RELEASE_X86_64 x86_64
ok       go-version                  go1.22.0 (gc)
ok       executable                  /usr/local/bin/chezmoi
ok       upgrade-method              replace-executable
ok       config-file                 no config file found
ok       source-dir                  ~/.local/share/chezmoi is a directory
ok       suspicious-entries          no suspicious entries
ok       working-tree                ~/.local/share/chezmoi is a directory
ok       dest-dir                    ~ is a directory
ok       umask                       022
ok       cd-command                  found /bin/zsh
ok       cd-args                     /bin/zsh
info     diff-command                not set
ok       edit-command                found /usr/local/bin/vi
ok       edit-args                   /usr/local/bin/vi
ok       git-command                 found /usr/local/bin/git, version 2.44.0
ok       merge-command               found /usr/local/bin/vimdiff
ok       shell-command               found /bin/zsh
ok       shell-args                  /bin/zsh
ok       age-command                 found /usr/local/bin/age, version 1.1.1
ok       gpg-command                 found /usr/local/bin/gpg, version 2.4.5
info     pinentry-command            not set
ok       1password-command           found /usr/local/bin/op, version 2.25.0
info     bitwarden-command           bw not found in $PATH
info     bitwarden-secrets-command   bws not found in $PATH
info     dashlane-command            dcli not found in $PATH
info     doppler-command             doppler not found in $PATH
info     gopass-command              gopass not found in $PATH
info     keepassxc-command           keepassxc-cli not found in $PATH
info     keepassxc-db                not set
info     keeper-command              keeper not found in $PATH
info     lastpass-command            lpass not found in $PATH
info     pass-command                pass not found in $PATH
info     passhole-command            ph not found in $PATH
info     rbw-command                 rbw not found in $PATH
ok       vault-command               found /usr/local/bin/vault, version 1.15.6
info     vlt-command                 vlt not found in $PATH
info     secret-command              not set

❯ env | grep CHEZ | grep SOURCE
CHEZMOI_SOURCE_DIR=/Users/david/dotfiles

Expected behavior

When manually creating a chezmoi.yaml config file, I am able to set the source dir manually and it works when running both cd and doctor commands.

What I expect to happen is that this is dealt with from the init command when setting the source. My goal is to streamline the setup process, hopefully in absence of a config zero file (as that will come later), rather than the creation of the config file as pre-req.

Output of command with the --verbose flag

❯ chezmoi cd --verbose
.local/share/chezmoi

Output of chezmoi doctor

❯ chezmoi doctor
RESULT   CHECK                       MESSAGE
ok       version                     v2.47.1, commit 1ce6b2eeb0caf75bd91883e5a968e713a26e7be2, built at 2024-03-03T00:47:52Z, built by Homebrew
ok       latest-version              v2.47.1
ok       os-arch                     darwin/amd64
ok       uname                       Darwin mbp.local 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:54:10 PST 2023; root:xnu-10002.61.3~2/RELEASE_X86_64 x86_64
ok       go-version                  go1.22.0 (gc)
ok       executable                  /usr/local/bin/chezmoi
ok       upgrade-method              replace-executable
ok       config-file                 no config file found
ok       source-dir                  ~/.local/share/chezmoi is a directory
ok       suspicious-entries          no suspicious entries
ok       working-tree                ~/.local/share/chezmoi is a directory
ok       dest-dir                    ~ is a directory
ok       umask                       022
ok       cd-command                  found /bin/zsh
ok       cd-args                     /bin/zsh
info     diff-command                not set
ok       edit-command                found /usr/local/bin/vi
ok       edit-args                   /usr/local/bin/vi
ok       git-command                 found /usr/local/bin/git, version 2.44.0
ok       merge-command               found /usr/local/bin/vimdiff
ok       shell-command               found /bin/zsh
ok       shell-args                  /bin/zsh
ok       age-command                 found /usr/local/bin/age, version 1.1.1
ok       gpg-command                 found /usr/local/bin/gpg, version 2.4.5
info     pinentry-command            not set
ok       1password-command           found /usr/local/bin/op, version 2.25.0
info     bitwarden-command           bw not found in $PATH
info     bitwarden-secrets-command   bws not found in $PATH
info     dashlane-command            dcli not found in $PATH
info     doppler-command             doppler not found in $PATH
info     gopass-command              gopass not found in $PATH
info     keepassxc-command           keepassxc-cli not found in $PATH
info     keepassxc-db                not set
info     keeper-command              keeper not found in $PATH
info     lastpass-command            lpass not found in $PATH
info     pass-command                pass not found in $PATH
info     passhole-command            ph not found in $PATH
info     rbw-command                 rbw not found in $PATH
ok       vault-command               found /usr/local/bin/vault, version 1.15.6
info     vlt-command                 vlt not found in $PATH
info     secret-command              not set

You can use file .chezmoi.yaml.tmpl (see docs) with this line: sourceDir: {{ .chezmoi.config.sourceDir | quote }}

You can use file .chezmoi.yaml.tmpl (see docs) with this line: sourceDir: {{ .chezmoi.config.sourceDir | quote }}

Yes, the config file works. But that would void chezmoi init --source as a working parameter. It's a bug, unless I'm missing something when running chezmoi init --source /path ?

I don't think that this is a bug, because chezmoi.$FORMAT is initialized from .chezmoi.$FORMAT.tmpl if it exists and does a minimal setup otherwise.

If you do not have .chezmoi.yaml.tmpl, I think it would be an enhancement that chezmoi would add sourceDir to the value of the --source flag.

If you add .chezmoi.yaml.tmpl as @ErrrorMaxx suggested, using chezmoi init --source /path would indeed result in .chezmoi.yaml containing sourceDir: /path:

$ chezmoi execute-template --init --source /foo '{{ .chezmoi.config.sourceDir }}'
/foo

You can use file .chezmoi.yaml.tmpl (see docs) with this line: sourceDir: {{ .chezmoi.config.sourceDir | quote }}

It's quite surprising to me to have to do this - I would expect that just setting --source without a config file being present, would override the default value - if this is the expected behavior, perhaps there should be mention of this in the docs somewhere? I agree with the OP: providing a --source value should override the default value without needing to provide a config file template - it feels like a bug to me

Ah, there is indeed mention of it at: https://www.chezmoi.io/user-guide/setup/#create-a-config-file-on-a-new-machine-automatically

It is still surprising that a minimal customised setup isn't possible without the config file template, and just by setting --source

¯_(ツ)_/¯

I’m changing this to an enhancement request. I think that it’s a reasonable default if there is no .chezmoi.$FORMAT.tmpl in the source. The biggest argument against it is the confusion of "I have a config template, why isn’t my custom --source used".

It is still surprising that a minimal customised setup isn't possible without the config file template, and just by setting --source

Flags like --source, --destination, --cache, --config, --working-tree, and --persistent-state primarily exist to help users test their chezmoi setup. For example, you can specify a different --destination to see what dotfiles chezmoi would write without affecting your actual dotfiles.

chezmoi is opinionated software (i.e. it provides sensible defaults) and follows the XDG specification (i.e. it stores its user-specific data files in ~/.local/share/chezmoi). While you are using chezmoi as it is intended to be used, things are automatic and easy. If you want to use it in a different way then you have to expect to do a bit of extra work.

Note also that chezmoi makes a clear distinction between config (which is only written by the user and is only read by chezmoi) and state (which is and only read and written by chezmoi and can be deleted at any time). If chezmoi were to implement:

It is still surprising that a minimal customised setup isn't possible without the config file template, and just by setting --source

then chezmoi would have to store the user's source directory somewhere. It can't store it in the config (as that is only written by the user) and it can't store it in the state (as that can be deleted at any time).

The compromise is that, if you want to use a different source directory to ~/.local/share/chezmoi then you have to add one line to your config file template:

sourceDir: {{ .chezmoi.config.sourceDir | quote }}

I think that is a reasonable compromise.

As a newbie to chezmoi and an old hat to open source, I appreciate the terse and prompt response!

I assumed that as --source is a global flag, and nothing evident to the contrary when running chezmoi init --help, that defining --source at init would make that sticky to the config.

then chezmoi would have to store the user's source directory somewhere. It can't store it in the config (as that is only written by the user) and it can't store it in the state (as that can be deleted at any time).

That makes sense. Wouldn't environment variables be a great use case for this?

❯ env | grep CHEZ | grep SOURCE
CHEZMOI_SOURCE_DIR=/Users/david/dotfiles

Even when setting --source and/or CHEZMOI_SOURCE_DIR, chezmoi doctor still defaulted the source to ~/.local/share/chezmoi.

Environment variables circumvent the config+state issue, just as long as chezmoi reads and respects what's set.

No worries to create a config file template, but as an enhancement it would be great to define or make known to the user of the implicit and/or explicit dependency/blocker that running chezmoi init --source has in the event you're NOT creating a config file as a pre-req.

Maybe this needs a separate issue, but I would currently classify this as a bug because the script generated by chezmoi generate install.sh uses init --apply --source="${script_dir}" - since the source dir isn't saved (in the config or elsewhere), and there is no data copied into the default source dir, the resulting chezmoi state is not functional.