Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ backplane-tools offers an easy solution to install, remove, and upgrade a useful
- [Upgrade a specific thing](#upgrade-a-specific-thing)
- [Remove everything](#remove-everything)
- [Remove a specific thing](#remove-a-specific-thing)
- [Cleanup everything](#cleanup-everything)
- [Cleanup a specific thing](#cleanup-a-specific-thing)
- [Design](#design)
- [Directory Structure](#directory-structure)
- [Installing](#installing)
- [Upgrading](#upgrading)
- [Removing](#removing)
- [Cleaning up](#cleaning-up)
<!-- tocstop -->

## Tools
Expand Down Expand Up @@ -155,6 +158,16 @@ backplane-tools remove all
backplane-tools remove <tool name>
```

### Cleanup everything
```shell
backplane-tools cleanup all
```

### Cleanup a specific thing
```shell
backplane-tools cleanup <tool name>
```

## Design

backplane-tools strives to be simplistic and non-invasive; it should not conflict with currently installed programs, nor should it require extensive research before operating.
Expand Down Expand Up @@ -215,3 +228,10 @@ Users are able to remove individual tools or completely remove all files and dat
`backplane-tools remove <toolA> <toolB> ...` allows users to remove a specific set of tools from their system. This is done by removing the tool-specific directory at `$HOME/.local/bin/backplane/<tool name>`, as well as the tool's linked executable in `$HOME/.local/bin/backplane/latest/`.

`backplane-tools remove all` allows users to remove everything managed by backplane-tools. This is done by completely removing `$HOME/.bin/local/backplane/`. Subsequent calls to `backplane-tools install` will cause the directory structure to be recreated from scratch.

### Cleaning up
Users are able to remove older versions of individual or all tools managed by backplane-tools.

`backplane-tools cleanup <toolA> <toolB> ...` allows users to cleanup older versions of a specific set of tools from their system. This is done by removing the tool-specific directory at `$HOME/.local/bin/backplane/<tool name>/<old_version>`, keeping only the latest installed version as well as the tool's linked executable in `$HOME/.local/bin/backplane/latest/`.

`backplane-tools cleanup all` allows users to remove older versions of everything managed by backplane-tools. This is done by removing `$HOME/.bin/local/backplane/<tool name>/<old_version>`.
61 changes: 61 additions & 0 deletions cmd/cleanup/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cleanup

import (
"fmt"
"strings"

"github.com/openshift/backplane-tools/pkg/tools"
"github.com/openshift/backplane-tools/pkg/utils"
"github.com/spf13/cobra"
)

// Cmd returns the Command used to invoke the upgrade logic
func Cmd() *cobra.Command {
toolNames := tools.Names()
cleanupCmd := &cobra.Command{
Use: fmt.Sprintf("cleanup [all|%s]", strings.Join(toolNames, "|")),
Aliases: []string{"clean-up"},
Args: cobra.OnlyValidArgs,
ValidArgs: append(toolNames, "all"),
Short: "Cleans up older versions of existing tool",
Long: "Cleans up older versions and keeps only the latest installed version of one or more tools from the provided list. It's valid to specify multiple tools: in this case, all tools provided will be cleaned up. If no specific tools are provided, all are cleaned up by default.",
RunE: func(_ *cobra.Command, args []string) error {
return Cleanup(args)
},
}
return cleanupCmd
}

// run cleanup the tool(s) specified by the provided positional args
func Cleanup(args []string) error {
var listTools []tools.Tool
if len(args) == 0 || utils.Contains(args, "all") {
// If user explicitly passes 'all' or doesn't specify which tools to clean up,
// everything that's been installed locally will be cleaned up
var err error
listTools, err = tools.ListInstalled()
if err != nil {
return err
}
} else {
// otherwise build the list verifying tool exist
toolMap := tools.GetMap()

listTools = []tools.Tool{}
for _, toolName := range args {
t, found := toolMap[toolName]
if !found {
return fmt.Errorf("failed to locate '%s' in list of supported tools", toolName)
}
listTools = append(listTools, t)
}
}

fmt.Println("Cleaning up the following tools: ")

err := tools.Cleanup(listTools)
if err != nil {
return fmt.Errorf("failed to clean up tools: %w", err)
}
return nil
}
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"log"

"github.com/openshift/backplane-tools/cmd/cleanup"
"github.com/openshift/backplane-tools/cmd/install"
"github.com/openshift/backplane-tools/cmd/list"
"github.com/openshift/backplane-tools/cmd/remove"
Expand All @@ -27,6 +28,7 @@ func init() {
cmd.AddCommand(list.Cmd())
cmd.AddCommand(remove.Cmd())
cmd.AddCommand(upgrade.Cmd())
cmd.AddCommand(cleanup.Cmd())
}

func main() {
Expand Down
43 changes: 43 additions & 0 deletions pkg/tools/base/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,46 @@ func (t *Default) InstalledVersion() (string, error) {
}
return t.installedVersion, nil
}

// Cleanup removes all previous versions of an installed tool except the currently linked version
func (t *Default) Cleanup() (string, error) {
toolDir := t.ToolDir()

// Get the currently installed version (the one linked in latest/)
currentVersion, err := t.InstalledVersion()
if err != nil {
return "", fmt.Errorf("failed to get installed version: %w", err)
}

// Read all version directories in the tool directory
entries, err := os.ReadDir(toolDir)
if err != nil {
return "", fmt.Errorf("failed to read tool directory %s: %w", toolDir, err)
}

removedVersions := []string{}
for _, entry := range entries {
if !entry.IsDir() {
continue
}

// Skip the current version
if entry.Name() == currentVersion {
continue
}

// Remove old version directory
versionPath := filepath.Join(toolDir, entry.Name())
err = os.RemoveAll(versionPath)
if err != nil {
return strings.Join(removedVersions, ", "), fmt.Errorf("failed to remove version %s: %w", entry.Name(), err)
}
removedVersions = append(removedVersions, entry.Name())
}

if len(removedVersions) == 0 {
return "no old versions found", nil
}

return fmt.Sprintf("removed versions: %s", strings.Join(removedVersions, ", ")), nil
}
18 changes: 18 additions & 0 deletions pkg/tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ type Tool interface {

// LatestVersion gets the latest version available on repo
LatestVersion() (string, error)

// Cleanup removes all previous versions of an installed tool
Cleanup() (string, error)
}

var toolMap map[string]Tool
Expand Down Expand Up @@ -202,3 +205,18 @@ func ListInstalled() ([]Tool, error) {
}
return installedTools, nil
}

func Cleanup(tools []Tool) error {
for _, tool := range tools {
fmt.Println()
fmt.Printf("Removing %s\n", tool.Name())
msg, err := tool.Cleanup()
if err != nil {
fmt.Printf("Encountered error while cleaning up %s: %v\n", tool.Name(), err)
fmt.Println("Skipping...")
} else {
fmt.Printf("Successfully cleaned up %s: %s\n", tool.Name(), msg)
}
}
return nil
}