twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
12.85k stars 477 forks source link

promptString is not yielding the expected result #3834

Closed 0xjams closed 2 months ago

0xjams commented 2 months ago

What exactly are you trying to do?

Using the example case of defining a variable during the init step. I'm currently testing by executing the template.

$ cat .chezmoi.toml.tmpl
{{- $email := promptStringOnce . "email" "Email address" -}}

[data]
    email = {{ $email | quote }}  
$ chezmoi --verbose execute-template --init --promptString email=me@home.org < ~/.local/share/chezmoi/.chezmoi.toml.tmpl

[data]
    email = "Email address"        

The expected result should be that the template should have been evaluated to me@home.org

What have you tried so far?

Where else have you checked for solutions?

Output of chezmoi doctor

```console $ chezmoi doctor RESULT CHECK MESSAGE ok version v2.49.1, commit b4b55659c69fb13a502903c16dcdd566b988eece, built at 2024-06-23T12:28:09Z, built by goreleaser ok latest-version v2.49.1 ok os-arch linux/amd64 (Kali GNU/Linux 2024.2) ok uname Linux kali 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64 GNU/Linux ok go-version go1.22.4 (gc) ok executable /usr/local/bin/chezmoi ok upgrade-method sudo-upgrade-package ok config-file no config file found warning source-dir ~/.local/share/chezmoi is a git working tree (dirty) ok suspicious-entries no suspicious entries warning working-tree ~/.local/share/chezmoi is a git working tree (dirty) ok dest-dir ~ is a directory ok umask 002 ok cd-command found /usr/bin/zsh ok cd-args /usr/bin/zsh info diff-command not set ok edit-command found /usr/bin/vi ok edit-args /usr/bin/vi ok git-command found /usr/bin/git, version 2.43.0 ok merge-command found /usr/bin/vimdiff ok shell-command found /usr/bin/zsh ok shell-args /usr/bin/zsh info age-command age not found in $PATH ok gpg-command found /usr/bin/gpg, version 2.2.43 info pinentry-command not set info 1password-command op not found in $PATH 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 info vault-command vault not found in $PATH info vlt-command vlt not found in $PATH info secret-command not set ```

Additional context

My use case is slightly different, but I used the default example as a sanity check. I still haven't gotten the expected result.

twpayne commented 2 months ago

promptStringOnce only prompts for a string if it is not already set.

Do you already have data.email set in your configuration? If so, promptStringOnce will return the existing value (which might not be me@home.org) instead of prompting.

0xjams commented 2 months ago

The example of my post was extracted from the documentation in the Create a config file on a new machine automatically section. Am I wrong to assume that after executing the execute-template subcommand with the promptStringOnce flag, the value should have been overridden and it should not have used the default value of the function call?

[data]
    email = "Email address"      
twpayne commented 2 months ago

Am I wrong to assume that after executing the execute-template subcommand with the promptStringOnce flag, the value should have been overridden and it should not have used the default value of the function call?

Yes.

promptString always asks for a string. promptStringOnce asks for a string if there is no existing value. If you already have a config file, then there is probably already an existing value.

Breaking the arguments to promptStringOnce down:

promptStringOnce map path prompt [default]

map and path tell chezmoi where to find the existing value.

prompt is the prompt for the user if there is no existing value.

default is the default value if the user hits enter in response to the prompt.

In the case of

promptStringOnce . "email" "Email address"

map is . and path is email which means that chezmoi is looking up the .email template variable. If you already have a config file with data.email set then the .email template variable is already set.

0xjams commented 2 months ago

My bad. The problem was that I never actually ran chezmoi init after creating that template, I was only running chezmoi execute-template --init, I guess that execution defined the value, that's probably why promptStringOnce was not firing up.

Thank you so much! Sorry for the trouble.

0xjams commented 2 months ago

I just tested this with interesting results.

kali@kali:~/.local/share/chezmoi$  rm ~/.config/chezmoi/chezmoi.toml
kali@kali:~/.local/share/chezmoi$  rm ~/.config/chezmoi/chezmoi.toml
rm: cannot remove '/home/kali/.config/chezmoi/chezmoi.toml': No such file or directory
❌ kali@kali:~/.local/share/chezmoi$  chezmoi execute-template --verbose --init --promptString email=me@mail.com < ~/.local/share/chezmoi/.chezmoi.toml.tmpl

[data]
    email = "Email address"%                                                                           
kali@kali:~/.local/share/chezmoi$  chezmoi init
# Here the promptStringOnce ran, and I set the value
kali@kali:~/.local/share/chezmoi$  cat /home/kali/.config/chezmoi/chezmoi.toml

[data]
    email = "me@me.com"%                                                                               
kali@kali:~/.local/share/chezmoi$  chezmoi execute-template --verbose --init --promptString email=me@mail.com < ~/.local/share/chezmoi/.chezmoi.toml.tmpl

[data]
    email = "me@me.com"% 
twpayne commented 2 months ago

The value passed to the --promptString flag is the prompt, not the key. i.e. I think you want:

$ chezmoi execute-template --verbose --init --promptString 'Email address=me@mail.com' < ~/.local/share/chezmoi/.chezmoi.toml.tmpl

Note --promptString 'Email address=me@mail.com' instead of --promptString email=me@mail.com.

0xjams commented 2 months ago

Thank you so much. I completely misunderstood the flag. I thought that this --promptString email=me@mail.com was supposed to override the value of the email variable.