Compare commits

...

34 commits
v0.3.1 ... main

Author SHA1 Message Date
ea317efaa4 chore(deps): update dependencies 2026-01-10 17:10:38 +01:00
git
5c00c164dd Merge pull request 'chore(deps): update module golang.org/x/sys to v0.34.0' (#8) from renovate/golang.org-x-sys-0.x into main
Reviewed-on: #8
2025-09-07 12:38:38 +02:00
Renovate Bot
0a7a1c43d9 chore(deps): update module golang.org/x/sys to v0.34.0 2025-07-25 07:31:51 +00:00
e5ef2f0b88 deps: update dependencies and supported go version 2025-06-25 11:05:01 +02:00
9597007953 refactor: replace for loop over slice 2025-06-20 13:24:09 +02:00
git
73881bf9b5 Merge pull request 'chore(deps): update module golang.org/x/sys to v0.33.0' (#7) from renovate/golang.org-x-sys-0.x into main
Reviewed-on: #7
2025-06-05 08:14:44 +02:00
Renovate Bot
3cd2187932 chore(deps): update module golang.org/x/sys to v0.33.0 2025-06-04 20:06:30 +00:00
git
956aad51f5 Merge pull request 'chore(deps): update module github.com/spf13/cobra to v1.9.1' (#5) from renovate/github.com-spf13-cobra-1.x into main
Reviewed-on: #5
2025-06-04 20:12:07 +02:00
git
2081b002e5 Merge pull request 'chore(deps): update module github.com/charmbracelet/huh to v0.7.0' (#4) from renovate/github.com-charmbracelet-huh-0.x into main
Reviewed-on: #4
2025-06-04 20:11:55 +02:00
Renovate Bot
fc2372e0b1 chore(deps): update module github.com/spf13/cobra to v1.9.1 2025-06-04 18:03:54 +00:00
Renovate Bot
9c8b19405a chore(deps): update module github.com/charmbracelet/huh to v0.7.0 2025-06-04 18:03:41 +00:00
git
db4892c08a Merge pull request 'chore: Configure Renovate' (#3) from renovate/configure into main
Reviewed-on: #3
2025-06-04 19:20:59 +02:00
Renovate Bot
2f5c05bea2 Add renovate.json 2025-06-04 10:48:25 +00:00
594d7e48f5 chore: update modul name and imports. 2025-02-04 16:31:55 +01:00
5a92382063 chore(go.mod): update module name 2025-02-04 16:23:38 +01:00
179e2a6ec3 chore(docs): prepare release 2025-02-04 16:16:18 +01:00
0cc50e15c9 docs(cli): update version 2025-02-04 16:11:55 +01:00
e49138fdd2 refactor(packagemanager,cli,tui): move packages in specific subfolders 2025-02-04 16:11:03 +01:00
11b8541630 feat(cli): add check command 2025-01-31 17:56:02 +01:00
3519efeccc update Changelog.md 2025-01-24 10:28:04 +01:00
b18b7761fc refactor(cli): perform code clean up 2025-01-24 10:24:48 +01:00
7d4a54b34c feat(cli): add max history length 2025-01-24 10:11:32 +01:00
8ed3b0c013 feat(cli): add history command and logging for actions 2025-01-24 09:24:59 +01:00
f8abf29594 feat(config): add creation of default config if no config exists 2025-01-24 08:10:09 +01:00
70dbc9e062 feat(cli): add aliases to commands 2025-01-23 07:59:26 +01:00
53a50f2be4 fix(packagemanager): reimplement getPackagemanager to enable installing buildtools on linux 2025-01-22 13:21:47 +01:00
afaf7707aa feat(cli): add concurrent execution of search and update to improve performance 2025-01-20 22:10:19 +01:00
0306ad36ef docs: update changelog.md 2025-01-20 21:37:35 +01:00
05e774764f fix(packagemanager): added missing build tag for macos 2025-01-20 21:37:13 +01:00
fc966df8f5 docs: update changelog.md 2025-01-20 21:33:07 +01:00
8281883e4d feat(cli,packagemanager): implemented first working windows and macos versions
in order to implement sst for windows and macos the structure of
osmanager has been changed.
Now osmanager has a new field pm, which contains the specific
packagemanager for the os.
Linux packagemanagers have been implemented as packagemanagers on their
own.
2025-01-20 21:28:44 +01:00
8dabc7357b feat(packagemanager): added packagemanager definitions for winget and chocolatey 2025-01-19 22:54:49 +01:00
43eb3ae4cb Merge branch 'dev/add-update-command' into development
* dev/add-update-command:
  feat(cli): add update and update-all command
2025-01-19 22:23:09 +01:00
f39051f93d feat(cli): add update and update-all command 2025-01-19 22:21:28 +01:00
44 changed files with 1543 additions and 581 deletions

View file

@ -2,6 +2,61 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [0.6.0] - 2025-02-04
### 🚀 Features
- *(cli)* Add check command
### 🚜 Refactor
- *(packagemanager,cli,tui)* Move packages in specific subfolders
### 📚 Documentation
- *(cli)* Update version
## [0.5.0] - 2025-01-24
### 🚀 Features
- *(cli)* Add concurrent execution of search and update to improve performance
- *(cli)* Add aliases to commands
- *(config)* Add creation of default config if no config exists
- *(cli)* Add history command and logging for actions
- *(cli)* Add max history length
### 🐛 Bug Fixes
- *(packagemanager)* Reimplement getPackagemanager to enable installing buildtools on linux
### 🚜 Refactor
- *(cli)* Perform code clean up
## [0.4.0] - 2025-01-20
### 🚀 Features
- *(cli)* Add update and update-all command
- *(packagemanager)* Added packagemanager definitions for winget and chocolatey
- *(cli,packagemanager)* Implemented first working windows and macos versions
### 🐛 Bug Fixes
- *(packagemanager)* Added missing build tag for macos
### 📚 Documentation
- Update changelog.md
- Update changelog.md
## [0.3.1] - 2025-01-19
### 🐛 Bug Fixes
- Fix nil pointer execution if no proper packagemanager selected
## [0.3.0] - 2025-01-18 ## [0.3.0] - 2025-01-18
### 🚀 Features ### 🚀 Features
@ -19,6 +74,10 @@ All notable changes to this project will be documented in this file.
- Seperate files, function and structs into seperate packages - Seperate files, function and structs into seperate packages
- Move main.go back to project root - Move main.go back to project root
### 📚 Documentation
- Update changelog.md
## [0.2.0] - 2025-01-16 ## [0.2.0] - 2025-01-16
### 🚀 Features ### 🚀 Features

50
cmd/check_cmd.go Normal file
View file

@ -0,0 +1,50 @@
package cmd
import (
"fmt"
"log"
"codeberg.org/Pata1704/system_setup_tool/internal/utils"
pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/spf13/cobra"
)
var checkCmd = &cobra.Command{
Use: "check [package-name]",
Short: "Check if the specified package is installed",
Args: cobra.ExactArgs(1),
Aliases: []string{"c"},
Run: func(cmd *cobra.Command, args []string) {
packageName := args[0]
managerName, _ := cmd.Flags().GetString("manager")
var manager pm.PackageManager
switch managerName {
case "os":
managerName = "OS Package Manager"
case "brew":
managerName = "homebrew"
}
switch managerName {
case "OS Package Manager":
manager = pm.NewOSManager("")
case "homebrew":
manager = &pm.HomebrewManager{}
case "cargo":
manager = &pm.CargoManager{}
case "pipx":
manager = &pm.PipxManager{}
case "flatpak":
manager = &pm.FlatpakManager{}
default:
fmt.Println("No PackageManager found")
}
if err := manager.Check(packageName); err != nil {
log.Printf("error: %v\n", err)
}
fmt.Printf("Package: %s installed\n", packageName)
if err := utils.LogToHistory("checked", packageName, manager.Name()); err != nil {
fmt.Println("error logging action:", err)
}
},
}

View file

@ -2,8 +2,12 @@ package cmd
import ( import (
"fmt" "fmt"
"log"
"log/slog"
"os" "os"
"system_setup_tool/tui" "path/filepath"
"codeberg.org/Pata1704/system_setup_tool/internal/tui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -12,13 +16,17 @@ import (
var RootCmd = &cobra.Command{ var RootCmd = &cobra.Command{
Use: "system_setup_tool", Use: "system_setup_tool",
Short: "Installs packages based on TOML configuration", Short: "Installs packages based on TOML configuration",
Version: "0.6.0",
Run: tui.Run, Run: tui.Run,
} }
func init() { func init() {
cobra.OnInitialize(initConfig) cobra.OnInitialize(initConfig)
RootCmd.PersistentFlags().StringP("config", "c", "", "Path to the configuration file") RootCmd.PersistentFlags().StringP("config", "c", "", "Path to the configuration file")
viper.BindPFlag("config", RootCmd.PersistentFlags().Lookup("config")) err := viper.BindPFlag("config", RootCmd.PersistentFlags().Lookup("config"))
if err != nil {
slog.Error("could not bind config flag")
}
addCmd.Flags().StringP("name", "n", "", "The name of the package you want to add") addCmd.Flags().StringP("name", "n", "", "The name of the package you want to add")
addCmd.Flags().StringP("manager", "m", "", "The package manager you want to add the package to (homebrew|cargo|flatpak|pipx|go)") addCmd.Flags().StringP("manager", "m", "", "The package manager you want to add the package to (homebrew|cargo|flatpak|pipx|go)")
@ -38,8 +46,26 @@ func init() {
searchCmd.Flags().StringP("manager", "m", "", "The package manager you want to search a package with. (Options: os|homebrew|flatpak)") 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) updateCmd.Flags().StringP("manager", "m", "os", "The package manager you want to update packages with. (Options: os|homebrew|pipx|flatpak)")
RootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd)
checkCmd.Flags().StringP("manager", "m", "os", "The package manager you want to check for a packages with. (Options: os|homebrew|pipx|flatpak)")
packageCmd.AddCommand(
addCmd,
deleteCmd,
showCmd,
enableCmd,
)
RootCmd.AddCommand(
packageCmd,
searchCmd,
installCmd,
removeCmd,
updateCmd,
updateAllCmd,
historyCmd,
checkCmd,
)
} }
func initConfig() { func initConfig() {
@ -48,11 +74,68 @@ func initConfig() {
} else { } else {
viper.SetConfigName("config") viper.SetConfigName("config")
viper.SetConfigType("toml") viper.SetConfigType("toml")
viper.AddConfigPath(".") dirname, err := os.UserConfigDir()
if err != nil {
log.Println("cant obtain config dir")
} else {
viper.AddConfigPath(filepath.Join(dirname, "sst"))
}
} }
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
fmt.Println("Error reading configuration file:", err) if _, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Println("no config file found, creating a new one...")
if err = createDefaultConfig(); err != nil {
slog.Error(fmt.Sprintf("error creating default config: %v\n", err))
os.Exit(1) os.Exit(1)
} }
} else {
log.Printf("error reading config file: %v\n", err)
os.Exit(1)
}
}
}
func createDefaultConfig() error {
v := viper.New()
v.SetDefault("config", "")
v.SetDefault("headless", true)
v.SetDefault("dotfiles.enable", false)
v.SetDefault("dotfiles.git_repo", "")
v.SetDefault("package_managers.cargo.enable", false)
v.SetDefault("package_managers.cargo.packages", []string{})
v.SetDefault("package_managers.flatpak.enable", false)
v.SetDefault("package_managers.flatpak.packages", []string{})
v.SetDefault("package_managers.go.enable", false)
v.SetDefault("package_managers.go.packages", []string{})
v.SetDefault("package_managers.homebrew.enable", false)
v.SetDefault("package_managers.homebrew.packages", []string{})
v.SetDefault("package_managers.pipx.enable", false)
v.SetDefault("package_managers.pipx.packages", []string{})
v.SetDefault("package_managers.os.enable", true)
v.SetDefault("package_managers.os.packages", []string{})
configDir := filepath.Join(os.Getenv("HOME"), ".config", "sst")
if err := os.MkdirAll(configDir, 0o755); err != nil {
return fmt.Errorf("error creating config dir: %w", err)
}
configPath := filepath.Join(configDir, "config.toml")
v.SetConfigFile(configPath)
v.SetConfigType("toml")
if err := v.WriteConfig(); err != nil {
return fmt.Errorf("error writing default config: %w", err)
}
fmt.Println("default config created:", configPath)
return nil
} }

29
cmd/history_cmd.go Normal file
View file

@ -0,0 +1,29 @@
package cmd
import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/spf13/cobra"
)
var historyCmd = &cobra.Command{
Use: "history",
Short: "show command history",
Long: "Shows history of the last 2000 commands",
Run: func(cmd *cobra.Command, args []string) {
dirname, err := os.UserConfigDir()
if err != nil {
log.Printf("error getting user config dir: %v\n", err)
}
historyFile := filepath.Join(dirname, "sst", "sst_history")
content, err := os.ReadFile(historyFile)
if err != nil {
fmt.Println("error reading history: ", err)
return
}
fmt.Println(string(content))
},
}

View file

@ -3,9 +3,11 @@ package cmd
import ( import (
"fmt" "fmt"
"log" "log"
"system_setup_tool/utils" "runtime"
pm "system_setup_tool/packagemanager" "codeberg.org/Pata1704/system_setup_tool/internal/utils"
pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -14,21 +16,29 @@ var installCmd = &cobra.Command{
Use: "install [package_name]", Use: "install [package_name]",
Short: "Install a package with the specified package manager", Short: "Install a package with the specified package manager",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Aliases: []string{"i"},
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
packageName := args[0] packageName := args[0]
managerName, _ := cmd.Flags().GetString("manager") managerName, _ := cmd.Flags().GetString("manager")
var manager pm.PackageManager var manager pm.PackageManager
switch managerName { switch managerName {
case "os": case "os":
managerName = "OS Package Manager"
case "brew":
managerName = "homebrew"
}
switch managerName {
case "OS Package Manager":
if runtime.GOOS != "windows" {
sudoPassword, err := utils.GetSudoPassword() sudoPassword, err := utils.GetSudoPassword()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
osManager := pm.NewOSManager(sudoPassword) manager = pm.NewOSManager(sudoPassword)
if err := osManager.Install([]string{packageName}); err != nil { } else {
log.Printf("error: %v\n", err) manager = pm.NewOSManager("")
} }
case "homebrew", "brew": case "homebrew":
manager = &pm.HomebrewManager{} manager = &pm.HomebrewManager{}
case "cargo": case "cargo":
manager = &pm.CargoManager{} manager = &pm.CargoManager{}
@ -40,8 +50,11 @@ var installCmd = &cobra.Command{
fmt.Println("No PackageManager found") fmt.Println("No PackageManager found")
return return
} }
if err := manager.InstallPackage(packageName); err != nil { if err := manager.Install([]string{packageName}); err != nil {
log.Printf("error: %v\n", err) log.Printf("error: %v\n", err)
} }
if err := utils.LogToHistory("installed", packageName, manager.Name()); err != nil {
fmt.Println("error logging action:", err)
}
}, },
} }

View file

@ -1,8 +1,10 @@
package cmd package cmd
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/utils"
"fmt" "fmt"
"os" "os"
"slices"
"sort" "sort"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -41,12 +43,10 @@ var addCmd = &cobra.Command{
} else { } else {
packages := viper.GetStringSlice(fmt.Sprintf("package_managers.%s.packages", manager)) packages := viper.GetStringSlice(fmt.Sprintf("package_managers.%s.packages", manager))
for _, pkg := range packages { if slices.Contains(packages, name) {
if pkg == name {
fmt.Printf("Package %s is already present in the configuration for %s\n", name, manager) fmt.Printf("Package %s is already present in the configuration for %s\n", name, manager)
return return
} }
}
packages = append(packages, name) packages = append(packages, name)
viper.Set(fmt.Sprintf("package_managers.%s.packages", manager), packages) viper.Set(fmt.Sprintf("package_managers.%s.packages", manager), packages)
@ -58,6 +58,9 @@ var addCmd = &cobra.Command{
} }
fmt.Printf("Package %s has been added to the configuration for %s\n", name, manager) fmt.Printf("Package %s has been added to the configuration for %s\n", name, manager)
if err := utils.LogToHistory("added", name, manager); err != nil {
fmt.Println("error logging action:", err)
}
}, },
} }
@ -120,6 +123,9 @@ var deleteCmd = &cobra.Command{
} }
fmt.Printf("Package %s was not found in the configuration for %s\n", name, manager) fmt.Printf("Package %s was not found in the configuration for %s\n", name, manager)
if err := utils.LogToHistory("removed", name, manager); err != nil {
fmt.Println("error logging action:", err)
}
} }
}, },
} }
@ -187,5 +193,8 @@ var enableCmd = &cobra.Command{
} }
fmt.Printf("Package manager %s has been %s\n", manager, map[bool]string{true: "enabled", false: "disabled"}[enable]) fmt.Printf("Package manager %s has been %s\n", manager, map[bool]string{true: "enabled", false: "disabled"}[enable])
if err := utils.LogToHistory("enabled", "", manager); err != nil {
fmt.Println("error logging action:", err)
}
}, },
} }

View file

@ -3,9 +3,11 @@ package cmd
import ( import (
"fmt" "fmt"
"log" "log"
"system_setup_tool/utils" "runtime"
pm "system_setup_tool/packagemanager" "codeberg.org/Pata1704/system_setup_tool/internal/utils"
pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,15 +22,22 @@ var removeCmd = &cobra.Command{
var manager pm.PackageManager var manager pm.PackageManager
switch managerName { switch managerName {
case "os": case "os":
managerName = "OS Package Manager"
case "brew":
managerName = "homebrew"
}
switch managerName {
case "OS Package Manager":
if runtime.GOOS != "windows" {
sudoPassword, err := utils.GetSudoPassword() sudoPassword, err := utils.GetSudoPassword()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
osManager := pm.NewOSManager(sudoPassword) manager = pm.NewOSManager(sudoPassword)
if err := osManager.Install([]string{packageName}); err != nil { } else {
log.Printf("error: %v\n", err) manager = pm.NewOSManager("")
} }
case "homebrew", "brew": case "homebrew":
manager = &pm.HomebrewManager{} manager = &pm.HomebrewManager{}
case "cargo": case "cargo":
manager = &pm.CargoManager{} manager = &pm.CargoManager{}
@ -43,5 +52,8 @@ var removeCmd = &cobra.Command{
if err := manager.RemovePackage(packageName); err != nil { if err := manager.RemovePackage(packageName); err != nil {
log.Printf("error: %v\n", err) log.Printf("error: %v\n", err)
} }
if err := utils.LogToHistory("removed", packageName, manager.Name()); err != nil {
fmt.Println("error logging action:", err)
}
}, },
} }

View file

@ -2,9 +2,13 @@ package cmd
import ( import (
"fmt" "fmt"
"log"
"runtime"
"strings" "strings"
"sync"
pm "system_setup_tool/packagemanager" "codeberg.org/Pata1704/system_setup_tool/internal/utils"
pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -13,23 +17,40 @@ var searchCmd = &cobra.Command{
Use: "search [package_name]", Use: "search [package_name]",
Short: "Search for a package across package managers (will search in os|flatpak|homebrew)", Short: "Search for a package across package managers (will search in os|flatpak|homebrew)",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Aliases: []string{"s"},
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
packageName := args[0] packageName := args[0]
managerName, _ := cmd.Flags().GetString("manager") managerName, _ := cmd.Flags().GetString("manager")
if managerName == "os" { switch managerName {
case "os":
managerName = "OS Package Manager" managerName = "OS Package Manager"
case "brew":
managerName = "homebrew"
} }
managers := []pm.PackageManager{ var managers []pm.PackageManager
switch runtime.GOOS {
case "linux":
managers = []pm.PackageManager{
pm.NewOSManager(""), pm.NewOSManager(""),
&pm.HomebrewManager{}, &pm.HomebrewManager{},
&pm.FlatpakManager{}, &pm.FlatpakManager{},
} }
case "windows":
managers = []pm.PackageManager{
pm.NewOSManager(""),
&pm.WingetManager{},
&pm.ChocoManager{},
}
case "darwin":
managers = []pm.PackageManager{
pm.NewOSManager(""),
}
default:
log.Println("No Package Managers found")
}
if managerName != "" { if managerName != "" {
if managerName == "brew" {
managerName = "homebrew"
}
for _, m := range managers { for _, m := range managers {
if strings.EqualFold(m.Name(), managerName) { if strings.EqualFold(m.Name(), managerName) {
searchAndDisplayResults(m, packageName) searchAndDisplayResults(m, packageName)
@ -40,9 +61,7 @@ var searchCmd = &cobra.Command{
return return
} }
for _, manager := range managers { searchConcurrently(managers, packageName)
searchAndDisplayResults(manager, packageName)
}
}, },
} }
@ -62,3 +81,37 @@ func searchAndDisplayResults(manager pm.PackageManager, packageName string) {
displayResults(results, manager.Name()) displayResults(results, manager.Name())
fmt.Println() fmt.Println()
} }
func searchConcurrently(managers []pm.PackageManager, packageName string) {
var wg sync.WaitGroup
results := make(chan struct {
manager pm.PackageManager
results []string
}, len(managers))
for _, manager := range managers {
wg.Add(1)
go func(m pm.PackageManager) {
defer wg.Done()
searchResults := m.SearchPackage(packageName)
results <- struct {
manager pm.PackageManager
results []string
}{m, searchResults}
}(manager)
}
go func() {
wg.Wait()
close(results)
}()
for result := range results {
fmt.Printf("Results from %s:\n", result.manager.Name())
displayResults(result.results, result.manager.Name())
fmt.Println()
if err := utils.LogToHistory("searched", packageName, result.manager.Name()); err != nil {
fmt.Println("error logging action:", err)
}
}
}

129
cmd/update_command.go Normal file
View file

@ -0,0 +1,129 @@
package cmd
import (
"fmt"
"log"
"runtime"
"sync"
"codeberg.org/Pata1704/system_setup_tool/internal/utils"
pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/spf13/cobra"
)
var updateCmd = &cobra.Command{
Use: "update [package_name]",
Short: "update a package with the specified package manager.",
Long: "update a package with the specified package manager.\nIf no package specified, all packages for the package manager will be updated",
Args: cobra.ExactArgs(1),
Aliases: []string{"u"},
Run: func(cmd *cobra.Command, args []string) {
packageName := args[0]
managerName, _ := cmd.Flags().GetString("manager")
var manager pm.PackageManager
switch managerName {
case "os":
managerName = "OS Package Manager"
case "brew":
managerName = "homebrew"
}
switch managerName {
case "OS Package Manager":
if runtime.GOOS != "windows" {
sudoPassword, err := utils.GetSudoPassword()
if err != nil {
log.Fatal(err)
}
manager = pm.NewOSManager(sudoPassword)
} else {
manager = pm.NewOSManager("")
}
case "homebrew":
manager = &pm.HomebrewManager{}
case "cargo":
manager = &pm.CargoManager{}
case "pipx":
manager = &pm.PipxManager{}
case "flatpak":
manager = &pm.FlatpakManager{}
default:
fmt.Println("No PackageManager found")
return
}
if packageName != "" {
if err := manager.UpdatePackage(packageName); err != nil {
log.Printf("error: %v\n", err)
} else {
if err := utils.LogToHistory("updated", packageName, manager.Name()); err != nil {
fmt.Println("error logging action:", err)
}
}
} else {
if err := manager.UpdateAllPackages(); err != nil {
log.Printf("error: %v\n", err)
} else {
if err := utils.LogToHistory("updated", "all", "all"); err != nil {
fmt.Println("error logging action:", err)
}
}
}
},
}
var updateAllCmd = &cobra.Command{
Use: "update-all",
Short: "update all packages with all package managers.",
Run: func(cmd *cobra.Command, args []string) {
var managers []pm.PackageManager
switch runtime.GOOS {
case "linux":
sudoPassword, err := utils.GetSudoPassword()
if err != nil {
log.Fatal(err)
}
managers = []pm.PackageManager{
pm.NewOSManager(sudoPassword),
&pm.HomebrewManager{},
&pm.FlatpakManager{},
&pm.PipxManager{},
}
case "windows":
managers = []pm.PackageManager{
pm.NewOSManager(""),
&pm.WingetManager{},
&pm.ChocoManager{},
&pm.PipxManager{},
}
case "darwin":
sudoPassword, err := utils.GetSudoPassword()
if err != nil {
log.Fatal(err)
}
managers = []pm.PackageManager{
pm.NewOSManager(sudoPassword),
&pm.PipxManager{},
}
default:
log.Println("No Package Managers found")
}
updateAllConcurrently(managers)
},
}
func updateAllConcurrently(managers []pm.PackageManager) {
var wg sync.WaitGroup
for _, m := range managers {
wg.Add(1)
go func(manager pm.PackageManager) {
defer wg.Done()
fmt.Printf("Updating %s-Packages\n", manager.Name())
err := manager.UpdateAllPackages()
if err != nil {
log.Printf("Error updating %s: %v\n", manager.Name(), err)
}
}(m)
}
wg.Wait()
}

View file

@ -1,118 +0,0 @@
config = ''
headless = true
[dotfiles]
enable = false
git_repo = 'https://codeberg.org/Pata1704/dotfiles.git'
[package_managers]
[package_managers.cargo]
enable = true
packages = ['typst-cli']
[package_managers.flatpak]
enable = true
packages = [
'com.spotify.Client',
'us.zoom.Zoom',
'org.zotero.Zotero',
'com.google.AndroidStudio',
'io.freetubeapp.FreeTube',
'com.discordapp.Discord',
'com.nextcloud.desktopclient.nextcloud',
'com.github.tchx84.Flatseal',
'io.github.flattool.Warehouse',
'org.onlyoffice.desktopeditors',
]
[package_managers.go]
enable = true
packages = [
'github.com/stefanlogue/meteor',
'golang.org/x/tools/gopls',
'github.com/go-delve/delve/cmd/dlv',
'github.com/air-verse/air',
]
[package_managers.homebrew]
enable = true
packages = [
'oh-my-posh',
'fd',
'fzf',
'ripgrep',
'neovim',
'helix',
'node',
'yazi',
'zk',
'bat',
'bottom',
'btop',
'git-cliff',
'glow',
'lazygit',
'goreleaser',
'harlequin',
'mage',
'posting',
'typst',
'wails',
'zoxide',
'lsd',
'jq',
'yq',
'timewarrior',
'tmux',
'fastfetch',
'stow',
'distrobox',
]
[package_managers.pipx]
enable = true
packages = ['euporie']
[package_managers.os]
enable = true
packages = [
'git',
'curl',
'wget',
'biber',
'bear',
'docker',
'docker-compose',
'zsh',
'npm',
'task',
'tree-sitter-cli',
'python3-pip',
'latexmk',
'luarocks',
'flameshot',
'fuzzel',
'hyprcursor',
'hypridle',
'hyprland',
'hyprland-qtutils',
'hyprlock',
'hyprpaper',
'hyprutils',
'kitty',
'mako',
'SwayNotificationCenter',
'SwayNotificationCenter-zsh-completion',
'mpv',
'pidgin',
'remmina',
'thunderbird-i18n-de',
'virt-manager',
'vlc',
'waybar',
'nwg-panel',
'nwg-look',
'xdg-desktop-portal-hyprland',
'zathura',
'zathura-pdf-mupdf',
]

72
go.mod
View file

@ -1,59 +1,61 @@
module system_setup_tool module codeberg.org/Pata1704/system_setup_tool
go 1.23.4 go 1.25.5
require ( require (
github.com/charmbracelet/huh v0.6.0 github.com/charmbracelet/huh v0.8.0
github.com/magefile/mage v1.15.0 github.com/magefile/mage v1.15.0
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/schollz/progressbar/v3 v3.18.0 github.com/schollz/progressbar/v3 v3.19.0
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.19.0 github.com/spf13/viper v1.21.0
golang.org/x/sys v0.40.0
) )
require ( require (
github.com/atotto/clipboard v0.1.4 // indirect github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/catppuccin/go v0.2.0 // indirect github.com/catppuccin/go v0.3.0 // indirect
github.com/charmbracelet/bubbles v0.20.0 // indirect github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect
github.com/charmbracelet/bubbletea v1.2.4 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect
github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/colorprofile v0.4.1 // indirect
github.com/charmbracelet/x/ansi v0.4.5 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect github.com/charmbracelet/x/ansi v0.11.3 // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
github.com/charmbracelet/x/exp/strings v0.0.0-20260109001716-2fbdffcb221f // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/clipperhouse/displaywidth v0.6.2 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect github.com/muesli/termenv v0.16.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/sync v0.9.0 // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/sys v0.29.0 // indirect golang.org/x/sync v0.19.0 // indirect
golang.org/x/term v0.28.0 // indirect golang.org/x/term v0.39.0 // indirect
golang.org/x/text v0.18.0 // indirect golang.org/x/text v0.33.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

197
go.sum
View file

@ -4,41 +4,81 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE= github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
github.com/charmbracelet/bubbletea v1.2.4/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM= github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8= github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 h1:JFgG/xnwFfbezlUnFMJy0nusZvytYysV4SCS2cYbvws=
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU= github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7/go.mod h1:ISC1gtLcVilLOf23wvTfoQuYbW2q0JevFxPfUzZ9Ybw=
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
github.com/charmbracelet/huh v0.7.0 h1:W8S1uyGETgj9Tuda3/JdVkc3x7DBLZYPZc4c+/rnRdc=
github.com/charmbracelet/huh v0.7.0/go.mod h1:UGC3DZHlgOKHvHC07a5vHag41zzhpPFj34U92sOmyuk=
github.com/charmbracelet/huh v0.8.0 h1:Xz/Pm2h64cXQZn/Jvele4J3r7DDiqFCNIVteYukxDvY=
github.com/charmbracelet/huh v0.8.0/go.mod h1:5YVc+SlZ1IhQALxRPpkGwwEKftN/+OlJlnJYlDRFqN4=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0=
github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI=
github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI=
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U=
github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ=
github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA=
github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/exp/strings v0.0.0-20250623112707-45752038d08d h1:fEsdno3tFo//l8pS4hlzH5hj6zGSaMzQcbyDLfToeJg=
github.com/charmbracelet/x/exp/strings v0.0.0-20250623112707-45752038d08d/go.mod h1:Rgw3/F+xlcUc5XygUtimVSxAqCOsqyvJjqF5UHRvc5k=
github.com/charmbracelet/x/exp/strings v0.0.0-20260109001716-2fbdffcb221f h1:c0cKImYFPrOEEzMsYss56Q7Q69HD7H4ss3Yu9Mw9vqQ=
github.com/charmbracelet/x/exp/strings v0.0.0-20260109001716-2fbdffcb221f/go.mod h1:/ehtMPNh9K4odGFkqYJKpIYyePhdp1hLBRvyY4bWkH8=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY=
github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo=
github.com/charmbracelet/x/xpty v0.1.2 h1:Pqmu4TEJ8KeA9uSkISKMU3f+C1F6OGBn8ABuGlqCbtI=
github.com/charmbracelet/x/xpty v0.1.2/go.mod h1:XK2Z0id5rtLWcpeNiMYBccNNBrP2IJnzHI0Lq13Xzq4=
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@ -50,16 +90,18 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
@ -70,71 +112,82 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA= github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec= github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/schollz/progressbar/v3 v3.19.0 h1:Ea18xuIRQXLAUidVDox3AbwfUhD0/1IvohyTutOIFoc=
github.com/schollz/progressbar/v3 v3.19.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,8 +1,8 @@
package config package config
import ( import (
"system_setup_tool/dotfiles" "codeberg.org/Pata1704/system_setup_tool/internal/dotfiles"
pm "system_setup_tool/packagemanager" pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
) )
type PackageManagerConfig struct { type PackageManagerConfig struct {

View file

@ -1,11 +1,11 @@
package dotfiles package dotfiles
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt" "fmt"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"system_setup_tool/internal/shell"
) )
type DotfilesConfig struct { type DotfilesConfig struct {

View file

@ -1,13 +1,13 @@
package tui package tui
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/config"
"codeberg.org/Pata1704/system_setup_tool/internal/dotfiles"
"codeberg.org/Pata1704/system_setup_tool/internal/utils"
"fmt" "fmt"
"log" "log"
"system_setup_tool/config"
"system_setup_tool/dotfiles"
"system_setup_tool/utils"
pm "system_setup_tool/packagemanager" pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager"
"github.com/charmbracelet/huh" "github.com/charmbracelet/huh"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"

80
internal/utils/utils.go Normal file
View file

@ -0,0 +1,80 @@
package utils
import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/charmbracelet/huh"
)
func GetSudoPassword() (string, error) {
var password string
form := huh.NewForm(
huh.NewGroup(
huh.NewInput().
Title("Enter your password").
EchoMode(huh.EchoModePassword).
Value(&password),
),
).WithTheme(huh.ThemeCatppuccin())
err := form.Run()
if err != nil {
return "", fmt.Errorf("error at password-dialog: %v", err)
}
return password, nil
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
const (
maxHistoryLines = 2000
historyFileName = "sst_history"
)
func LogToHistory(action, pkg, manager string) error {
dirname, err := os.UserConfigDir()
if err != nil {
return fmt.Errorf("cant obtain config dir: %v", err)
}
historyFile := filepath.Join(dirname, "sst", historyFileName)
lines, err := readHistoryLines(historyFile)
if err != nil {
return err
}
timestamp := time.Now().Format("2006-01-02 15:04:05")
logEntry := fmt.Sprintf("%s: action: [%s] - package: [%s] - packagemanager: [%s]", timestamp, action, pkg, manager)
lines = append(lines, logEntry)
if len(lines) > maxHistoryLines {
lines = lines[len(lines)-maxHistoryLines:]
}
return writeHistoryLines(historyFile, lines)
}
func readHistoryLines(filePath string) ([]string, error) {
content, err := os.ReadFile(filePath)
if err != nil {
if os.IsNotExist(err) {
return []string{}, nil
}
return nil, err
}
return strings.Split(string(content), "\n"), nil
}
func writeHistoryLines(filePath string, lines []string) error {
content := strings.Join(lines, "\n")
return os.WriteFile(filePath, []byte(content), 0644)
}

View file

@ -1,8 +1,8 @@
package utils package utils
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

View file

@ -16,9 +16,8 @@ import (
// A build step that requires additional params, or platform specific steps for example // A build step that requires additional params, or platform specific steps for example
func Build() error { func Build() error {
mg.Deps(InstallDeps)
fmt.Println("Building...") fmt.Println("Building...")
cmd := exec.Command("go", "build", "-o", "system_setup_tool", ".") cmd := exec.Command("go", "build", "-o", "sst", ".")
return cmd.Run() return cmd.Run()
} }
@ -26,20 +25,13 @@ func Build() error {
func Install() error { func Install() error {
mg.Deps(Build) mg.Deps(Build)
fmt.Println("Installing...") fmt.Println("Installing...")
return os.Rename("./system_setup_tool", "/usr/bin/system_setup_tool") return os.Rename("./sst", "~/.local/bin/sst")
}
// Manage your deps, or running package managers.
func InstallDeps() error {
fmt.Println("Installing Deps...")
cmd := exec.Command("go", "get", "github.com/stretchr/piglatin")
return cmd.Run()
} }
// Clean up after yourself // Clean up after yourself
func Clean() { func Clean() {
fmt.Println("Cleaning...") fmt.Println("Cleaning...")
os.RemoveAll("MyApp") os.RemoveAll("system_setup_tool")
} }
// Use gofmt to format your code // Use gofmt to format your code

View file

@ -3,7 +3,8 @@ package main
import ( import (
"log" "log"
"os" "os"
"system_setup_tool/cmd"
"codeberg.org/Pata1704/system_setup_tool/cmd"
) )
func main() { func main() {

View file

@ -1,230 +0,0 @@
package packagemanager
import (
"fmt"
"log"
"os"
"strings"
"system_setup_tool/internal/shell"
)
type OSManager struct {
OS *OS
SudoPassword string
}
func NewOSManager(sudoPassword string) *OSManager {
os, err := GetLinuxDistribution()
if err != nil {
log.Fatalf("error geting os information: %v", err)
}
return &OSManager{
OS: os,
SudoPassword: sudoPassword,
}
}
func (o *OSManager) Name() string {
return "OS Package Manager"
}
func (o *OSManager) InstallManager() error { return nil }
func (o *OSManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(o, packages)
if err != nil {
return err
}
return nil
}
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)
}
func (o *OSManager) RemovePackage(pkg string) error {
fullCmd := fmt.Sprintf("%s %s", o.OS.RemoveCommand, pkg)
command := shell.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 := shell.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
RemoveCommand string
}
func parseOsRelease(osRelease string) *OS {
var result OS
result.ID = "Unknown"
result.Name = "Unknown"
result.Version = "Unknown"
result.PackageManager = "Unkown"
result.InstallCommand = "Unkown"
lines := strings.Split(osRelease, "\n")
for _, line := range lines {
splitLine := strings.SplitN(line, "=", 2)
if len(splitLine) != 2 {
continue
}
switch splitLine[0] {
case "ID":
result.ID = strings.ToLower(strings.Trim(splitLine[1], "\""))
case "NAME":
result.Name = strings.Trim(splitLine[1], "\"")
case "VERSION_ID":
result.Version = strings.Trim(splitLine[1], "\"")
}
}
err := result.getPackageManager()
if err != nil {
log.Fatal(err)
}
err = result.getInstallCommand()
if err != nil {
log.Fatal(err)
}
err = result.getSearchCommand()
if err != nil {
log.Fatal(err)
}
return &result
}
func GetLinuxDistribution() (*OS, error) {
_, err := os.Stat("/etc/os-release")
if os.IsNotExist(err) {
return nil, fmt.Errorf("unable to read system information")
}
osRelease, _ := os.ReadFile("/etc/os-release")
return parseOsRelease(string(osRelease)), nil
}
func (os *OS) getPackageManager() error {
switch os.ID {
case "debian", "ubuntu":
os.PackageManager = "apt"
return nil
case "arch":
os.PackageManager = "pacman"
return nil
case "fedora":
os.PackageManager = "dnf"
return nil
default:
pmcommands := []string{
"apt",
"dnf",
"pacman",
}
for _, pmname := range pmcommands {
_, err := shell.ExecLookPath(pmname)
if err == nil {
os.PackageManager = pmname
return nil
}
}
return fmt.Errorf("no packagemanager found for os: %s", os)
}
}
func (os *OS) getInstallCommand() error {
switch os.PackageManager {
case "apt":
os.InstallCommand = "apt install -y"
return nil
case "pacman":
os.InstallCommand = "pacman -S --noconfirm --needed"
return nil
case "dnf":
os.InstallCommand = "dnf install -y --best"
return nil
default:
return fmt.Errorf("no install command found for package manager: %s", os.ID)
}
}
func (os *OS) getSearchCommand() error {
switch os.PackageManager {
case "apt":
os.SearchCommand = "apt search"
return nil
case "pacman":
os.SearchCommand = "pacman -Ss"
return nil
case "dnf":
os.SearchCommand = "dnf search"
return nil
default:
return fmt.Errorf("no install command found for package manager: %s", os.ID)
}
}
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 {
case "pacman":
command = "pacman -S --noconfirm --needed base-devel"
case "apt":
command = "apt install -y build-essential"
case "dnf":
command = "dnf install -y @development-tools"
default:
return fmt.Errorf("keine Build Essentials für OS %s definiert", os.ID)
}
fmt.Printf("Installiere Build Essentials für %s...\n", os.Name)
if err := InstallPackage(command, "", sudoPassword); err != nil {
return fmt.Errorf("error installing Build Essentials: %v", err)
}
return nil
}

81
pkg/packagemanager/apt.go Normal file
View file

@ -0,0 +1,81 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"log"
"strings"
)
type AptManager struct {
SudoPassword string
}
func (a *AptManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(a, packages)
if err != nil {
return err
}
return nil
}
func (a *AptManager) Name() string {
return "OS Home Manager"
}
func (a *AptManager) InstallManager() error {
return nil
}
func (a *AptManager) InstallPackage(pkg string) error {
cmd := "apt install -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(a.SudoPassword + "\n")
return command.Run()
}
func (a *AptManager) RemovePackage(pkg string) error {
cmd := "apt remove -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(a.SudoPassword + "\n")
return command.Run()
}
func (a *AptManager) SearchPackage(pkg string) []string {
cmd := "apt search -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(a.SudoPassword + "\n")
packages, err := command.Output()
if err != nil {
log.Printf("error fetching %s packages: %v", a.Name(), err)
}
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList
}
func (a *AptManager) UpdatePackage(pkg string) error {
cmd := "apt update -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(a.SudoPassword + "\n")
return command.Run()
}
func (a *AptManager) UpdateAllPackages() error {
cmd := "apt update -y"
fullCmd := fmt.Sprintf("%s", cmd)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(a.SudoPassword + "\n")
return command.Run()
}
func (a *AptManager) Check(pkg string) error {
cmd := shell.ExecCommand("/bin/sh", "-c", fmt.Sprintf("dpkg -l | grep %s", pkg))
return cmd.Run()
}

View file

@ -1,6 +1,11 @@
package packagemanager package packagemanager
import "system_setup_tool/internal/shell" import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"os"
"path/filepath"
)
type CargoManager struct{} type CargoManager struct{}
@ -45,3 +50,20 @@ func (c *CargoManager) RemovePackage(pkg string) error {
func (c *CargoManager) SearchPackage(pkg string) []string { func (c *CargoManager) SearchPackage(pkg string) []string {
return []string{} return []string{}
} }
func (c *CargoManager) UpdatePackage(pkg string) error {
return fmt.Errorf("update not supported")
}
func (c *CargoManager) UpdateAllPackages() error {
return fmt.Errorf("update not supported")
}
func (c *CargoManager) Check(pkg string) error {
home, err := os.UserHomeDir()
if err != nil {
return err
}
cmd := shell.ExecCommand("ls", filepath.Join(home, ".cargo", "bin", pkg))
return cmd.Run()
}

View file

@ -2,8 +2,8 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

View file

@ -0,0 +1,71 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"log"
"strings"
)
type ChocoManager struct{}
func (c *ChocoManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(c, packages)
if err != nil {
return err
}
return nil
}
func (c *ChocoManager) Name() string {
return "Chocolatey"
}
func (c *ChocoManager) InstallManager() error {
if _, err := shell.ExecLookPath("choco"); err == nil {
return nil
}
return installHomebrew()
}
func installChoco() error {
return nil
}
func (c *ChocoManager) InstallPackage(pkg string) error {
cmd := shell.ExecCommand("choco", "install", pkg)
return cmd.Run()
}
func (c *ChocoManager) RemovePackage(pkg string) error {
cmd := shell.ExecCommand("choco", "uninstall", pkg)
return cmd.Run()
}
func (c *ChocoManager) SearchPackage(pkg string) []string {
cmd := shell.ExecCommand("choco", "search", pkg)
packages, err := cmd.Output()
if err != nil {
log.Printf("error fetching %s packages: %v", c.Name(), err)
}
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList
}
func (c *ChocoManager) UpdatePackage(pkg string) error {
cmd := shell.ExecCommand("choco", "update", pkg)
return cmd.Run()
}
func (c *ChocoManager) UpdateAllPackages() error {
cmd := shell.ExecCommand("choco", "update")
return cmd.Run()
}
func (c *ChocoManager) Check(pkg string) error {
cmd := shell.ExecCommand("choco", "search", "--local-only", pkg)
return cmd.Run()
}

78
pkg/packagemanager/dnf.go Normal file
View file

@ -0,0 +1,78 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"log"
"strings"
)
type DnfManager struct {
SudoPassword string
}
func (d *DnfManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(d, packages)
if err != nil {
return err
}
return nil
}
func (d *DnfManager) Name() string {
return "OS Home Manager"
}
func (d *DnfManager) InstallManager() error {
return nil
}
func (d *DnfManager) InstallPackage(pkg string) error {
cmd := "dnf install -y --best"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(d.SudoPassword + "\n")
return command.Run()
}
func (d *DnfManager) RemovePackage(pkg string) error {
cmd := "dnf remove -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(d.SudoPassword + "\n")
return command.Run()
}
func (d *DnfManager) SearchPackage(pkg string) []string {
cmd := shell.ExecCommand("dnf", "search", pkg)
packages, err := cmd.Output()
if err != nil {
log.Printf("error fetching %s packages: %v", d.Name(), err)
}
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList
}
func (d *DnfManager) UpdatePackage(pkg string) error {
cmd := "dnf update -y"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(d.SudoPassword + "\n")
return command.Run()
}
func (d *DnfManager) UpdateAllPackages() error {
cmd := "dnf update -y"
fullCmd := fmt.Sprintf("%s", cmd)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(d.SudoPassword + "\n")
return command.Run()
}
func (d *DnfManager) Check(pkg string) error {
cmd := shell.ExecCommand("/bin/sh", "-c", fmt.Sprintf("dnf list installed | grep %s", pkg))
return cmd.Run()
}

View file

@ -1,10 +1,10 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt" "fmt"
"log" "log"
"strings" "strings"
"system_setup_tool/internal/shell"
) )
type FlatpakManager struct { type FlatpakManager struct {
@ -116,3 +116,18 @@ func (f *FlatpakManager) SearchPackage(pkg string) []string {
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList return packageList
} }
func (f *FlatpakManager) UpdatePackage(pkg string) error {
cmd := shell.ExecCommand("flatpak", "update", "-y", pkg)
return cmd.Run()
}
func (f *FlatpakManager) UpdateAllPackages() error {
cmd := shell.ExecCommand("flatpak", "update", "-y")
return cmd.Run()
}
func (f *FlatpakManager) Check(pkg string) error {
cmd := shell.ExecCommand("/bin/sh", "-c", fmt.Sprintf("flatpak list | grep %s", pkg))
return cmd.Run()
}

View file

@ -1,8 +1,8 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

View file

@ -1,6 +1,11 @@
package packagemanager package packagemanager
import "system_setup_tool/internal/shell" import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"os"
"path/filepath"
)
type GolangManager struct{} type GolangManager struct{}
@ -45,3 +50,20 @@ func (g *GolangManager) RemovePackage(pkg string) error {
func (g *GolangManager) SearchPackage(pkg string) []string { func (g *GolangManager) SearchPackage(pkg string) []string {
return []string{} return []string{}
} }
func (g *GolangManager) UpdatePackage(pkg string) error {
return fmt.Errorf("update not supported")
}
func (g *GolangManager) UpdateAllPackages() error {
return fmt.Errorf("update not supported")
}
func (g *GolangManager) Check(pkg string) error {
home, err := os.UserHomeDir()
if err != nil {
fmt.Printf("error: %v\n", err)
}
cmd := shell.ExecCommand("ls", filepath.Join(home, "go", "bin", pkg))
return cmd.Run()
}

View file

@ -1,8 +1,8 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

View file

@ -1,10 +1,10 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt" "fmt"
"log" "log"
"strings" "strings"
"system_setup_tool/internal/shell"
) )
type HomebrewManager struct{} type HomebrewManager struct{}
@ -59,3 +59,18 @@ func (h *HomebrewManager) SearchPackage(pkg string) []string {
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n") packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList return packageList
} }
func (h *HomebrewManager) UpdatePackage(pkg string) error {
cmd := shell.ExecCommand("brew", "upgrade", pkg)
return cmd.Run()
}
func (h *HomebrewManager) UpdateAllPackages() error {
cmd := shell.ExecCommand("brew", "upgrade")
return cmd.Run()
}
func (h *HomebrewManager) Check(pkg string) error {
cmd := shell.ExecCommand("brew", "list", pkg)
return cmd.Run()
}

View file

@ -1,8 +1,8 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

268
pkg/packagemanager/os.go Normal file
View file

@ -0,0 +1,268 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"log"
"os"
"runtime"
"strings"
)
type OSManager struct {
OS *OS
SudoPassword string
pm PackageManager
}
func NewOSManager(sudoPassword string) *OSManager {
switch runtime.GOOS {
case "linux":
os, err := GetLinuxDistribution()
if err != nil {
log.Fatalf("error getting os information: %v", err)
}
var pm PackageManager
switch os.ID {
case "debian", "ubuntu":
pm = &AptManager{SudoPassword: sudoPassword}
case "arch":
pm = &PacmanManager{SudoPassword: sudoPassword}
case "fedora":
pm = &DnfManager{SudoPassword: sudoPassword}
default:
log.Fatalf("Unsupported Linux distribution: %s", os.ID)
}
return &OSManager{
OS: os,
SudoPassword: sudoPassword,
pm: pm,
}
case "windows":
os, err := getPlatformInfo()
if err != nil {
return nil
}
if _, err := shell.ExecLookPath("winget"); err == nil {
return &OSManager{
OS: os,
SudoPassword: "",
pm: &WingetManager{},
}
} else if _, err := shell.ExecLookPath("choco"); err == nil {
return &OSManager{
OS: os,
SudoPassword: "",
pm: &ChocoManager{},
}
} else {
log.Println("Neither Winget nor Chocolatey found on Windows. Package management functionality will be limited.")
}
case "darwin":
os, err := platformInfoMac()
if err != nil {
return nil
}
_, err = shell.ExecLookPath("brew")
if err == nil {
return &OSManager{
OS: os,
SudoPassword: sudoPassword,
pm: &HomebrewManager{},
}
} else {
manager := &HomebrewManager{}
manager.InstallManager()
return &OSManager{
OS: os,
SudoPassword: sudoPassword,
pm: manager,
}
}
default:
log.Fatal("Operating system not supported")
}
return nil
}
func (o *OSManager) Name() string {
return "OS Package Manager"
}
func (o *OSManager) InstallManager() error { return nil }
func (o *OSManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(o.pm, packages)
if err != nil {
return err
}
return nil
}
func (o *OSManager) InstallPackage(pkg string) error {
return o.pm.InstallPackage(pkg) //(o.OS.InstallCommand, pkg, o.SudoPassword)
}
func (o *OSManager) InstallBuildEssentials() error {
return InstallBuildEssentials(o.OS, o.SudoPassword)
}
func (o *OSManager) RemovePackage(pkg string) error {
return o.pm.RemovePackage(pkg)
}
func (o *OSManager) SearchPackage(pkg string) []string {
return o.pm.SearchPackage(pkg)
}
func (o *OSManager) UpdatePackage(pkg string) error {
return o.pm.UpdatePackage(pkg)
}
func (o *OSManager) UpdateAllPackages() error {
return o.pm.UpdateAllPackages()
}
func (o *OSManager) Check(pkg string) error {
return o.pm.Check(pkg)
}
type OS struct {
ID string
Name string
Version string
PackageManager string
}
func parseOsRelease(osRelease string) *OS {
var result OS
result.ID = "Unknown"
result.Name = "Unknown"
result.Version = "Unknown"
lines := strings.Split(osRelease, "\n")
for _, line := range lines {
splitLine := strings.SplitN(line, "=", 2)
if len(splitLine) != 2 {
continue
}
switch splitLine[0] {
case "ID":
result.ID = strings.ToLower(strings.Trim(splitLine[1], "\""))
case "NAME":
result.Name = strings.Trim(splitLine[1], "\"")
case "VERSION_ID":
result.Version = strings.Trim(splitLine[1], "\"")
}
}
err := result.getPackageManager()
if err != nil {
log.Fatal(err)
}
return &result
}
func GetLinuxDistribution() (*OS, error) {
_, err := os.Stat("/etc/os-release")
if os.IsNotExist(err) {
return nil, fmt.Errorf("unable to read system information")
}
osRelease, _ := os.ReadFile("/etc/os-release")
return parseOsRelease(string(osRelease)), nil
}
func InstallBuildEssentials(os *OS, sudoPassword string) error {
var command string
switch os.PackageManager {
case "pacman":
command = "pacman -S --noconfirm --needed base-devel"
case "apt":
command = "apt install -y build-essential"
case "dnf":
command = "dnf install -y @development-tools"
default:
return fmt.Errorf("keine Build Essentials für OS %s definiert", os.ID)
}
fmt.Printf("Installiere Build Essentials für %s...\n", os.Name)
if err := InstallPackage(command, "", sudoPassword); err != nil {
return fmt.Errorf("error installing Build Essentials: %v", err)
}
return nil
}
func getSysctlValue(key string) (string, error) {
stdout, err := shell.ExecCommand(".", "sysctl", key).Output()
if err != nil {
return "", err
}
version := strings.TrimPrefix(string(stdout), key+": ")
return strings.TrimSpace(version), nil
}
func platformInfoMac() (*OS, error) {
var result OS
result.ID = "Unknown"
result.Name = "MacOS"
result.Version = "Unknown"
version, err := getSysctlValue("kern.osproductversion")
if err != nil {
return nil, err
}
result.Version = version
ID, err := getSysctlValue("kern.osversion")
if err != nil {
return nil, err
}
result.ID = ID
return &result, nil
}
func getPlatformInfo() (*OS, error) {
switch runtime.GOOS {
case "windows":
return platformInfoWin()
case "darwin":
return platformInfoMac()
case "linux":
return GetLinuxDistribution()
default:
return nil, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
}
}
func (os *OS) getPackageManager() error {
switch os.ID {
case "debian", "ubuntu":
os.PackageManager = "apt"
return nil
case "arch":
os.PackageManager = "pacman"
return nil
case "fedora":
os.PackageManager = "dnf"
return nil
default:
pmcommands := []string{
"apt",
"dnf",
"pacman",
}
for _, pmname := range pmcommands {
_, err := shell.ExecLookPath(pmname)
if err == nil {
os.PackageManager = pmname
return nil
}
}
return fmt.Errorf("no packagemanager found fos os: %s", os.Name)
}
}

View file

@ -41,13 +41,4 @@ VERSION_ID="20.04"
if os.Version != "20.04" { if os.Version != "20.04" {
t.Errorf("Expected Version to be '20.04', got %s", os.Version) t.Errorf("Expected Version to be '20.04', got %s", os.Version)
} }
if os.PackageManager != "apt" {
t.Errorf("Expected PackageManager to be 'apt', got %s", os.PackageManager)
}
if os.InstallCommand != "apt install -y" {
t.Errorf("Expected InstallCommand to be 'apt install -y', got %s", os.InstallCommand)
}
if os.SearchCommand != "apt search" {
t.Errorf("Expected SearchCommand to be 'apt search', got %s", os.SearchCommand)
}
} }

View file

@ -1,10 +1,10 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt" "fmt"
"log" "log"
"strings" "strings"
"system_setup_tool/internal/shell"
) )
type Packages struct { type Packages struct {

View file

@ -2,9 +2,12 @@ package packagemanager
type PackageManager interface { type PackageManager interface {
Install(packages []string) error Install(packages []string) error
Check(pkg string) error
InstallPackage(pkg string) error InstallPackage(pkg string) error
InstallManager() error InstallManager() error
RemovePackage(pkg string) error RemovePackage(pkg string) error
SearchPackage(pkg string) []string SearchPackage(pkg string) []string
UpdatePackage(pkg string) error
UpdateAllPackages() error
Name() string Name() string
} }

View file

@ -0,0 +1,81 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
"log"
"strings"
)
type PacmanManager struct {
SudoPassword string
}
func (m *PacmanManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(m, packages)
if err != nil {
return err
}
return nil
}
func (m *PacmanManager) Name() string {
return "OS Home Manager"
}
func (m *PacmanManager) InstallManager() error {
return nil
}
func (m *PacmanManager) InstallPackage(pkg string) error {
cmd := "pacman -S --noconfirm --needed"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(m.SudoPassword + "\n")
return command.Run()
}
func (m *PacmanManager) RemovePackage(pkg string) error {
cmd := "pacman -R"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(m.SudoPassword + "\n")
return command.Run()
}
func (p *PacmanManager) SearchPackage(pkg string) []string {
cmd := "pacman -Ss"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(p.SudoPassword + "\n")
packages, err := command.Output()
if err != nil {
log.Printf("error fetching %s packages: %v", p.Name(), err)
}
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList
}
func (p *PacmanManager) UpdatePackage(pkg string) error {
cmd := "pacman -S"
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(p.SudoPassword + "\n")
return command.Run()
}
func (p *PacmanManager) UpdateAllPackages() error {
cmd := "apt -S"
fullCmd := fmt.Sprintf("%s", cmd)
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(p.SudoPassword + "\n")
return command.Run()
}
func (p *PacmanManager) Check(pkg string) error {
cmd := shell.ExecCommand("/bin/sh", "-c", fmt.Sprintf("paxman -Q | grep %s", pkg))
return cmd.Run()
}

View file

@ -1,6 +1,9 @@
package packagemanager package packagemanager
import "system_setup_tool/internal/shell" import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"fmt"
)
type PipxManager struct{} type PipxManager struct{}
@ -46,3 +49,18 @@ func (p *PipxManager) RemovePackage(pkg string) error {
func (p *PipxManager) SearchPackage(pkg string) []string { func (p *PipxManager) SearchPackage(pkg string) []string {
return []string{} return []string{}
} }
func (p *PipxManager) UpdatePackage(pkg string) error {
cmd := shell.ExecCommand("pipx", "upgrade", pkg)
return cmd.Run()
}
func (p *PipxManager) UpdateAllPackages() error {
cmd := shell.ExecCommand("pipx", "upgrade-all")
return cmd.Run()
}
func (p *PipxManager) Check(pkg string) error {
cmd := shell.ExecCommand("/bin/sh", "-c", fmt.Sprintf("pipx list | grep %s", pkg))
return cmd.Run()
}

View file

@ -1,8 +1,8 @@
package packagemanager package packagemanager
import ( import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"os/exec" "os/exec"
"system_setup_tool/internal/shell"
"testing" "testing"
) )

30
pkg/packagemanager/win.go Normal file
View file

@ -0,0 +1,30 @@
//go:build windows
// +build windows
package packagemanager
import (
"fmt"
"golang.org/x/sys/windows/registry"
)
func platformInfoWin() (*OS, error) {
var result OS
result.ID = "Unknown"
result.Name = "Windows"
result.Version = "Unknown"
key, _ := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
productName, _, _ := key.GetStringValue("ProductName")
currentBuild, _, _ := key.GetStringValue("CurrentBuildNumber")
displayVersion, _, _ := key.GetStringValue("DisplayVersion")
releaseId, _, _ := key.GetStringValue("ReleaseId")
result.Name = productName
result.Version = fmt.Sprintf("%s (Build: %s)", releaseId, currentBuild)
result.ID = displayVersion
return &result, key.Close()
}

View file

@ -0,0 +1,8 @@
//go:build linux || darwin
// +build linux darwin
package packagemanager
func platformInfoWin() (*OS, error) {
return nil, nil
}

View file

@ -0,0 +1,71 @@
package packagemanager
import (
"codeberg.org/Pata1704/system_setup_tool/internal/shell"
"log"
"strings"
)
type WingetManager struct{}
func (w *WingetManager) Install(packages []string) error {
if len(packages) == 0 {
return nil
}
err := InstallWithProgress(w, packages)
if err != nil {
return err
}
return nil
}
func (w *WingetManager) Name() string {
return "Winget"
}
func (w *WingetManager) InstallManager() error {
if _, err := shell.ExecLookPath("winget"); err == nil {
return nil
}
return installHomebrew()
}
func installWinget() error {
return nil
}
func (w *WingetManager) InstallPackage(pkg string) error {
cmd := shell.ExecCommand("winget", "install", pkg)
return cmd.Run()
}
func (w *WingetManager) RemovePackage(pkg string) error {
cmd := shell.ExecCommand("winget", "uninstall", pkg)
return cmd.Run()
}
func (w *WingetManager) SearchPackage(pkg string) []string {
cmd := shell.ExecCommand("winget", "search", pkg)
packages, err := cmd.Output()
if err != nil {
log.Printf("error fetching %s packages: %v", w.Name(), err)
}
packageList := strings.Split(strings.TrimSpace(string(packages)), "\n")
return packageList
}
func (w *WingetManager) UpdatePackage(pkg string) error {
cmd := shell.ExecCommand("winget", "update", pkg)
return cmd.Run()
}
func (w *WingetManager) UpdateAllPackages() error {
cmd := shell.ExecCommand("winget", "update")
return cmd.Run()
}
func (w *WingetManager) Check(pkg string) error {
cmd := shell.ExecCommand("wiget", "show", pkg)
return cmd.Run()
}

3
renovate.json Normal file
View file

@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View file

@ -1,32 +0,0 @@
package utils
import (
"fmt"
"github.com/charmbracelet/huh"
)
func GetSudoPassword() (string, error) {
var password string
form := huh.NewForm(
huh.NewGroup(
huh.NewInput().
Title("Bitte geben Sie Ihr sudo-Passwort ein").
EchoMode(huh.EchoModePassword).
Value(&password),
),
).WithTheme(huh.ThemeCatppuccin())
err := form.Run()
if err != nil {
return "", fmt.Errorf("fehler bei der Passwortabfrage: %v", err)
}
return password, nil
}
func max(a, b int) int {
if a > b {
return a
}
return b
}