twpayne / chezmoi

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

Implementing Declarative Syntax for Streamlined Package Installation #3395

Closed kalip2 closed 11 months ago

kalip2 commented 11 months ago

Is your feature request related to a problem? Please describe.

I'm always frustrated when I have to think about cumbersome shell scripting for package installation, as demonstrated in the run_once_before_install-packages-darwin.sh.tmpl.

{{- if eq .chezmoi.os "darwin" -}}
#!/bin/bash

brew bundle --no-lock --file=/dev/stdin <<EOF
brew "git"
cask "google-chrome"
EOF
{{ end -}}

Describe the solution you'd like

The introduction of a declarative syntax for package installation would greatly simplify this process. This approach, as exemplified by rotz, allows for a more straightforward, readable configuration. Here's how a similar syntax could be applied:

dots.yaml

windows:
  installs:
    cmd: scoop install {{ name }}
    depends:
      - scoop
      - extras

darwin:
  installs:
    cmd: brew install {{ name }}
    depends:
      - brew

This method would streamline the installation process, making it more intuitive and less prone to errors.

Describe alternatives you've considered

One alternative explored is the use of nix-darwin, which also employs a declarative syntax. This method allows for a more structured and maintainable approach to package installation, as demonstrated below.

# Adapted examples from https://github.com/Homebrew/homebrew-bundle#usage
[
  # `brew install`
  "imagemagick"

  # `brew install --with-rmtp`, `brew services restart` on version changes
  {
    name = "denji/nginx/nginx-full";
    args = [ "with-rmtp" ];
    restart_service = "changed";
  }

  # `brew install`, always `brew services restart`, `brew link`, `brew unlink mysql` (if it is installed)
  {
    name = "mysql@5.6";
    restart_service = true;
    link = true;
    conflicts_with = [ "mysql" ];
  }
]

Additional context

The adoption of a declarative syntax aligns with modern configuration management practices, offering a more efficient and user-friendly approach to package installation and dependency management.

twpayne commented 11 months ago

You can already do this using a .chezmoidata file containing your list of packages and a templated run_ script. Something like:

.local/share/chezmoi/.chezmoidata/packages.yaml:

packages:
  darwin:
    brews:
    - "git"
    casks:
    - "google-chrome"

.local/share/chezmoi/run_onchange_install-packages-darwin.sh:

{{ if eq .chezmoi.os "darwin" -}}
#!/bin/bash

brew bundle --no-lock --file=/dev/stdin <<EOF
{{ range .packages.darwin.brews -}}
brew {{ . | quote }}
{{ end -}}
{{ range .packages.darwin.casks -}}
cask {{ . | quote }}
{{ end -}}
EOF
{{ end -}}
halostatue commented 11 months ago

@twpayne This might be a good thing to show in the FAQ, or in the Show & Tell section of the discussions. I am using something somewhat similar (except all variations of brew bundle) in my own dotfiles.