diff --git a/installer/apt_installer.go b/installer/apt_installer.go index f6ae936..645bc00 100644 --- a/installer/apt_installer.go +++ b/installer/apt_installer.go @@ -6,6 +6,7 @@ import ( ) type AptInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData PackageManager PackageManager @@ -23,7 +24,7 @@ const ( // Install implements IInstaller. func (i *AptInstaller) Install() error { name := *i.Info.Name - err := utils.RunCmdPassThrough(i.Info.Environ(), string(i.PackageManager), "update") + err := i.RunCmdPassThrough(string(i.PackageManager), "update") if err != nil { return err } @@ -31,7 +32,7 @@ func (i *AptInstaller) Install() error { if i.PackageManager == PackageManagerApk { install = "add" } - return utils.RunCmdPassThrough(i.Info.Environ(), string(i.PackageManager), install, i.getConfirmArg(), name) + return i.RunCmdPassThrough(string(i.PackageManager), install, i.getConfirmArg(), name) } func (i *AptInstaller) getConfirmArg() string { @@ -44,28 +45,31 @@ func (i *AptInstaller) getConfirmArg() string { // Update implements IInstaller. func (i *AptInstaller) Update() error { - return utils.RunCmdPassThrough(i.Info.Environ(), string(i.PackageManager), "upgrade", i.getConfirmArg(), *i.Info.Name) + return i.RunCmdPassThrough(string(i.PackageManager), "upgrade", i.getConfirmArg(), *i.Info.Name) } // CheckNeedsUpdate implements IInstaller. -func (i *AptInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *AptInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - err := utils.RunCmdPassThrough(i.Info.Environ(), "apk", "update") + err := i.RunCmdPassThrough("apk", "update") if err != nil { - return err, false + return false, err } - err, success := utils.RunCmdGetSuccess(i.Info.Environ(), string(i.PackageManager), "--simulate", "upgrade", *i.Info.Name) + success, err := i.RunCmdGetSuccess(string(i.PackageManager), "--simulate", "upgrade", *i.Info.Name) if err != nil { - return err, false + return false, err } - return nil, !success + return !success, nil } // CheckIsInstalled implements IInstaller. -func (i *AptInstaller) CheckIsInstalled() (error, bool) { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), i.GetBinName()) +func (i *AptInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() + } + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -99,6 +103,7 @@ func NewAptInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerDat packageManager = PackageManagerApk } i := &AptInstaller{ + InstallerBase: InstallerBase{Data: installer}, Config: cfg, Info: installer, PackageManager: packageManager, diff --git a/installer/brew_installer.go b/installer/brew_installer.go index 1f159a6..80823ba 100644 --- a/installer/brew_installer.go +++ b/installer/brew_installer.go @@ -6,6 +6,7 @@ import ( ) type BrewInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData } @@ -20,29 +21,32 @@ func (i *BrewInstaller) Install() error { if i.GetOpts().Tap != nil { name = *i.GetOpts().Tap + "/" + name } - return utils.RunCmdPassThrough(i.Info.Environ(), "brew", "install", name) + return i.RunCmdPassThrough("brew", "install", name) } // Update implements IInstaller. func (i *BrewInstaller) Update() error { - return utils.RunCmdPassThrough(i.Info.Environ(), "brew", "upgrade", *i.Info.Name) + return i.RunCmdPassThrough("brew", "upgrade", *i.Info.Name) } // CheckNeedsUpdate implements IInstaller. -func (i *BrewInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *BrewInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - err, success := utils.RunCmdGetSuccess(i.Info.Environ(), "brew", "outdated", "--json", *i.Info.Name) + success, err := i.RunCmdGetSuccess("brew", "outdated", "--json", *i.Info.Name) if err != nil { - return err, false + return false, err } - return nil, !success + return !success, nil } // CheckIsInstalled implements IInstaller. -func (i *BrewInstaller) CheckIsInstalled() (error, bool) { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), i.GetBinName()) +func (i *BrewInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() + } + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -71,8 +75,9 @@ func (i *BrewInstaller) GetBinName() string { func NewBrewInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *BrewInstaller { i := &BrewInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } return i diff --git a/installer/filter.go b/installer/filter.go index 73baeb9..94587c1 100644 --- a/installer/filter.go +++ b/installer/filter.go @@ -77,7 +77,7 @@ func InstallerIsEnabled(i IInstaller) (bool, error) { shell := utils.GetOSShell(i.GetData().EnvShell) args := utils.GetOSShellArgs(*enabledCmd) - err, success := utils.RunCmdGetSuccess(i.GetData().Environ(), shell, args...) + success, err := utils.RunCmdGetSuccess(i.GetData().Environ(), shell, args...) if err != nil { return false, err diff --git a/installer/git_installer.go b/installer/git_installer.go index d0a8403..341add4 100644 --- a/installer/git_installer.go +++ b/installer/git_installer.go @@ -11,6 +11,7 @@ import ( ) type GitInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData } @@ -23,42 +24,45 @@ type GitOpts struct { // Install implements IInstaller. func (i *GitInstaller) Install() error { args := []string{"clone", i.GetRepositoryUrl(), i.GetInstallDir()} - err := utils.RunCmdPassThrough(i.Info.Environ(), "git", args...) + err := i.RunCmdPassThrough("git", args...) if err != nil { return err } if i.GetOpts().Ref != nil { - return utils.RunCmdPassThrough(i.Info.Environ(), "git", "-C", i.GetInstallDir(), "checkout", *i.GetOpts().Ref) + return i.RunCmdPassThrough("git", "-C", i.GetInstallDir(), "checkout", *i.GetOpts().Ref) } return nil } // Update implements IInstaller. func (i *GitInstaller) Update() error { - return utils.RunCmdPassThrough(i.Info.Environ(), "git", "-C", i.GetInstallDir(), "pull") + return i.RunCmdPassThrough("git", "-C", i.GetInstallDir(), "pull") } // CheckNeedsUpdate implements IInstaller. -func (i *GitInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *GitInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - err, _ := utils.RunCmdGetSuccess(i.Info.Environ(), "git", "-C", i.GetInstallDir(), "fetch") + _, err := i.RunCmdGetSuccess("git", "-C", i.GetInstallDir(), "fetch") if err != nil { - return err, false + return false, err } - output, err := utils.RunCmdGetOutput(i.Info.Environ(), "git", "-C", i.GetInstallDir(), "status", "-uno") + output, err := i.RunCmdGetOutput("git", "-C", i.GetInstallDir(), "status", "-uno") if err != nil { - return err, false + return false, err } if strings.Contains(string(output), "Your branch is behind") { - return nil, true + return true, nil } - return nil, false + return false, nil } // CheckIsInstalled implements IInstaller. -func (i *GitInstaller) CheckIsInstalled() (error, bool) { +func (i *GitInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() + } return utils.PathExists(i.GetInstallDir()) } @@ -108,8 +112,9 @@ func (i *GitInstaller) GetInstallDir() string { func NewGitInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *GitInstaller { i := &GitInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } return i diff --git a/installer/group_installer.go b/installer/group_installer.go index a2714cb..2eb6ded 100644 --- a/installer/group_installer.go +++ b/installer/group_installer.go @@ -7,6 +7,7 @@ import ( ) type GroupInstaller struct { + InstallerBase Config *appconfig.AppConfig Data *appconfig.InstallerData } @@ -21,7 +22,7 @@ func (i *GroupInstaller) Install() error { name := *info.Name logger.Debug("Installing group %s", name) for _, step := range *i.Data.Steps { - err, installer := GetInstaller(i.Config, &step) + installer, err := GetInstaller(i.Config, &step) if err != nil { return err } @@ -40,19 +41,19 @@ func (i *GroupInstaller) Update() error { } // CheckNeedsUpdate implements IInstaller. -func (i *GroupInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Data.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *GroupInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - return nil, true + return true, nil } // CheckIsInstalled implements IInstaller. -func (i *GroupInstaller) CheckIsInstalled() (error, bool) { - if i.GetData().CheckInstalled != nil { - return utils.RunCmdGetSuccess(i.Data.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckInstalled)...) +func (i *GroupInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() } - return utils.RunCmdGetSuccess(i.Data.Environ(), utils.GetShellWhich(), i.GetBinName()) + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -79,7 +80,8 @@ func (i *GroupInstaller) GetBinName() string { func NewGroupInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *GroupInstaller { return &GroupInstaller{ - Config: cfg, - Data: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Data: installer, } } diff --git a/installer/installer.go b/installer/installer.go index ed8bec6..7f46257 100644 --- a/installer/installer.go +++ b/installer/installer.go @@ -9,37 +9,84 @@ import ( type IInstaller interface { GetData() *appconfig.InstallerData - CheckIsInstalled() (error, bool) - CheckNeedsUpdate() (error, bool) + CheckIsInstalled() (bool, error) + CheckNeedsUpdate() (bool, error) Install() error Update() error } -func GetInstaller(config *appconfig.AppConfig, data *appconfig.InstallerData) (error, IInstaller) { +type InstallerBase struct { + Data *appconfig.InstallerData +} + +func GetInstaller(config *appconfig.AppConfig, data *appconfig.InstallerData) (IInstaller, error) { data = InstallerWithDefaults(data, data.Type, config.Defaults) switch data.Type { case appconfig.InstallerTypeGroup: - return nil, NewGroupInstaller(config, data) + return NewGroupInstaller(config, data), nil case appconfig.InstallerTypeBrew: - return nil, NewBrewInstaller(config, data) + return NewBrewInstaller(config, data), nil case appconfig.InstallerTypeShell: - return nil, NewShellInstaller(config, data) + return NewShellInstaller(config, data), nil case appconfig.InstallerTypeRsync: - return nil, NewRsyncInstaller(config, data) + return NewRsyncInstaller(config, data), nil case appconfig.InstallerTypeNpm, appconfig.InstallerTypePnpm, appconfig.InstallerTypeYarn: - return nil, NewNpmInstaller(config, data) + return NewNpmInstaller(config, data), nil case appconfig.InstallerTypeApt, appconfig.InstallerTypeApk: - return nil, NewAptInstaller(config, data) + return NewAptInstaller(config, data), nil case appconfig.InstallerTypePipx: - return nil, NewPipxInstaller(config, data) + return NewPipxInstaller(config, data), nil case appconfig.InstallerTypeGit: - return nil, NewGitInstaller(config, data) + return NewGitInstaller(config, data), nil case appconfig.InstallerTypeManifest: - return nil, NewManifestInstaller(config, data) + return NewManifestInstaller(config, data), nil } return nil, nil } +func (i *InstallerBase) GetData() *appconfig.InstallerData { + return i.Data +} + +func (i *InstallerBase) RunCustomUpdateCheck() (bool, error) { + envShell := utils.GetOSShell(i.GetData().EnvShell) + args := utils.GetOSShellArgs(*i.GetData().CheckHasUpdate) + return utils.RunCmdGetSuccess(i.Data.Environ(), envShell, args...) +} + +func (i *InstallerBase) RunCustomInstallCheck() (bool, error) { + envShell := utils.GetOSShell(i.GetData().EnvShell) + args := utils.GetOSShellArgs(*i.GetData().CheckInstalled) + return utils.RunCmdGetSuccess(i.Data.Environ(), envShell, args...) +} + +func (i *InstallerBase) HasCustomUpdateCheck() bool { + return i.GetData().CheckHasUpdate != nil +} + +func (i *InstallerBase) HasCustomInstallCheck() bool { + return i.GetData().CheckInstalled != nil +} + +func (i *InstallerBase) RunCmdAsFile(command string) error { + data := i.GetData() + return utils.RunCmdAsFile(data.Environ(), command, data.EnvShell) +} + +func (i *InstallerBase) RunCmdPassThrough(command string, args ...string) error { + data := i.GetData() + return utils.RunCmdPassThrough(data.Environ(), command, args...) +} + +func (i *InstallerBase) RunCmdGetSuccess(command string, args ...string) (bool, error) { + data := i.GetData() + return utils.RunCmdGetSuccess(data.Environ(), command, args...) +} +func (i *InstallerBase) RunCmdGetOutput(command string, args ...string) ([]byte, error) { + data := i.GetData() + return utils.RunCmdGetOutput(data.Environ(), command, args...) +} + func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error { info := installer.GetData() name := *info.Name @@ -68,7 +115,7 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error { } logger.Debug("Checking %s (%s)", name, info.Type) - err, installed := installer.CheckIsInstalled() + installed, err := installer.CheckIsInstalled() if err != nil { return err } @@ -76,7 +123,7 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error { logger.Debug("%s (%s) is already installed", name, info.Type) if config.CheckUpdates { logger.Info("Checking updates for %s (%s)", name, info.Type) - err, needsUpdate := installer.CheckNeedsUpdate() + needsUpdate, err := installer.CheckNeedsUpdate() if err != nil { return err } diff --git a/installer/installer_test.go b/installer/installer_test.go index ae9f772..292e118 100644 --- a/installer/installer_test.go +++ b/installer/installer_test.go @@ -22,12 +22,12 @@ func (m *MockInstaller) GetData() *appconfig.InstallerData { return m.data } -func (m *MockInstaller) CheckIsInstalled() (error, bool) { - return m.checkInstall, m.isInstalled +func (m *MockInstaller) CheckIsInstalled() (bool, error) { + return m.isInstalled, m.checkInstall } -func (m *MockInstaller) CheckNeedsUpdate() (error, bool) { - return m.checkUpdate, m.needsUpdate +func (m *MockInstaller) CheckNeedsUpdate() (bool, error) { + return m.needsUpdate, m.checkUpdate } func (m *MockInstaller) Install() error { @@ -42,7 +42,7 @@ func TestGetInstaller(t *testing.T) { config := &appconfig.AppConfig{} logger.InitLogger(config.Debug) installer := &appconfig.InstallerData{Type: appconfig.InstallerTypeBrew} - err, inst := GetInstaller(config, installer) + inst, err := GetInstaller(config, installer) assert.NoError(t, err) assert.NotNil(t, inst) } diff --git a/installer/manifest_installer.go b/installer/manifest_installer.go index e04c25f..e88ac4d 100644 --- a/installer/manifest_installer.go +++ b/installer/manifest_installer.go @@ -11,6 +11,7 @@ import ( ) type ManifestInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData ManifestConfig *appconfig.AppConfig @@ -35,7 +36,7 @@ func (i *ManifestInstaller) Install() error { logger.Info("Installing manifest %s", name) for _, step := range config.Install { logger.Debug("Checking step %s", *step.Name) - err, installer := GetInstaller(config, &step) + installer, err := GetInstaller(config, &step) if err != nil { return err } @@ -54,21 +55,19 @@ func (i *ManifestInstaller) Update() error { } // CheckNeedsUpdate implements IInstaller. -func (i *ManifestInstaller) CheckNeedsUpdate() (error, bool) { - info := i.GetData() - if info.CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(info.Environ(), utils.GetOSShell(info.EnvShell), utils.GetOSShellArgs(*info.CheckHasUpdate)...) +func (i *ManifestInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - return nil, true + return true, nil } // CheckIsInstalled implements IInstaller. -func (i *ManifestInstaller) CheckIsInstalled() (error, bool) { - info := i.GetData() - if info.CheckInstalled != nil { - return utils.RunCmdGetSuccess(info.Environ(), utils.GetOSShell(info.EnvShell), utils.GetOSShellArgs(*info.CheckInstalled)...) +func (i *ManifestInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() } - return nil, false + return false, nil } // GetData implements IInstaller. @@ -128,17 +127,16 @@ func (i *ManifestInstaller) FetchManifest() error { func (i *ManifestInstaller) getGitManifestConfig(source string) (string, error) { opts := i.GetOpts() - info := i.GetData() tmpDir, err := os.MkdirTemp("", "sofmani") defer os.RemoveAll(tmpDir) if err != nil { return "", err } logger.Debug("Cloning %s to %s", source, tmpDir) - err, success := utils.RunCmdGetSuccess(info.Environ(), "git", "clone", "--depth=1", source, tmpDir) + success, err := i.RunCmdGetSuccess("git", "clone", "--depth=1", source, tmpDir) if opts.Ref != nil { logger.Debug("Checking out ref %s", *opts.Ref) - err = utils.RunCmdPassThrough(info.Environ(), "git", "-C", tmpDir, "checkout", *opts.Ref) + err = i.RunCmdPassThrough("git", "-C", tmpDir, "checkout", *opts.Ref) if err != nil { return "", err } @@ -203,7 +201,8 @@ func (i *ManifestInstaller) inheritManifest(config *appconfig.AppConfig) *appcon func NewManifestInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *ManifestInstaller { return &ManifestInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } } diff --git a/installer/npm_installer.go b/installer/npm_installer.go index d2b9690..bf93d31 100644 --- a/installer/npm_installer.go +++ b/installer/npm_installer.go @@ -6,6 +6,7 @@ import ( ) type NpmInstaller struct { + InstallerBase Config *appconfig.AppConfig PackageManager PackageManager Info *appconfig.InstallerData @@ -25,32 +26,32 @@ const ( // Install implements IInstaller. func (i *NpmInstaller) Install() error { - return utils.RunCmdPassThrough(i.Info.Environ(), string(i.PackageManager), "install", "--global", *i.Info.Name) + return i.RunCmdPassThrough(string(i.PackageManager), "install", "--global", *i.Info.Name) } // Update implements IInstaller. func (i *NpmInstaller) Update() error { - return utils.RunCmdPassThrough(i.Info.Environ(), string(i.PackageManager), "install", "--global", *i.Info.Name+"@latest") + return i.RunCmdPassThrough(string(i.PackageManager), "install", "--global", *i.Info.Name+"@latest") } // CheckNeedsUpdate implements IInstaller. -func (i *NpmInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *NpmInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - err, success := utils.RunCmdGetSuccess(i.Info.Environ(), string(i.PackageManager), "outdated", "--global", "--json", *i.Info.Name) + success, err := i.RunCmdGetSuccess(string(i.PackageManager), "outdated", "--global", "--json", *i.Info.Name) if err != nil { - return err, false + return false, err } - return nil, !success + return !success, nil } // CheckIsInstalled implements IInstaller. -func (i *NpmInstaller) CheckIsInstalled() (error, bool) { - if i.GetData().CheckInstalled != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckInstalled)...) +func (i *NpmInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() } - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), i.GetBinName()) + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -83,6 +84,7 @@ func NewNpmInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerDat packageManager = PackageManagerYarn } i := &NpmInstaller{ + InstallerBase: InstallerBase{Data: installer}, Config: cfg, PackageManager: packageManager, Info: installer, diff --git a/installer/pipx_installer.go b/installer/pipx_installer.go index a4622b4..18711de 100644 --- a/installer/pipx_installer.go +++ b/installer/pipx_installer.go @@ -6,6 +6,7 @@ import ( ) type PipxInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData } @@ -17,29 +18,32 @@ type PipxOpts struct { // Install implements IInstaller. func (i *PipxInstaller) Install() error { name := *i.Info.Name - return utils.RunCmdPassThrough(i.Info.Environ(), "pipx", "install", name) + return i.RunCmdPassThrough("pipx", "install", name) } // Update implements IInstaller. func (i *PipxInstaller) Update() error { - return utils.RunCmdPassThrough(i.Info.Environ(), "pipx", "upgrade", *i.Info.Name) + return i.RunCmdPassThrough("pipx", "upgrade", *i.Info.Name) } // CheckNeedsUpdate implements IInstaller. -func (i *PipxInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *PipxInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - err, success := utils.RunCmdGetSuccess(i.Info.Environ(), "pipx", "upgrade", "--pip-args=--dry-run", *i.Info.Name) + success, err := i.RunCmdGetSuccess("pipx", "upgrade", "--pip-args=--dry-run", *i.Info.Name) if err != nil { - return err, false + return false, err } - return nil, !success + return !success, nil } // CheckIsInstalled implements IInstaller. -func (i *PipxInstaller) CheckIsInstalled() (error, bool) { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), i.GetBinName()) +func (i *PipxInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() + } + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -66,8 +70,9 @@ func (i *PipxInstaller) GetBinName() string { func NewPipxInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *PipxInstaller { i := &PipxInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } return i diff --git a/installer/rsync_installer.go b/installer/rsync_installer.go index 7330a2a..a1d5ef3 100644 --- a/installer/rsync_installer.go +++ b/installer/rsync_installer.go @@ -9,6 +9,7 @@ import ( ) type RsyncInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData } @@ -31,15 +32,16 @@ func (i *RsyncInstaller) Install() error { flags = append(flags, flag) } } - - src := utils.GetRealPath(i.Info.Environ(), *i.GetOpts().Source) - dest := utils.GetRealPath(i.Info.Environ(), *i.GetOpts().Destination) + data := i.GetData() + env := data.Environ() + src := utils.GetRealPath(env, *i.GetOpts().Source) + dest := utils.GetRealPath(env, *i.GetOpts().Destination) flags = append(flags, src) flags = append(flags, dest) logger.Debug("rsync %s to %s", src, dest) - return utils.RunCmdPassThrough(i.Info.Environ(), "rsync", flags...) + return i.RunCmdPassThrough("rsync", flags...) } // Update implements IInstaller. @@ -48,19 +50,19 @@ func (i *RsyncInstaller) Update() error { } // CheckNeedsUpdate implements IInstaller. -func (i *RsyncInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckHasUpdate)...) +func (i *RsyncInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - return nil, true + return true, nil } // CheckIsInstalled implements IInstaller. -func (i *RsyncInstaller) CheckIsInstalled() (error, bool) { - if i.GetData().CheckInstalled != nil { - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetOSShell(i.GetData().EnvShell), utils.GetOSShellArgs(*i.GetData().CheckInstalled)...) +func (i *RsyncInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() } - return nil, false + return false, nil } // GetData implements IInstaller. @@ -95,8 +97,9 @@ func (i *RsyncInstaller) GetBinName() string { func NewRsyncInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *RsyncInstaller { i := &RsyncInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } return i diff --git a/installer/shell_installer.go b/installer/shell_installer.go index 787672c..86ac1dd 100644 --- a/installer/shell_installer.go +++ b/installer/shell_installer.go @@ -6,6 +6,7 @@ import ( ) type ShellInstaller struct { + InstallerBase Config *appconfig.AppConfig Info *appconfig.InstallerData } @@ -17,35 +18,31 @@ type ShellOpts struct { // Install implements IInstaller. func (i *ShellInstaller) Install() error { - return utils.RunCmdAsFile(i.Info.Environ(), *i.GetOpts().Command, i.GetData().EnvShell) + return i.RunCmdAsFile(*i.GetOpts().Command) } // Update implements IInstaller. func (i *ShellInstaller) Update() error { if i.GetOpts().UpdateCommand != nil { - return utils.RunCmdAsFile(i.Info.Environ(), *i.GetOpts().UpdateCommand, i.GetData().EnvShell) + return i.RunCmdAsFile(*i.GetOpts().UpdateCommand) } return i.Install() } // CheckNeedsUpdate implements IInstaller. -func (i *ShellInstaller) CheckNeedsUpdate() (error, bool) { - if i.GetData().CheckHasUpdate != nil { - shell := utils.GetOSShell(i.GetData().EnvShell) - args := utils.GetOSShellArgs(*i.GetData().CheckHasUpdate) - return utils.RunCmdGetSuccess(i.Info.Environ(), shell, args...) +func (i *ShellInstaller) CheckNeedsUpdate() (bool, error) { + if i.HasCustomUpdateCheck() { + return i.RunCustomUpdateCheck() } - return nil, false + return false, nil } // CheckIsInstalled implements IInstaller. -func (i *ShellInstaller) CheckIsInstalled() (error, bool) { - if i.GetData().CheckInstalled != nil { - shell := utils.GetOSShell(i.GetData().EnvShell) - args := utils.GetOSShellArgs(*i.GetData().CheckInstalled) - return utils.RunCmdGetSuccess(i.Info.Environ(), shell, args...) +func (i *ShellInstaller) CheckIsInstalled() (bool, error) { + if i.HasCustomInstallCheck() { + return i.RunCustomInstallCheck() } - return utils.RunCmdGetSuccess(i.Info.Environ(), utils.GetShellWhich(), i.GetBinName()) + return i.RunCmdGetSuccess(utils.GetShellWhich(), i.GetBinName()) } // GetData implements IInstaller. @@ -77,7 +74,8 @@ func (i *ShellInstaller) GetBinName() string { func NewShellInstaller(cfg *appconfig.AppConfig, installer *appconfig.InstallerData) *ShellInstaller { return &ShellInstaller{ - Config: cfg, - Info: installer, + InstallerBase: InstallerBase{Data: installer}, + Config: cfg, + Info: installer, } } diff --git a/main.go b/main.go index c8c5335..f7b9348 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func main() { logger.Info("Checking all installers...") for _, i := range cfg.Install { - err, installerInstance := installer.GetInstaller(cfg, &i) + installerInstance, err := installer.GetInstaller(cfg, &i) if err != nil { logger.Error("%s", err) return diff --git a/utils/command.go b/utils/command.go index 6f4486a..7f7daac 100644 --- a/utils/command.go +++ b/utils/command.go @@ -41,15 +41,15 @@ func RunCmdPassThroughChained(env []string, commands [][]string) error { return nil } -func RunCmdGetSuccess(env []string, bin string, args ...string) (error, bool) { +func RunCmdGetSuccess(env []string, bin string, args ...string) (bool, error) { logger.Debug("Running command: %s %v", bin, args) cmd := exec.Command(bin, args...) cmd.Env = ResolveEnvPaths(os.Environ(), cmd.Env, env) err := cmd.Run() if err != nil { - return nil, false + return false, nil } - return nil, true + return true, nil } func RunCmdGetOutput(env []string, bin string, args ...string) ([]byte, error) { diff --git a/utils/fs.go b/utils/fs.go index 0c5cd94..e53a42a 100644 --- a/utils/fs.go +++ b/utils/fs.go @@ -33,8 +33,8 @@ func GetRealPath(env []string, path string) string { return strings.TrimSpace(string(path)) } -func PathExists(path string) (error, bool) { +func PathExists(path string) (bool, error) { _, err := os.Stat(path) exists := !errors.Is(err, fs.ErrNotExist) - return nil, exists + return exists, nil }