twpayne / chezmoi

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

promptStringOnce and promptBoolOnce generate null output with `chezmoi init` #2920

Closed arrrgi closed 1 year ago

arrrgi commented 1 year ago

What exactly are you trying to do?

In the following chezmoi.yaml.tmpl I have defined a number of empty variables, these should then be replaced by the values derived from prompts in the template when running chezmoi init or chezmoi init --data=false but the init completes without error and my .data.git variables are empty, and the .boolEnvRestricted is still false even though I provided a 'true' input:

{{/* define defaults */}}
{{- $stringName := "" }}
{{- $stringEmail := "" }}
{{- $stringGithubUser := "" }}
{{- $stringDevOpsOrg := "" }}
{{- $boolEnvRestricted := false -}}
{{- $boolEnvWsl := and (eq .chezmoi.os "linux") (.chezmoi.kernel.osrelease | lower | contains "microsoft") | not | not -}}
{{- $boolEnvContainer := or (env "REMOTE_CONTAINERS") (env "VSCODE_REMOTE_CONTAINER_SESSION") (eq .chezmoi.username "ubuntu" "vscode") | not | not -}}
{{- $boolEnvMacOS := eq .chezmoi.os "darwin" -}}
{{- $boolEnvMultipass := and (stat "/sys/class/dmi/id/product_name") (output "cat" "/sys/class/dmi/id/product_name" | regexMatch "(QEMU|VirtualBox)") | not | not -}}
{{- $boolEnvServer := eq .chezmoi.username "sysadm" -}}
{{- $secrets := dict "keys" false "api" false "storage" false -}}
{{- $data := . }}
{{- $_ := set $data "git" (default (dict) (get $data "git")) -}}
{{- $_ := set $data "flags" (default (dict) (get $data "flags")) -}}

{{/* handle conditionals */}}
{{- if stdinIsATTY -}}
{{-   writeToStdout "💡 Tip: You can re-enter prompted inputs with `chezmoi init --data=false`.\n" -}}
{{-   $stringName := promptStringOnce $data.git "name" "Provide a full name or handle for .gitconfig" -}}
{{-   $boolEnvRestricted := promptBoolOnce $data.flags "boolEnvRestricted" "Is this a work target device?" -}}
{{-   if $boolEnvRestricted -}}
{{-     $stringEmail := promptStringOnce $data.git "email" "Provide your work email address for .gitconfig" -}}
{{-     $stringDevOpsOrg := promptStringOnce $data.git "org" "Provide your work Azure Org for .gitconfig" -}}
{{-     writeToStdout "💬 Info: Setting up work target device..." -}}
{{-     if or $boolEnvWsl $boolEnvMultipass -}}
{{/*      set flag to copy only SSH & API keys */}}
{{-       $_ := set $secrets "keys" true -}}
{{-       $_ := set $secrets "api" true -}}
{{-     end -}}
{{-   else -}}
{{-     $boolEnvRestricted := false -}}
{{-     $stringEmail := promptStringOnce $data.git "email" "Provide your personal email address for .gitconfig" -}}
{{-     $stringGithubUser := promptStringOnce $data.git "username" "Provide your work Github username for .gitconfig" -}}
{{-     if $boolEnvMacOS -}}
{{-       writeToStdout "💬 Info: Setting up MacOS target device..." -}}
{{/*      set flag to copy all sensitive data */}}
{{-       $_ := set $secrets "keys" true -}}
{{-       $_ := set $secrets "api" true -}}
{{-       $_ := set $secrets "storage" true -}}
{{-     else if $boolEnvServer -}}
{{-       writeToStdout "💬 Info: Setting up Server target device..." -}}
{{/*      set flag to copy only API keys */}}
{{-       $_ := set $secrets "api" true -}}
{{-     end -}}
{{-   end -}}
{{- else if $boolEnvContainer -}}
{{-   writeToStdout "💬 Info: Setting up ephemeral target device..." -}}
{{/*  set flag to copy only API keys */}}
{{-   $_ := set $secrets "api" true -}}
{{- else -}}
{{-   writeToStdout "❌ Error: Unsupported dotfiles target" -}}
{{- end }}
diff:
  pager: "less -FX"
  exclude: ["externals"]
encryption: age
age:
  identity: <redacted>
  recipient: <redacted>
data:
  git:
    name: {{ $stringName | quote }}
    email: {{ $stringEmail | quote }}
    username: {{ $stringGithubUser | quote }}
    org: {{ $stringDevOpsOrg | quote }}
  secrets:
    keys: {{ $secrets.keys }}
    api: {{ $secrets.api }}
    storage: {{ $secrets.storage }}
  flags:
    boolEnvContainer: {{ $boolEnvContainer }}
    boolEnvWsl: {{ $boolEnvWsl }}
    boolEnvMultipass: {{ $boolEnvMultipass }}
    boolEnvMacOS: {{ $boolEnvMacOS }}
    boolEnvServer: {{ $boolEnvServer }}
    boolEnvRestricted: {{ $boolEnvRestricted }}

What have you tried so far?

If I set the empty variables with default values, my inputs at prompts are also ignored and the defaults are applied to the .data.git variables

Where else have you checked for solutions?

Output of any commands you've tried with --verbose flag

$ chezmoi --verbose init --data=false

^^^no additional info sent to console, only the template prompts^^^

Output of chezmoi doctor

```console $ chezmoi doctor RESULT CHECK MESSAGE ok version v2.33.1, commit bc4478d84f59ea38084cf7e58b9226278d0e046d, built at 2023-04-07T22:36:48Z, built by goreleaser ok latest-version v2.33.1 ok os-arch darwin/arm64 ok uname Darwin elm-hwd-mni01p 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar 6 21:00:41 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T8103 arm64 ok go-version go1.20.3 (gc) ok executable ~/.local/bin/chezmoi ok upgrade-method replace-executable ok config-file ~/.config/chezmoi/chezmoi.yaml, last modified 2023-04-12T00:23:31+10:00 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 022 ok cd-command found /bin/zsh ok cd-args /bin/zsh info diff-command not set ok edit-command found /opt/homebrew/bin/nvim ok edit-args /opt/homebrew/bin/nvim ok git-command found /opt/homebrew/bin/git, version 2.40.0 ok merge-command found /usr/bin/vimdiff ok shell-command found /bin/zsh ok shell-args /bin/zsh ok age-command found /opt/homebrew/bin/age, version 1.1.1 info gpg-command gpg not found in $PATH info pinentry-command not set ok 1password-command found /usr/local/bin/op, version 2.16.1 info bitwarden-command bw not found in $PATH info dashlane-command dcli 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 secret-command not set ```

Additional context

Add any other context about the problem here.

halostatue commented 1 year ago

$variable := value in a new scope (e.g., your if block) creates a new binding which is lost at the end of the scope. Use $variable = value to reassign the value of the variable.

arrrgi commented 1 year ago

Thanks @halostatue , will give that a try now and report back

arrrgi commented 1 year ago

Looks good to me now, but not being overtly familiar with Go template/Sprig I wasn't able to easily spot this. Is there a good reference to the scoping consideration you mentioned @halostatue ??

Closed as resolved now.

halostatue commented 1 year ago

Yes, in the Go text/template documentation. I know this from what programming in Go that I’ve done. I suspect that chezmoi could probably use a gentle introduction to Go templates in its documentation, as the Go documentation is fairly opaque, and even I have to refer to it periodically.

Maybe we could consider something similar to Hugo’s introduction to templating, as the basics largely overlap. This might be more of a chezmoi v3 thing since there is a desire to eliminate Sprig, so having one place to refer to chezmoi functions would be more sensible.

twpayne commented 1 year ago

There is already https://chezmoi.io/user-guide/templating/. Improvements welcome.

arrrgi commented 1 year ago

Maybe we could consider something similar to Hugo’s introduction to templating, as the basics largely overlap. This might be more of a chezmoi v3 thing since there is a desire to eliminate Sprig, so having one place to refer to chezmoi functions would be more sensible.

Well that was a huge lightbulb moment for me, thanks for linking that as it makes much more sense now (sorry @twpayne !)

halostatue commented 1 year ago

There is already https://chezmoi.io/user-guide/templating/. Improvements welcome.

When I have time, I may lift some stuff from Hugo’s documentation that’s not in the Chezmoi guide (what’s there is good, but doesn’t cover some of the basics like the Hugo one does).