diff --git a/cmd/cardano-up/uninstall.go b/cmd/cardano-up/uninstall.go index 3a44cde..ab61928 100644 --- a/cmd/cardano-up/uninstall.go +++ b/cmd/cardano-up/uninstall.go @@ -24,8 +24,12 @@ import ( "github.com/spf13/cobra" ) +var uninstallFlags = struct { + keepData bool +}{} + func uninstallCommand() *cobra.Command { - return &cobra.Command{ + uninstallCmd := &cobra.Command{ Use: "uninstall", Short: "Uninstall package", Args: func(cmd *cobra.Command, args []string) error { @@ -44,10 +48,12 @@ func uninstallCommand() *cobra.Command { os.Exit(1) } // Uninstall package - if err := pm.Uninstall(args[0]); err != nil { + if err := pm.Uninstall(uninstallFlags.keepData, args[0]); err != nil { slog.Error(err.Error()) os.Exit(1) } }, } + uninstallCmd.Flags().BoolVarP(&uninstallFlags.keepData, "keep-data", "k", false, "don't cleanup package data") + return uninstallCmd } diff --git a/pkgmgr/package.go b/pkgmgr/package.go index 983d42e..5bcd436 100644 --- a/pkgmgr/package.go +++ b/pkgmgr/package.go @@ -118,7 +118,7 @@ func (p Package) install(cfg Config, context string) (string, error) { return "", nil } -func (p Package) uninstall(cfg Config, context string) error { +func (p Package) uninstall(cfg Config, context string, keepData bool) error { pkgName := fmt.Sprintf("%s-%s-%s", p.Name, p.Version, context) // Iterate over install steps in reverse for idx := len(p.InstallSteps) - 1; idx >= 0; idx-- { @@ -129,7 +129,7 @@ func (p Package) uninstall(cfg Config, context string) error { return ErrMultipleInstallMethods } if installStep.Docker != nil { - if err := installStep.Docker.uninstall(cfg, pkgName); err != nil { + if err := installStep.Docker.uninstall(cfg, pkgName, keepData); err != nil { return err } } else if installStep.File != nil { @@ -140,6 +140,54 @@ func (p Package) uninstall(cfg Config, context string) error { return ErrNoInstallMethods } } + if keepData { + cfg.Logger.Debug( + "skipping cleanup of package data/cache directories", + ) + } else { + // Remove package cache dir + pkgCacheDir := filepath.Join( + cfg.CacheDir, + pkgName, + ) + if err := os.RemoveAll(pkgCacheDir); err != nil { + cfg.Logger.Warn( + fmt.Sprintf( + "failed to remove package cache directory %q: %s", + pkgCacheDir, + err, + ), + ) + } else { + cfg.Logger.Debug( + fmt.Sprintf( + "removed package cache directory %q", + pkgCacheDir, + ), + ) + } + // Remove package data dir + pkgDataDir := filepath.Join( + cfg.DataDir, + pkgName, + ) + if err := os.RemoveAll(pkgDataDir); err != nil { + cfg.Logger.Warn( + fmt.Sprintf( + "failed to remove package data directory %q: %s", + pkgDataDir, + err, + ), + ) + } else { + cfg.Logger.Debug( + fmt.Sprintf( + "removed package data directory %q", + pkgCacheDir, + ), + ) + } + } return nil } @@ -322,7 +370,7 @@ func (p *PackageInstallStepDocker) install(cfg Config, pkgName string) error { return nil } -func (p *PackageInstallStepDocker) uninstall(cfg Config, pkgName string) error { +func (p *PackageInstallStepDocker) uninstall(cfg Config, pkgName string, keepData bool) error { if !p.PullOnly { containerName := fmt.Sprintf("%s-%s", pkgName, p.ContainerName) svc, err := NewDockerServiceFromContainerName(containerName, cfg.Logger) @@ -338,21 +386,30 @@ func (p *PackageInstallStepDocker) uninstall(cfg Config, pkgName string) error { return err } } - if err := RemoveDockerImage(p.Image); err != nil { + if keepData { cfg.Logger.Debug( fmt.Sprintf( - "failed to delete image %q: %s", + "skipping deletion of docker image %q", p.Image, - err, ), ) } else { - cfg.Logger.Debug( - fmt.Sprintf( - "removed unused image %q", - p.Image, - ), - ) + if err := RemoveDockerImage(p.Image); err != nil { + cfg.Logger.Debug( + fmt.Sprintf( + "failed to delete image %q: %s", + p.Image, + err, + ), + ) + } else { + cfg.Logger.Debug( + fmt.Sprintf( + "removed unused image %q", + p.Image, + ), + ) + } } return nil } @@ -415,7 +472,7 @@ func (p *PackageInstallStepFile) uninstall(cfg Config, pkgName string) error { ) cfg.Logger.Debug(fmt.Sprintf("deleting file %s", filePath)) if err := os.Remove(filePath); err != nil { - cfg.Logger.Debug(fmt.Sprintf("failed to remove file %s", filePath)) + cfg.Logger.Warn(fmt.Sprintf("failed to remove file %s", filePath)) } if p.Binary { binPath := filepath.Join( @@ -423,7 +480,7 @@ func (p *PackageInstallStepFile) uninstall(cfg Config, pkgName string) error { p.Filename, ) if err := os.Remove(binPath); err != nil { - cfg.Logger.Debug(fmt.Sprintf("failed to remove symlink %s", binPath)) + cfg.Logger.Warn(fmt.Sprintf("failed to remove symlink %s", binPath)) } } return nil diff --git a/pkgmgr/pkgmgr.go b/pkgmgr/pkgmgr.go index 982c8a3..2fc7583 100644 --- a/pkgmgr/pkgmgr.go +++ b/pkgmgr/pkgmgr.go @@ -219,7 +219,7 @@ func (p *PackageManager) Upgrade(pkgs ...string) error { ), ) // Uninstall old version - if err := p.uninstallPackage(upgradePkg.Installed); err != nil { + if err := p.uninstallPackage(upgradePkg.Installed, true); err != nil { return err } // Install new version @@ -259,7 +259,7 @@ func (p *PackageManager) Upgrade(pkgs ...string) error { return nil } -func (p *PackageManager) Uninstall(pkgs ...string) error { +func (p *PackageManager) Uninstall(keepData bool, pkgs ...string) error { // Find installed packages activeContextName, _ := p.ActiveContext() installedPackages := p.InstalledPackages() @@ -294,7 +294,7 @@ func (p *PackageManager) Uninstall(pkgs ...string) error { return err } for _, uninstallPkg := range uninstallPkgs { - if err := p.uninstallPackage(uninstallPkg); err != nil { + if err := p.uninstallPackage(uninstallPkg, keepData); err != nil { return err } if err := p.state.Save(); err != nil { @@ -412,9 +412,9 @@ func (p *PackageManager) Info(pkgs ...string) error { return nil } -func (p *PackageManager) uninstallPackage(uninstallPkg InstalledPackage) error { +func (p *PackageManager) uninstallPackage(uninstallPkg InstalledPackage, keepData bool) error { // Uninstall package - if err := uninstallPkg.Package.uninstall(p.config, uninstallPkg.Context); err != nil { + if err := uninstallPkg.Package.uninstall(p.config, uninstallPkg.Context, keepData); err != nil { return err } // Remove package from installed packages