diff --git a/appconfig/installer_data.go b/appconfig/installer_data.go index 5acb66c..aeadb80 100755 --- a/appconfig/installer_data.go +++ b/appconfig/installer_data.go @@ -87,6 +87,8 @@ type InstallerData struct { EnvShell *platform.PlatformMap[string] `json:"env_shell" yaml:"env_shell"` // SkipSummary controls whether this installer is excluded from the summary. SkipSummary *SkipSummary `json:"skip_summary" yaml:"skip_summary"` + // Verbose enables verbose output for the installer's native commands. + Verbose *bool `json:"verbose" yaml:"verbose"` } // InstallerType represents the type of an installer. diff --git a/docs/installer-configuration.md b/docs/installer-configuration.md index 9e5ad37..872d0e9 100755 --- a/docs/installer-configuration.md +++ b/docs/installer-configuration.md @@ -215,6 +215,49 @@ These fields are shared by all installer types. Some fields may vary in behavior - **Description**: Shell to use for Linux command executions. If not specified, the default shell will be used. +- **`verbose`** + - **Type**: Boolean (optional) + - **Description**: Enable verbose output for the installer's native commands. When set to `true`, + the installer will pass verbose flags to the underlying tool, producing more detailed output + during installation and updates. The specific flag used depends on the installer type. Can also + be set via [defaults](#) per installer type. + - **Default**: `false` (not set) + - **Verbose flags per installer type**: + + | Type | Verbose flag | + | ----------------- | --------------- | + | `rsync` | `-v` | + | `brew` | `--verbose` | + | `git` | `--verbose` | + | `npm`/`pnpm`/`yarn` | `--verbose` | + | `pipx` | `--verbose` | + | `pacman`/`yay` | `--verbose` | + | `apk` | `--verbose` | + | `apt` | _(no-op)_ | + | `docker` | _(no-op)_ | + | `shell` | _(no-op)_ | + | `github-release` | _(no-op)_ | + | `manifest` | _(no-op)_ | + | `group` | _(no-op)_ | + + - **Examples**: + + ```yaml + # Enable verbose for a single installer + - name: xdg-config + type: rsync + verbose: true + opts: + source: ~/.dotfiles/.config + destination: ~/.config + + # Enable verbose for all brew installers via defaults + defaults: + type: + brew: + verbose: true + ``` + - **`skip_summary`** - **Type**: Boolean or Object (optional) - **Description**: Exclude this installer from the installation summary. Useful for installers diff --git a/installer/apt_installer.go b/installer/apt_installer.go index eda152e..39081b2 100755 --- a/installer/apt_installer.go +++ b/installer/apt_installer.go @@ -56,6 +56,11 @@ func (i *AptInstaller) Install() error { install = "add" } args := []string{install} + if i.IsVerbose() { + if i.PackageManager == PackageManagerApk { + args = append(args, "--verbose") + } + } if confirm := i.getConfirmArg(); confirm != "" { args = append(args, confirm) } @@ -82,6 +87,11 @@ func (i *AptInstaller) getConfirmArg() string { func (i *AptInstaller) Update() error { opts := i.GetOpts() args := []string{"upgrade"} + if i.IsVerbose() { + if i.PackageManager == PackageManagerApk { + args = append(args, "--verbose") + } + } if confirm := i.getConfirmArg(); confirm != "" { args = append(args, confirm) } diff --git a/installer/brew_installer.go b/installer/brew_installer.go index 935256f..14b8484 100755 --- a/installer/brew_installer.go +++ b/installer/brew_installer.go @@ -56,6 +56,9 @@ func (i *BrewInstaller) Install() error { name := i.GetFullName() opts := i.GetOpts() cmd := "brew install" + if i.IsVerbose() { + cmd += " --verbose" + } if i.IsCask() { cmd += " --cask" } @@ -72,6 +75,9 @@ func (i *BrewInstaller) Update() error { name := i.GetFullName() opts := i.GetOpts() cmd := "brew upgrade" + if i.IsVerbose() { + cmd += " --verbose" + } if i.IsCask() { cmd += " --cask" } diff --git a/installer/git_installer.go b/installer/git_installer.go index 6d00514..39fcd9c 100755 --- a/installer/git_installer.go +++ b/installer/git_installer.go @@ -51,6 +51,9 @@ func (i *GitInstaller) Validate() []ValidationError { func (i *GitInstaller) Install() error { opts := i.GetOpts() args := []string{"clone"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.InstallFlags != nil { args = append(args, strings.Fields(*opts.InstallFlags)...) } else if opts.Flags != nil { @@ -71,6 +74,9 @@ func (i *GitInstaller) Install() error { func (i *GitInstaller) Update() error { opts := i.GetOpts() args := []string{"-C", i.GetInstallDir(), "pull"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.UpdateFlags != nil { args = append(args, strings.Fields(*opts.UpdateFlags)...) } else if opts.Flags != nil { diff --git a/installer/installer.go b/installer/installer.go index ef82c5b..35aecfe 100755 --- a/installer/installer.go +++ b/installer/installer.go @@ -86,6 +86,11 @@ func (i *InstallerBase) GetTemplateVars() *TemplateVars { return i.TemplateVars } +// IsVerbose returns true if verbose output is enabled for this installer. +func (i *InstallerBase) IsVerbose() bool { + return i.Data != nil && i.Data.Verbose != nil && *i.Data.Verbose +} + // BaseValidate performs basic validation common to all installers. func (i *InstallerBase) BaseValidate() []ValidationError { errors := []ValidationError{} diff --git a/installer/installer_defaults.go b/installer/installer_defaults.go index 97bb61c..860fcec 100755 --- a/installer/installer_defaults.go +++ b/installer/installer_defaults.go @@ -88,6 +88,9 @@ func InstallerWithDefaults( if override.CheckInstalled != nil { data.CheckInstalled = override.CheckInstalled } + if override.Verbose != nil && data.Verbose == nil { + data.Verbose = override.Verbose + } } } return data diff --git a/installer/npm_installer.go b/installer/npm_installer.go index a515443..d05cd20 100755 --- a/installer/npm_installer.go +++ b/installer/npm_installer.go @@ -49,6 +49,9 @@ func (i *NpmInstaller) Validate() []ValidationError { func (i *NpmInstaller) Install() error { opts := i.GetOpts() args := []string{"install", "--global"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.InstallFlags != nil { args = append(args, strings.Fields(*opts.InstallFlags)...) } else if opts.Flags != nil { @@ -62,6 +65,9 @@ func (i *NpmInstaller) Install() error { func (i *NpmInstaller) Update() error { opts := i.GetOpts() args := []string{"install", "--global"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.UpdateFlags != nil { args = append(args, strings.Fields(*opts.UpdateFlags)...) } else if opts.Flags != nil { diff --git a/installer/pacman_installer.go b/installer/pacman_installer.go index 8062d6d..1d401be 100755 --- a/installer/pacman_installer.go +++ b/installer/pacman_installer.go @@ -49,6 +49,9 @@ func (i *PacmanInstaller) Install() error { name := *i.Info.Name opts := i.GetOpts() args := []string{"-S", "--noconfirm"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.Needed != nil && *opts.Needed { args = append(args, "--needed") } @@ -66,6 +69,9 @@ func (i *PacmanInstaller) Update() error { name := *i.Info.Name opts := i.GetOpts() args := []string{"-S", "--noconfirm"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.Needed != nil && *opts.Needed { args = append(args, "--needed") } diff --git a/installer/pipx_installer.go b/installer/pipx_installer.go index 5917a1f..36a69bc 100755 --- a/installer/pipx_installer.go +++ b/installer/pipx_installer.go @@ -37,6 +37,9 @@ func (i *PipxInstaller) Install() error { name := *i.Info.Name opts := i.GetOpts() args := []string{"install"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.InstallFlags != nil { args = append(args, strings.Fields(*opts.InstallFlags)...) } else if opts.Flags != nil { @@ -50,6 +53,9 @@ func (i *PipxInstaller) Install() error { func (i *PipxInstaller) Update() error { opts := i.GetOpts() args := []string{"upgrade"} + if i.IsVerbose() { + args = append(args, "--verbose") + } if opts.UpdateFlags != nil { args = append(args, strings.Fields(*opts.UpdateFlags)...) } else if opts.Flags != nil { diff --git a/installer/rsync_installer.go b/installer/rsync_installer.go index 578f98a..4beed82 100755 --- a/installer/rsync_installer.go +++ b/installer/rsync_installer.go @@ -48,7 +48,7 @@ func (i *RsyncInstaller) Validate() []ValidationError { // Install implements IInstaller. func (i *RsyncInstaller) Install() error { defaultFlags := "-tr" - if i.Config.Debug != nil && *i.Config.Debug { + if i.IsVerbose() || (i.Config.Debug != nil && *i.Config.Debug) { defaultFlags += "v" } flags := []string{defaultFlags}