diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 8bc3b8a..3a2d8da 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,8 +1,3 @@ -# This is an example .goreleaser.yml file with some sensible defaults. -# Make sure to check the documentation at https://goreleaser.com - -# The lines below are called `modelines`. See `:help modeline` -# Feel free to remove those if you don't want/need to use them. # yaml-language-server: $schema=https://goreleaser.com/static/schema.json # vim: set ts=2 sw=2 tw=0 fo=cnqoj @@ -10,11 +5,9 @@ version: 2 before: hooks: - # You may remove this if you don't use go modules. - go mod tidy - # you may remove this if you don't need go generate - go generate ./... - - go test ./... + - go test ./... -v builds: - env: @@ -26,7 +19,6 @@ builds: archives: - format: tar.gz - # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- {{ .ProjectName }}_ {{- title .Os }}_ @@ -34,7 +26,6 @@ archives: {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} - # use zip for windows archives format_overrides: - goos: windows format: zip diff --git a/cargo.go b/cargo.go index 8935969..a5a80d8 100644 --- a/cargo.go +++ b/cargo.go @@ -34,3 +34,12 @@ func (c *CargoManager) InstallPackage(pkg string) error { cmd := execCommand("cargo", "install", pkg) return cmd.Run() } + +func (c *CargoManager) RemovePackage(pkg string) error { + cmd := execCommand("cargo", "uninstall", pkg) + return cmd.Run() +} + +func (c *CargoManager) SearchPackage(pkg string) []string { + return []string{} +} diff --git a/cmd.go b/cmd.go index 67d69b2..598ccdb 100644 --- a/cmd.go +++ b/cmd.go @@ -2,10 +2,7 @@ package main import ( "fmt" - "log" "os" - "os/exec" - "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -17,24 +14,6 @@ var rootCmd = &cobra.Command{ Run: run, } -var searchCmd = &cobra.Command{ - Use: "search [package_name]", - Short: "Search for a package across package managers (will search in os|flatpak|homebrew)", - Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { - packageName := args[0] - - managers := []string{"brew", "os", "flatpak"} - - for _, manager := range managers { - fmt.Printf("Searching in %s:\n", manager) - results := searchPackage(packageName, manager) - displayResults(results, manager) - fmt.Println() - } - }, -} - func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringP("config", "c", "", "Path to the configuration file") @@ -52,8 +31,14 @@ func init() { enableCmd.Flags().Bool("value", true, "Set to true to enable, false to disable") + installCmd.Flags().StringP("manager", "m", "os", "The package manager you want to install a package with. (Options: os|homebrew|pipx|flatpak|cargo)") + + removeCmd.Flags().StringP("manager", "m", "os", "The package manager you want to remove a package with. (Options: os|homebrew|pipx|flatpak|cargo)") + + searchCmd.Flags().StringP("manager", "m", "", "The package manager you want to search a package with. (Options: os|homebrew|flatpak)") + packageCmd.AddCommand(addCmd, deleteCmd, showCmd, enableCmd) - rootCmd.AddCommand(packageCmd, searchCmd) + rootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd) } func initConfig() { @@ -70,57 +55,3 @@ func initConfig() { os.Exit(1) } } - -func displayResults(results []string, manager string) { - if len(results) == 0 { - fmt.Printf("No results found in %s\n", manager) - return - } - for _, result := range results { - fmt.Printf("- %s\n", result) - } -} - -func searchPackage(packageName, manager string) []string { - switch manager { - case "brew": - cmd := exec.Command("brew", "search", packageName) - packages, err := cmd.Output() - if err != nil { - log.Printf("error fetching %s packages: %v", manager, err) - } - packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") - return packageList - case "os": - opSys, err := getLinuxDistribution() - if err != nil { - log.Printf("Error getting OS information: %v", err) - return []string{} - } - - cmdParts := strings.Fields(opSys.SearchCommand) - if len(cmdParts) == 0 { - log.Printf("Invalid search command for OS package manager") - return []string{} - } - - cmd := exec.Command(cmdParts[0], append(cmdParts[1:], packageName)...) - packages, err := cmd.Output() - if err != nil { - log.Printf("Error fetching %s packages: %v", manager, err) - return []string{} - } - - packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") - return packageList - case "flatpak": - cmd := exec.Command("flatpak", "search", packageName) - packages, err := cmd.Output() - if err != nil { - log.Printf("error fetching %s packages: %v", manager, err) - } - packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") - return packageList - } - return []string{"Beispielpaket 1", "Beispielpaket 2"} // Platzhalter -} diff --git a/flatpak.go b/flatpak.go index 4f2bf4c..0c926bc 100644 --- a/flatpak.go +++ b/flatpak.go @@ -2,7 +2,9 @@ package main import ( "fmt" + "log" "os/exec" + "strings" ) type FlatpakManager struct { @@ -87,3 +89,18 @@ func (f *FlatpakManager) InstallPackage(pkg string) error { cmd := execCommand("flatpak", "install", "-y", pkg) return cmd.Run() } + +func (f *FlatpakManager) RemovePackage(pkg string) error { + cmd := execCommand("flatpak", "uninstall", "-y", pkg) + return cmd.Run() +} + +func (f *FlatpakManager) SearchPackage(pkg string) []string { + cmd := execCommand("flatpak", "search", pkg) + packages, err := cmd.Output() + if err != nil { + log.Printf("error fetching %s packages: %v", f.Name(), err) + } + packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") + return packageList +} diff --git a/golang.go b/golang.go index b209eab..690c2d4 100644 --- a/golang.go +++ b/golang.go @@ -34,3 +34,12 @@ func (g *GolangManager) InstallPackage(pkg string) error { cmd := execCommand("go", "install", pkg+"@latest") return cmd.Run() } + +func (g *GolangManager) RemovePackage(pkg string) error { + cmd := execCommand("go", "uninstall", pkg) + return cmd.Run() +} + +func (g *GolangManager) SearchPackage(pkg string) []string { + return []string{} +} diff --git a/homebrew.go b/homebrew.go index 528631f..9cd259d 100644 --- a/homebrew.go +++ b/homebrew.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "log" + "strings" ) type HomebrewManager struct{} @@ -41,3 +43,18 @@ func (h *HomebrewManager) InstallPackage(pkg string) error { cmd := execCommand("brew", "install", pkg) return cmd.Run() } + +func (h *HomebrewManager) RemovePackage(pkg string) error { + cmd := execCommand("brew", "uninstall", pkg) + return cmd.Run() +} + +func (h *HomebrewManager) SearchPackage(pkg string) []string { + cmd := execCommand("brew", "search", pkg) + packages, err := cmd.Output() + if err != nil { + log.Printf("error fetching %s packages: %v", h.Name(), err) + } + packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") + return packageList +} diff --git a/install_cmd.go b/install_cmd.go new file mode 100644 index 0000000..468ab9f --- /dev/null +++ b/install_cmd.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "log" + + "github.com/spf13/cobra" +) + +var installCmd = &cobra.Command{ + Use: "install [package_name]", + Short: "Install a package with the specified package manager", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + packageName := args[0] + managerName, _ := cmd.Flags().GetString("manager") + var manager PackageManager + switch managerName { + case "os": + opSys, err := getLinuxDistribution() + if err != nil { + log.Printf("error getting OS information: %v", err) + } + sudoPassword, err := getSudoPassword() + if err != nil { + log.Fatal(err) + } + osManager := NewOSManager(opSys, sudoPassword, []string{packageName}) + if err := osManager.Install([]string{packageName}); err != nil { + log.Printf("error: %v\n", err) + } + case "homebrew": + manager = &HomebrewManager{} + case "cargo": + manager = &CargoManager{} + case "pipx": + manager = &PipxManager{} + case "flatpak": + manager = &FlatpakManager{} + default: + fmt.Println("No PackageManager found") + } + if err := manager.InstallPackage(packageName); err != nil { + log.Printf("error: %v\n", err) + } + }, +} diff --git a/osinfo.go b/osinfo.go index dad41ef..bba7397 100644 --- a/osinfo.go +++ b/osinfo.go @@ -40,6 +40,10 @@ func (o *OSManager) Install(packages []string) error { return err } +func (o *OSManager) InstallPackage(pkg string) error { + return installPackage(o.OS.InstallCommand, pkg, o.SudoPassword) +} + func (o *OSManager) InstallBuildEssentials() error { return installBuildEssentials(o.OS, o.SudoPassword) } @@ -48,13 +52,40 @@ func (o *OSManager) InstallSpecialSoftware() error { return o.Model.installSpecialSoftware() } +func (o *OSManager) RemovePackage(pkg string) error { + fullCmd := fmt.Sprintf("%s %s", o.OS.RemoveCommand, pkg) + command := execCommand("sudo", "-S", "sh", "-c", fullCmd) + command.Stdin = strings.NewReader(o.SudoPassword + "\n") + return command.Run() +} + +func (o *OSManager) SearchPackage(pkg string) []string { + + cmdParts := strings.Fields(o.OS.SearchCommand) + if len(cmdParts) == 0 { + log.Printf("Invalid search command for OS package manager") + return []string{} + } + + cmd := execCommand(cmdParts[0], append(cmdParts[1:], pkg)...) + packages, err := cmd.Output() + if err != nil { + log.Printf("Error fetching %s packages: %v", o.OS.PackageManager, err) + return []string{} + } + + packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") + return packageList +} + type OS struct { ID string Name string Version string PackageManager string InstallCommand string - SearchCommand string // TODO: has to be implemented + SearchCommand string + RemoveCommand string } func parseOsRelease(osRelease string) *OS { @@ -166,6 +197,22 @@ func (os *OS) getSearchCommand() error { } } +func (os *OS) getDeleteCommand() error { + switch os.PackageManager { + case "apt": + os.RemoveCommand = "apt remove" + return nil + case "pacman": + os.RemoveCommand = "pacman -R" + return nil + case "dnf": + os.RemoveCommand = "dnf remove" + return nil + default: + return fmt.Errorf("no install command found for package manager: %s", os.ID) + } +} + func installBuildEssentials(os *OS, sudoPassword string) error { var command string switch os.PackageManager { diff --git a/packagemanager.go b/packagemanager.go index 388540c..a5f17c2 100644 --- a/packagemanager.go +++ b/packagemanager.go @@ -4,5 +4,7 @@ type PackageManager interface { Install(packages []string) error InstallPackage(pkg string) error InstallManager() error + RemovePackage(pkg string) error + SearchPackage(pkg string) []string Name() string } diff --git a/pipx.go b/pipx.go index ddbcd34..8f6820a 100644 --- a/pipx.go +++ b/pipx.go @@ -35,3 +35,12 @@ func (p *PipxManager) InstallPackage(pkg string) error { cmd := execCommand("pipx", "install", pkg) return cmd.Run() } + +func (p *PipxManager) RemovePackage(pkg string) error { + cmd := execCommand("pipx", "uninstall", pkg) + return cmd.Run() +} + +func (p *PipxManager) SearchPackage(pkg string) []string { + return []string{} +} diff --git a/remove_cmd.go b/remove_cmd.go new file mode 100644 index 0000000..6609578 --- /dev/null +++ b/remove_cmd.go @@ -0,0 +1,45 @@ +package main + +import ( + "log" + + "github.com/spf13/cobra" +) + +var removeCmd = &cobra.Command{ + Use: "remove [package_name]", + Short: "Remove a package with the specified package manager", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + packageName := args[0] + managerName, _ := cmd.Flags().GetString("manager") + var manager PackageManager + switch managerName { + case "os": + opSys, err := getLinuxDistribution() + if err != nil { + log.Printf("error getting OS information: %v", err) + } + sudoPassword, err := getSudoPassword() + if err != nil { + log.Fatal(err) + } + osManager := NewOSManager(opSys, sudoPassword, []string{packageName}) + if err := osManager.Install([]string{packageName}); err != nil { + log.Printf("error: %v\n", err) + } + case "homebrew": + manager = &HomebrewManager{} + case "cargo": + manager = &CargoManager{} + case "pipx": + manager = &PipxManager{} + case "flatpak": + manager = &FlatpakManager{} + default: + } + if err := manager.RemovePackage(packageName); err != nil { + log.Printf("error: %v\n", err) + } + }, +} diff --git a/search_cmd.go b/search_cmd.go new file mode 100644 index 0000000..8514355 --- /dev/null +++ b/search_cmd.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "log" + "strings" + + "github.com/spf13/cobra" +) + +var searchCmd = &cobra.Command{ + Use: "search [package_name]", + Short: "Search for a package across package managers (will search in os|flatpak|homebrew)", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + packageName := args[0] + managerName, _ := cmd.Flags().GetString("manager") + if managerName == "os" { + managerName = "OS Package Manager" + } + opSys, err := getLinuxDistribution() + if err != nil { + log.Printf("error getting OS information: %v", err) + return + } + + managers := []PackageManager{ + NewOSManager(opSys, "", nil), + &HomebrewManager{}, + &FlatpakManager{}, + } + + if managerName != "" { + for _, m := range managers { + if strings.EqualFold(m.Name(), managerName) { + searchAndDisplayResults(m, packageName) + return + } + } + fmt.Printf("Not supported for '%s'\n", managerName) + return + } + + for _, manager := range managers { + searchAndDisplayResults(manager, packageName) + } + }, +} + +func displayResults(results []string, manager string) { + if len(results) == 0 { + fmt.Printf("No results found in %s\n", manager) + return + } + for _, result := range results { + fmt.Printf("- %s\n", result) + } +} + +func searchAndDisplayResults(manager PackageManager, packageName string) { + fmt.Printf("Searching in %s:\n", manager.Name()) + results := manager.SearchPackage(packageName) + displayResults(results, manager.Name()) + fmt.Println() +} diff --git a/utils_test.go b/utils_test.go index 20dcde6..ffd2eaa 100644 --- a/utils_test.go +++ b/utils_test.go @@ -53,7 +53,6 @@ func TestInstallWithProgress(t *testing.T) { } } -// MockPackageManager implementiert das PackageManager Interface für Tests type MockPackageManager struct { packages []string installedPackages []string @@ -76,3 +75,11 @@ func (m *MockPackageManager) InstallManager() error { func (m *MockPackageManager) Name() string { return "MockManager" } + +func (m *MockPackageManager) RemovePackage(pkg string) error { + return nil +} + +func (m *MockPackageManager) SearchPackage(pkg string) []string { + return nil +}