refactor: seperate files, function and structs into seperate packages
This commit is contained in:
parent
7f951585c8
commit
5b7775f33e
37 changed files with 547 additions and 677 deletions
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
|
env:
|
||||||
|
- GITHUB_TOKEN={{ .Env.CODEBERG_TOKEN }}
|
||||||
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"system_setup_tool/tui"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
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",
|
||||||
Run: 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"))
|
viper.BindPFlag("config", RootCmd.PersistentFlags().Lookup("config"))
|
||||||
|
|
||||||
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,7 +39,7 @@ 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)
|
packageCmd.AddCommand(addCmd, deleteCmd, showCmd, enableCmd)
|
||||||
rootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd)
|
RootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"system_setup_tool/utils"
|
||||||
|
|
||||||
|
pm "system_setup_tool/packagemanager"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
@ -14,29 +17,25 @@ var installCmd = &cobra.Command{
|
||||||
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 PackageManager
|
var manager pm.PackageManager
|
||||||
switch managerName {
|
switch managerName {
|
||||||
case "os":
|
case "os":
|
||||||
opSys, err := getLinuxDistribution()
|
sudoPassword, err := utils.GetSudoPassword()
|
||||||
if err != nil {
|
|
||||||
log.Printf("error getting OS information: %v", err)
|
|
||||||
}
|
|
||||||
sudoPassword, err := getSudoPassword()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
osManager := NewOSManager(opSys, sudoPassword, []string{packageName})
|
osManager := pm.NewOSManager(sudoPassword)
|
||||||
if err := osManager.Install([]string{packageName}); err != nil {
|
if err := osManager.Install([]string{packageName}); err != nil {
|
||||||
log.Printf("error: %v\n", err)
|
log.Printf("error: %v\n", err)
|
||||||
}
|
}
|
||||||
case "homebrew":
|
case "homebrew":
|
||||||
manager = &HomebrewManager{}
|
manager = &pm.HomebrewManager{}
|
||||||
case "cargo":
|
case "cargo":
|
||||||
manager = &CargoManager{}
|
manager = &pm.CargoManager{}
|
||||||
case "pipx":
|
case "pipx":
|
||||||
manager = &PipxManager{}
|
manager = &pm.PipxManager{}
|
||||||
case "flatpak":
|
case "flatpak":
|
||||||
manager = &FlatpakManager{}
|
manager = &pm.FlatpakManager{}
|
||||||
default:
|
default:
|
||||||
fmt.Println("No PackageManager found")
|
fmt.Println("No PackageManager found")
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"system_setup_tool/utils"
|
||||||
|
|
||||||
|
pm "system_setup_tool/packagemanager"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
@ -13,29 +16,25 @@ var removeCmd = &cobra.Command{
|
||||||
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 PackageManager
|
var manager pm.PackageManager
|
||||||
switch managerName {
|
switch managerName {
|
||||||
case "os":
|
case "os":
|
||||||
opSys, err := getLinuxDistribution()
|
sudoPassword, err := utils.GetSudoPassword()
|
||||||
if err != nil {
|
|
||||||
log.Printf("error getting OS information: %v", err)
|
|
||||||
}
|
|
||||||
sudoPassword, err := getSudoPassword()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
osManager := NewOSManager(opSys, sudoPassword, []string{packageName})
|
osManager := pm.NewOSManager(sudoPassword)
|
||||||
if err := osManager.Install([]string{packageName}); err != nil {
|
if err := osManager.Install([]string{packageName}); err != nil {
|
||||||
log.Printf("error: %v\n", err)
|
log.Printf("error: %v\n", err)
|
||||||
}
|
}
|
||||||
case "homebrew":
|
case "homebrew":
|
||||||
manager = &HomebrewManager{}
|
manager = &pm.HomebrewManager{}
|
||||||
case "cargo":
|
case "cargo":
|
||||||
manager = &CargoManager{}
|
manager = &pm.CargoManager{}
|
||||||
case "pipx":
|
case "pipx":
|
||||||
manager = &PipxManager{}
|
manager = &pm.PipxManager{}
|
||||||
case "flatpak":
|
case "flatpak":
|
||||||
manager = &FlatpakManager{}
|
manager = &pm.FlatpakManager{}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if err := manager.RemovePackage(packageName); err != nil {
|
if err := manager.RemovePackage(packageName); err != nil {
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
pm "system_setup_tool/packagemanager"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -18,16 +19,11 @@ var searchCmd = &cobra.Command{
|
||||||
if managerName == "os" {
|
if managerName == "os" {
|
||||||
managerName = "OS Package Manager"
|
managerName = "OS Package Manager"
|
||||||
}
|
}
|
||||||
opSys, err := getLinuxDistribution()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("error getting OS information: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
managers := []PackageManager{
|
managers := []pm.PackageManager{
|
||||||
NewOSManager(opSys, "", nil),
|
pm.NewOSManager(""),
|
||||||
&HomebrewManager{},
|
&pm.HomebrewManager{},
|
||||||
&FlatpakManager{},
|
&pm.FlatpakManager{},
|
||||||
}
|
}
|
||||||
|
|
||||||
if managerName != "" {
|
if managerName != "" {
|
||||||
|
|
@ -57,7 +53,7 @@ func displayResults(results []string, manager string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchAndDisplayResults(manager PackageManager, packageName string) {
|
func searchAndDisplayResults(manager pm.PackageManager, packageName string) {
|
||||||
fmt.Printf("Searching in %s:\n", manager.Name())
|
fmt.Printf("Searching in %s:\n", manager.Name())
|
||||||
results := manager.SearchPackage(packageName)
|
results := manager.SearchPackage(packageName)
|
||||||
displayResults(results, manager.Name())
|
displayResults(results, manager.Name())
|
||||||
|
|
@ -3,10 +3,11 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"system_setup_tool/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := cmd.RootCmd.Execute(); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
99
config.toml
99
config.toml
|
|
@ -12,20 +12,107 @@ packages = ['typst-cli']
|
||||||
|
|
||||||
[package_managers.flatpak]
|
[package_managers.flatpak]
|
||||||
enable = true
|
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']
|
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]
|
[package_managers.go]
|
||||||
enable = true
|
enable = true
|
||||||
packages = ['github.com/stefanlogue/meteor', 'golang.org/x/tools/gopls', 'github.com/go-delve/delve/cmd/dlv', 'github.com/air-verse/air']
|
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]
|
[package_managers.homebrew]
|
||||||
enable = true
|
enable = true
|
||||||
packages = ['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']
|
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]
|
[package_managers.pipx]
|
||||||
enable = true
|
enable = true
|
||||||
packages = ['euporie']
|
packages = ['euporie']
|
||||||
|
|
||||||
[packages]
|
[package_managers.os]
|
||||||
headless = ['git', 'curl', 'wget', 'biber', 'bear', 'docker', 'docker-compose', 'zsh', 'npm', 'task', 'tree-sitter-cli', 'python3-pip', 'latexmk', 'luarocks']
|
enable = true
|
||||||
non_headless = ['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']
|
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',
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
package main
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"system_setup_tool/dotfiles"
|
||||||
|
pm "system_setup_tool/packagemanager"
|
||||||
|
)
|
||||||
|
|
||||||
type PackageManagerConfig struct {
|
type PackageManagerConfig struct {
|
||||||
Enable bool `mapstructure:"enable"`
|
Enable bool `mapstructure:"enable"`
|
||||||
|
|
@ -7,7 +12,7 @@ type PackageManagerConfig struct {
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Headless bool `mapstructure:"headless"`
|
Headless bool `mapstructure:"headless"`
|
||||||
Packages Packages `mapstructure:"packages"`
|
Packages pm.Packages `mapstructure:"packages"`
|
||||||
PackageManagers map[string]PackageManagerConfig `mapstructure:"package_managers"`
|
PackageManagers map[string]PackageManagerConfig `mapstructure:"package_managers"`
|
||||||
Dotfiles DotfilesConfig `mapstructure:"dotfiles"`
|
Dotfiles dotfiles.DotfilesConfig `mapstructure:"dotfiles"`
|
||||||
}
|
}
|
||||||
42
dotfiles.go
42
dotfiles.go
|
|
@ -1,42 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DotfilesConfig struct {
|
|
||||||
Enable bool `mapstructure:"enable"`
|
|
||||||
GitRepo string `mapstructure:"git_repo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupDotfiles(config DotfilesConfig) error {
|
|
||||||
if _, err := execLookPath("git"); err != nil {
|
|
||||||
return fmt.Errorf("git ist nicht installiert")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := execLookPath("stow"); err != nil {
|
|
||||||
return fmt.Errorf("gnu stow ist nicht installiert")
|
|
||||||
}
|
|
||||||
|
|
||||||
dotfilesDir := filepath.Join(os.Getenv("HOME"), "dotfiles")
|
|
||||||
|
|
||||||
cmd := execCommand("git", "clone", config.GitRepo, dotfilesDir)
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
return fmt.Errorf("fehler beim Klonen der Dotfiles: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Chdir(dotfilesDir); err != nil {
|
|
||||||
return fmt.Errorf("fehler beim Wechseln in das Dotfiles-Verzeichnis: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = execCommand("stow", ".", "--override='*'")
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
log.Printf("Fehler beim Linken: %v", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Alles erfolgreich verlinkt\n")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
43
dotfiles/dotfiles.go
Normal file
43
dotfiles/dotfiles.go
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
package dotfiles
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DotfilesConfig struct {
|
||||||
|
Enable bool `mapstructure:"enable"`
|
||||||
|
GitRepo string `mapstructure:"git_repo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetupDotfiles(config DotfilesConfig) error {
|
||||||
|
if _, err := shell.ExecLookPath("git"); err != nil {
|
||||||
|
return fmt.Errorf("git ist nicht installiert")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := shell.ExecLookPath("stow"); err != nil {
|
||||||
|
return fmt.Errorf("gnu stow not installed")
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfilesDir := filepath.Join(os.Getenv("HOME"), "dotfiles")
|
||||||
|
|
||||||
|
cmd := shell.ExecCommand("git", "clone", config.GitRepo, dotfilesDir)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("error cloning dotfiles: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Chdir(dotfilesDir); err != nil {
|
||||||
|
return fmt.Errorf("error changing into dotfiles directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = shell.ExecCommand("stow", ".", "--override='*'")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("error creating links: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("all linked properly\n")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
7
go.mod
7
go.mod
|
|
@ -3,10 +3,7 @@ module system_setup_tool
|
||||||
go 1.23.4
|
go 1.23.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/charmbracelet/bubbles v0.20.0
|
|
||||||
github.com/charmbracelet/bubbletea v1.2.4
|
|
||||||
github.com/charmbracelet/huh v0.6.0
|
github.com/charmbracelet/huh v0.6.0
|
||||||
github.com/charmbracelet/lipgloss v1.0.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.18.0
|
||||||
|
|
@ -18,7 +15,9 @@ 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.2.0 // indirect
|
||||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
github.com/charmbracelet/bubbles v0.20.0 // indirect
|
||||||
|
github.com/charmbracelet/bubbletea v1.2.4 // indirect
|
||||||
|
github.com/charmbracelet/lipgloss v1.0.0 // indirect
|
||||||
github.com/charmbracelet/x/ansi v0.4.5 // indirect
|
github.com/charmbracelet/x/ansi v0.4.5 // indirect
|
||||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
|
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
|
||||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -10,8 +10,6 @@ github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQW
|
||||||
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
||||||
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
|
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
|
||||||
github.com/charmbracelet/bubbletea v1.2.4/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM=
|
github.com/charmbracelet/bubbletea v1.2.4/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM=
|
||||||
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
|
|
||||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
|
||||||
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=
|
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=
|
||||||
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
|
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
|
||||||
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
|
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
|
||||||
|
|
|
||||||
23
internal/shell/shell.go
Normal file
23
internal/shell/shell.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package shell
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ExecCommand = exec.Command
|
||||||
|
ExecLookPath = exec.LookPath
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExecuteShellCommand(command string, env string) error {
|
||||||
|
cmd := ExecCommand("bash", "-c", command)
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Env = append(cmd.Env, env)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("befehl fehlgeschlagen: %v\nAusgabe: %s", err, output)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build mage
|
//go:build mage
|
||||||
// +build mage
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
|
||||||
164
model.go
164
model.go
|
|
@ -1,164 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/progress"
|
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
|
||||||
)
|
|
||||||
|
|
||||||
type model struct {
|
|
||||||
packages []string
|
|
||||||
index int
|
|
||||||
width int
|
|
||||||
height int
|
|
||||||
spinner spinner.Model
|
|
||||||
progress progress.Model
|
|
||||||
done bool
|
|
||||||
sudoPassword string
|
|
||||||
os OS
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) installSpecialSoftware() error {
|
|
||||||
if _, err := execLookPath("oh-my-posh"); err == nil {
|
|
||||||
fmt.Println("Oh-my-posh ist bereits installiert")
|
|
||||||
} else {
|
|
||||||
poshCommand := "curl -s https://ohmyposh.dev/install.sh | bash -s"
|
|
||||||
if err := installPackage(poshCommand, "", ""); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
homeDir, err := os.UserHomeDir()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Fehler beim Ermitteln des Home-Verzeichnisses: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ohMyZshDir := filepath.Join(homeDir, ".oh-my-zsh")
|
|
||||||
if _, err := os.Stat(ohMyZshDir); !os.IsNotExist(err) {
|
|
||||||
fmt.Println("Oh My Zsh ist bereits installiert.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Installiere Oh My Zsh...")
|
|
||||||
err = executeShellCommand(`sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"`, "")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Fehler bei der Installation von Oh My Zsh: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins := []string{
|
|
||||||
"git clone https://github.com/zsh-users/zsh-autosuggestions.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autosuggestions",
|
|
||||||
"git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting",
|
|
||||||
"git clone https://github.com/zdharma-continuum/fast-syntax-highlighting.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/fast-syntax-highlighting",
|
|
||||||
"git clone --depth 1 -- https://github.com/marlonrichert/zsh-autocomplete.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autocomplete",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, plugin := range plugins {
|
|
||||||
err := executeShellCommand(plugin, "")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Fehler bei der Installation des Plugins: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Oh My Zsh wurde erfolgreich installiert.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newModel(packages []string, sudoPassword string, os *OS) model {
|
|
||||||
p := progress.New(
|
|
||||||
progress.WithDefaultGradient(),
|
|
||||||
progress.WithWidth(40),
|
|
||||||
progress.WithoutPercentage(),
|
|
||||||
)
|
|
||||||
s := spinner.New()
|
|
||||||
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
|
|
||||||
return model{
|
|
||||||
packages: packages,
|
|
||||||
spinner: s,
|
|
||||||
progress: p,
|
|
||||||
sudoPassword: sudoPassword,
|
|
||||||
os: *os,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) Init() tea.Cmd {
|
|
||||||
return tea.Batch(m.installPackageCmd(m.packages[m.index]), m.spinner.Tick)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case tea.WindowSizeMsg:
|
|
||||||
m.width, m.height = msg.Width, msg.Height
|
|
||||||
case tea.KeyMsg:
|
|
||||||
switch msg.String() {
|
|
||||||
case "ctrl+c", "esc", "q":
|
|
||||||
return m, tea.Quit
|
|
||||||
}
|
|
||||||
case installedPkgMsg:
|
|
||||||
pkg := m.packages[m.index]
|
|
||||||
if m.index >= len(m.packages)-1 {
|
|
||||||
m.done = true
|
|
||||||
return m, tea.Sequence(
|
|
||||||
tea.Printf("%s %s", checkMark, pkg),
|
|
||||||
tea.Quit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.index++
|
|
||||||
progressCmd := m.progress.SetPercent(float64(m.index) / float64(len(m.packages)))
|
|
||||||
|
|
||||||
return m, tea.Batch(
|
|
||||||
progressCmd,
|
|
||||||
tea.Printf("%s %s", checkMark, pkg),
|
|
||||||
m.installPackageCmd(m.packages[m.index]),
|
|
||||||
)
|
|
||||||
case spinner.TickMsg:
|
|
||||||
var cmd tea.Cmd
|
|
||||||
m.spinner, cmd = m.spinner.Update(msg)
|
|
||||||
return m, cmd
|
|
||||||
case progress.FrameMsg:
|
|
||||||
newModel, cmd := m.progress.Update(msg)
|
|
||||||
if newModel, ok := newModel.(progress.Model); ok {
|
|
||||||
m.progress = newModel
|
|
||||||
}
|
|
||||||
return m, cmd
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) View() string {
|
|
||||||
n := len(m.packages)
|
|
||||||
w := lipgloss.Width(fmt.Sprintf("%d", n))
|
|
||||||
|
|
||||||
if m.done {
|
|
||||||
return doneStyle.Render(fmt.Sprintf("Done! Installed %d packages.\n", n))
|
|
||||||
}
|
|
||||||
|
|
||||||
pkgCount := fmt.Sprintf(" %*d/%*d", w, m.index, w, n)
|
|
||||||
|
|
||||||
spin := m.spinner.View() + " "
|
|
||||||
prog := m.progress.View()
|
|
||||||
cellsAvail := max(0, m.width-lipgloss.Width(spin+prog+pkgCount))
|
|
||||||
|
|
||||||
pkgName := currentPkgNameStyle.Render(m.packages[m.index])
|
|
||||||
info := lipgloss.NewStyle().MaxWidth(cellsAvail).Render("Installing " + pkgName)
|
|
||||||
|
|
||||||
cellsRemaining := max(0, m.width-lipgloss.Width(spin+info+prog+pkgCount))
|
|
||||||
gap := strings.Repeat(" ", cellsRemaining)
|
|
||||||
|
|
||||||
return spin + info + gap + prog + pkgCount
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) installPackageCmd(pkg string) tea.Cmd {
|
|
||||||
return func() tea.Msg {
|
|
||||||
if err := installPackage(m.os.InstallCommand, pkg, m.sudoPassword); err != nil {
|
|
||||||
log.Printf("Fehler beim Installieren von %s: %v", pkg, err)
|
|
||||||
}
|
|
||||||
return installedPkgMsg(pkg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
|
import "system_setup_tool/internal/shell"
|
||||||
|
|
||||||
type CargoManager struct{}
|
type CargoManager struct{}
|
||||||
|
|
||||||
|
|
@ -6,7 +8,7 @@ func (c *CargoManager) Install(packages []string) error {
|
||||||
if len(packages) == 0 {
|
if len(packages) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := installWithProgress(c, packages)
|
err := InstallWithProgress(c, packages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -18,25 +20,25 @@ func (c *CargoManager) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CargoManager) InstallManager() error {
|
func (c *CargoManager) InstallManager() error {
|
||||||
if _, err := execLookPath("brew"); err != nil {
|
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||||
installHomebrew()
|
installHomebrew()
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := execLookPath("cargo"); err == nil {
|
if _, err := shell.ExecLookPath("cargo"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := execCommand("brew", "install", "rust")
|
cmd := shell.ExecCommand("brew", "install", "rust")
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CargoManager) InstallPackage(pkg string) error {
|
func (c *CargoManager) InstallPackage(pkg string) error {
|
||||||
cmd := execCommand("cargo", "install", pkg)
|
cmd := shell.ExecCommand("cargo", "install", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CargoManager) RemovePackage(pkg string) error {
|
func (c *CargoManager) RemovePackage(pkg string) error {
|
||||||
cmd := execCommand("cargo", "uninstall", pkg)
|
cmd := shell.ExecCommand("cargo", "uninstall", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// cargo_test.go
|
// cargo_test.go
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,13 +18,13 @@ func TestCargoManager_InstallManager(t *testing.T) {
|
||||||
cm := &CargoManager{}
|
cm := &CargoManager{}
|
||||||
|
|
||||||
// Mock exec.LookPath
|
// Mock exec.LookPath
|
||||||
execLookPath = func(file string) (string, error) {
|
shell.ExecLookPath = func(file string) (string, error) {
|
||||||
if file == "cargo" {
|
if file == "cargo" {
|
||||||
return "/usr/bin/cargo", nil
|
return "/usr/bin/cargo", nil
|
||||||
}
|
}
|
||||||
return "", exec.ErrNotFound
|
return "", exec.ErrNotFound
|
||||||
}
|
}
|
||||||
defer func() { execLookPath = exec.LookPath }()
|
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||||
|
|
||||||
if err := cm.InstallManager(); err != nil {
|
if err := cm.InstallManager(); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -34,10 +35,10 @@ func TestCargoManager_InstallPackage(t *testing.T) {
|
||||||
cm := &CargoManager{}
|
cm := &CargoManager{}
|
||||||
|
|
||||||
// Mock exec.Command
|
// Mock exec.Command
|
||||||
execCommand = func(name string, arg ...string) *exec.Cmd {
|
shell.ExecCommand = func(name string, arg ...string) *exec.Cmd {
|
||||||
return exec.Command("echo", "mocked cargo install")
|
return exec.Command("echo", "mocked cargo install")
|
||||||
}
|
}
|
||||||
defer func() { execCommand = exec.Command }()
|
defer func() { shell.ExecCommand = exec.Command }()
|
||||||
|
|
||||||
if err := cm.InstallPackage("test-package"); err != nil {
|
if err := cm.InstallPackage("test-package"); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlatpakManager struct {
|
type FlatpakManager struct {
|
||||||
|
|
@ -13,11 +13,23 @@ type FlatpakManager struct {
|
||||||
Config FlatpakConfig
|
Config FlatpakConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewFlatpakManager(sudoPassword string, config FlatpakConfig) *FlatpakManager {
|
||||||
|
os, err := GetLinuxDistribution()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error geting os information: %v", err)
|
||||||
|
}
|
||||||
|
return &FlatpakManager{
|
||||||
|
OS: os,
|
||||||
|
SudoPassword: sudoPassword,
|
||||||
|
Config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FlatpakManager) Install(packages []string) error {
|
func (f *FlatpakManager) Install(packages []string) error {
|
||||||
if len(packages) == 0 {
|
if len(packages) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := installWithProgress(f, packages)
|
err := InstallWithProgress(f, packages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +41,7 @@ func (f *FlatpakManager) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlatpakManager) InstallManager() error {
|
func (f *FlatpakManager) InstallManager() error {
|
||||||
if _, err := exec.LookPath("flatpak"); err == nil {
|
if _, err := shell.ExecLookPath("flatpak"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +81,7 @@ func installFlatpak(os *OS, sudoPassword string) error {
|
||||||
return fmt.Errorf("keine Flatpak-Installation für OS %s definiert", os.ID)
|
return fmt.Errorf("keine Flatpak-Installation für OS %s definiert", os.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := installPackage(command, "", sudoPassword); err != nil {
|
if err := InstallPackage(command, "", sudoPassword); err != nil {
|
||||||
return fmt.Errorf("fehler bei der Flatpak-Installation: %v", err)
|
return fmt.Errorf("fehler bei der Flatpak-Installation: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -77,7 +89,7 @@ func installFlatpak(os *OS, sudoPassword string) error {
|
||||||
|
|
||||||
func addFlatpakRemotes(remotes []Remote) error {
|
func addFlatpakRemotes(remotes []Remote) error {
|
||||||
for _, remote := range remotes {
|
for _, remote := range remotes {
|
||||||
cmd := execCommand("flatpak", "remote-add", "--if-not-exists", remote.Name, remote.URL)
|
cmd := shell.ExecCommand("flatpak", "remote-add", "--if-not-exists", remote.Name, remote.URL)
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return fmt.Errorf("fehler beim Hinzufügen des Remotes %s: %v", remote.Name, err)
|
return fmt.Errorf("fehler beim Hinzufügen des Remotes %s: %v", remote.Name, err)
|
||||||
}
|
}
|
||||||
|
|
@ -86,17 +98,17 @@ func addFlatpakRemotes(remotes []Remote) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlatpakManager) InstallPackage(pkg string) error {
|
func (f *FlatpakManager) InstallPackage(pkg string) error {
|
||||||
cmd := execCommand("flatpak", "install", "-y", pkg)
|
cmd := shell.ExecCommand("flatpak", "install", "-y", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlatpakManager) RemovePackage(pkg string) error {
|
func (f *FlatpakManager) RemovePackage(pkg string) error {
|
||||||
cmd := execCommand("flatpak", "uninstall", "-y", pkg)
|
cmd := shell.ExecCommand("flatpak", "uninstall", "-y", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlatpakManager) SearchPackage(pkg string) []string {
|
func (f *FlatpakManager) SearchPackage(pkg string) []string {
|
||||||
cmd := execCommand("flatpak", "search", pkg)
|
cmd := shell.ExecCommand("flatpak", "search", pkg)
|
||||||
packages, err := cmd.Output()
|
packages, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error fetching %s packages: %v", f.Name(), err)
|
log.Printf("error fetching %s packages: %v", f.Name(), err)
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// flatpak_test.go
|
package packagemanager
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -33,10 +33,10 @@ func TestFlatpakManager_InstallPackage(t *testing.T) {
|
||||||
fm := &FlatpakManager{}
|
fm := &FlatpakManager{}
|
||||||
|
|
||||||
// Mock exec.Command
|
// Mock exec.Command
|
||||||
execCommand = func(name string, arg ...string) *exec.Cmd {
|
shell.ExecCommand = func(name string, arg ...string) *exec.Cmd {
|
||||||
return exec.Command("echo", "mocked flatpak install")
|
return exec.Command("echo", "mocked flatpak install")
|
||||||
}
|
}
|
||||||
defer func() { execCommand = exec.Command }()
|
defer func() { shell.ExecCommand = exec.Command }()
|
||||||
|
|
||||||
if err := fm.InstallPackage("test-package"); err != nil {
|
if err := fm.InstallPackage("test-package"); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
|
import "system_setup_tool/internal/shell"
|
||||||
|
|
||||||
type GolangManager struct{}
|
type GolangManager struct{}
|
||||||
|
|
||||||
|
|
@ -6,7 +8,7 @@ func (g *GolangManager) Install(packages []string) error {
|
||||||
if len(packages) == 0 {
|
if len(packages) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := installWithProgress(g, packages)
|
err := InstallWithProgress(g, packages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -18,25 +20,25 @@ func (g *GolangManager) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GolangManager) InstallManager() error {
|
func (g *GolangManager) InstallManager() error {
|
||||||
if _, err := execLookPath("brew"); err != nil {
|
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||||
installHomebrew()
|
installHomebrew()
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := execLookPath("go"); err == nil {
|
if _, err := shell.ExecLookPath("go"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := execCommand("brew", "install", "golang")
|
cmd := shell.ExecCommand("brew", "install", "golang")
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GolangManager) InstallPackage(pkg string) error {
|
func (g *GolangManager) InstallPackage(pkg string) error {
|
||||||
cmd := execCommand("go", "install", pkg+"@latest")
|
cmd := shell.ExecCommand("go", "install", pkg+"@latest")
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GolangManager) RemovePackage(pkg string) error {
|
func (g *GolangManager) RemovePackage(pkg string) error {
|
||||||
cmd := execCommand("go", "uninstall", pkg)
|
cmd := shell.ExecCommand("go", "uninstall", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// golang_test.go
|
package packagemanager
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,13 +17,13 @@ func TestGolangManager_InstallManager(t *testing.T) {
|
||||||
gm := &GolangManager{}
|
gm := &GolangManager{}
|
||||||
|
|
||||||
// Mock exec.LookPath
|
// Mock exec.LookPath
|
||||||
execLookPath = func(file string) (string, error) {
|
shell.ExecLookPath = func(file string) (string, error) {
|
||||||
if file == "go" {
|
if file == "go" {
|
||||||
return "/usr/local/go/bin/go", nil
|
return "/usr/local/go/bin/go", nil
|
||||||
}
|
}
|
||||||
return "", exec.ErrNotFound
|
return "", exec.ErrNotFound
|
||||||
}
|
}
|
||||||
defer func() { execLookPath = exec.LookPath }()
|
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||||
|
|
||||||
if err := gm.InstallManager(); err != nil {
|
if err := gm.InstallManager(); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -34,10 +34,10 @@ func TestGolangManager_InstallPackage(t *testing.T) {
|
||||||
gm := &GolangManager{}
|
gm := &GolangManager{}
|
||||||
|
|
||||||
// Mock exec.Command
|
// Mock exec.Command
|
||||||
execCommand = func(name string, arg ...string) *exec.Cmd {
|
shell.ExecCommand = func(name string, arg ...string) *exec.Cmd {
|
||||||
return exec.Command("echo", "mocked go install")
|
return exec.Command("echo", "mocked go install")
|
||||||
}
|
}
|
||||||
defer func() { execCommand = exec.Command }()
|
defer func() { shell.ExecCommand = exec.Command }()
|
||||||
|
|
||||||
if err := gm.InstallPackage("github.com/test/package"); err != nil {
|
if err := gm.InstallPackage("github.com/test/package"); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HomebrewManager struct{}
|
type HomebrewManager struct{}
|
||||||
|
|
@ -12,7 +13,7 @@ func (h *HomebrewManager) Install(packages []string) error {
|
||||||
if len(packages) == 0 {
|
if len(packages) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := installWithProgress(h, packages)
|
err := InstallWithProgress(h, packages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +25,7 @@ func (h *HomebrewManager) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HomebrewManager) InstallManager() error {
|
func (h *HomebrewManager) InstallManager() error {
|
||||||
if _, err := execLookPath("brew"); err == nil {
|
if _, err := shell.ExecLookPath("brew"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,7 +33,7 @@ func (h *HomebrewManager) InstallManager() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func installHomebrew() error {
|
func installHomebrew() error {
|
||||||
err := executeShellCommand("sh -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)", "NONINTERACTE=1")
|
err := shell.ExecuteShellCommand("sh -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)", "NONINTERACTE=1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fehler bei der Installation von Homebrew: %v", err)
|
return fmt.Errorf("fehler bei der Installation von Homebrew: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -40,17 +41,17 @@ func installHomebrew() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HomebrewManager) InstallPackage(pkg string) error {
|
func (h *HomebrewManager) InstallPackage(pkg string) error {
|
||||||
cmd := execCommand("brew", "install", pkg)
|
cmd := shell.ExecCommand("brew", "install", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HomebrewManager) RemovePackage(pkg string) error {
|
func (h *HomebrewManager) RemovePackage(pkg string) error {
|
||||||
cmd := execCommand("brew", "uninstall", pkg)
|
cmd := shell.ExecCommand("brew", "uninstall", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HomebrewManager) SearchPackage(pkg string) []string {
|
func (h *HomebrewManager) SearchPackage(pkg string) []string {
|
||||||
cmd := execCommand("brew", "search", pkg)
|
cmd := shell.ExecCommand("brew", "search", pkg)
|
||||||
packages, err := cmd.Output()
|
packages, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error fetching %s packages: %v", h.Name(), err)
|
log.Printf("error fetching %s packages: %v", h.Name(), err)
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// homebrew_test.go
|
package packagemanager
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,13 +17,13 @@ func TestHomebrewManager_InstallManager(t *testing.T) {
|
||||||
hm := &HomebrewManager{}
|
hm := &HomebrewManager{}
|
||||||
|
|
||||||
// Mock exec.LookPath and executeShellCommand
|
// Mock exec.LookPath and executeShellCommand
|
||||||
execLookPath = func(file string) (string, error) {
|
shell.ExecLookPath = func(file string) (string, error) {
|
||||||
if file == "brew" {
|
if file == "brew" {
|
||||||
return "/usr/local/bin/brew", nil
|
return "/usr/local/bin/brew", nil
|
||||||
}
|
}
|
||||||
return "", exec.ErrNotFound
|
return "", exec.ErrNotFound
|
||||||
}
|
}
|
||||||
defer func() { execLookPath = exec.LookPath }()
|
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||||
|
|
||||||
if err := hm.InstallManager(); err != nil {
|
if err := hm.InstallManager(); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -34,10 +34,10 @@ func TestHomebrewManager_InstallPackage(t *testing.T) {
|
||||||
hm := &HomebrewManager{}
|
hm := &HomebrewManager{}
|
||||||
|
|
||||||
// Mock exec.Command
|
// Mock exec.Command
|
||||||
execCommand = func(name string, arg ...string) *exec.Cmd {
|
shell.ExecCommand = func(name string, arg ...string) *exec.Cmd {
|
||||||
return exec.Command("echo", "mocked brew install")
|
return exec.Command("echo", "mocked brew install")
|
||||||
}
|
}
|
||||||
defer func() { execCommand = exec.Command }()
|
defer func() { shell.ExecCommand = exec.Command }()
|
||||||
|
|
||||||
if err := hm.InstallPackage("test-package"); err != nil {
|
if err := hm.InstallPackage("test-package"); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -1,27 +1,26 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OSManager struct {
|
type OSManager struct {
|
||||||
OS *OS
|
OS *OS
|
||||||
SudoPassword string
|
SudoPassword string
|
||||||
Packages []string
|
|
||||||
Model model
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOSManager(os *OS, sudoPassword string, packages []string) *OSManager {
|
func NewOSManager(sudoPassword string) *OSManager {
|
||||||
|
os, err := GetLinuxDistribution()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error geting os information: %v", err)
|
||||||
|
}
|
||||||
return &OSManager{
|
return &OSManager{
|
||||||
OS: os,
|
OS: os,
|
||||||
SudoPassword: sudoPassword,
|
SudoPassword: sudoPassword,
|
||||||
Packages: packages,
|
|
||||||
Model: newModel(packages, sudoPassword, os),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,42 +31,39 @@ func (o *OSManager) Name() string {
|
||||||
func (o *OSManager) InstallManager() error { return nil }
|
func (o *OSManager) InstallManager() error { return nil }
|
||||||
|
|
||||||
func (o *OSManager) Install(packages []string) error {
|
func (o *OSManager) Install(packages []string) error {
|
||||||
o.Packages = packages
|
if len(packages) == 0 {
|
||||||
o.Model = newModel(packages, o.SudoPassword, o.OS)
|
return nil
|
||||||
|
}
|
||||||
p := tea.NewProgram(o.Model)
|
err := InstallWithProgress(o, packages)
|
||||||
_, err := p.Run()
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSManager) InstallPackage(pkg string) error {
|
func (o *OSManager) InstallPackage(pkg string) error {
|
||||||
return installPackage(o.OS.InstallCommand, pkg, o.SudoPassword)
|
return InstallPackage(o.OS.InstallCommand, pkg, o.SudoPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSManager) InstallBuildEssentials() error {
|
func (o *OSManager) InstallBuildEssentials() error {
|
||||||
return installBuildEssentials(o.OS, o.SudoPassword)
|
return InstallBuildEssentials(o.OS, o.SudoPassword)
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OSManager) InstallSpecialSoftware() error {
|
|
||||||
return o.Model.installSpecialSoftware()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSManager) RemovePackage(pkg string) error {
|
func (o *OSManager) RemovePackage(pkg string) error {
|
||||||
fullCmd := fmt.Sprintf("%s %s", o.OS.RemoveCommand, pkg)
|
fullCmd := fmt.Sprintf("%s %s", o.OS.RemoveCommand, pkg)
|
||||||
command := execCommand("sudo", "-S", "sh", "-c", fullCmd)
|
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
|
||||||
command.Stdin = strings.NewReader(o.SudoPassword + "\n")
|
command.Stdin = strings.NewReader(o.SudoPassword + "\n")
|
||||||
return command.Run()
|
return command.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSManager) SearchPackage(pkg string) []string {
|
func (o *OSManager) SearchPackage(pkg string) []string {
|
||||||
|
|
||||||
cmdParts := strings.Fields(o.OS.SearchCommand)
|
cmdParts := strings.Fields(o.OS.SearchCommand)
|
||||||
if len(cmdParts) == 0 {
|
if len(cmdParts) == 0 {
|
||||||
log.Printf("Invalid search command for OS package manager")
|
log.Printf("Invalid search command for OS package manager")
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := execCommand(cmdParts[0], append(cmdParts[1:], pkg)...)
|
cmd := shell.ExecCommand(cmdParts[0], append(cmdParts[1:], pkg)...)
|
||||||
packages, err := cmd.Output()
|
packages, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error fetching %s packages: %v", o.OS.PackageManager, err)
|
log.Printf("Error fetching %s packages: %v", o.OS.PackageManager, err)
|
||||||
|
|
@ -127,7 +123,7 @@ func parseOsRelease(osRelease string) *OS {
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLinuxDistribution() (*OS, error) {
|
func GetLinuxDistribution() (*OS, error) {
|
||||||
_, err := os.Stat("/etc/os-release")
|
_, err := os.Stat("/etc/os-release")
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("unable to read system information")
|
return nil, fmt.Errorf("unable to read system information")
|
||||||
|
|
@ -155,7 +151,7 @@ func (os *OS) getPackageManager() error {
|
||||||
"pacman",
|
"pacman",
|
||||||
}
|
}
|
||||||
for _, pmname := range pmcommands {
|
for _, pmname := range pmcommands {
|
||||||
_, err := execLookPath(pmname)
|
_, err := shell.ExecLookPath(pmname)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
os.PackageManager = pmname
|
os.PackageManager = pmname
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -213,7 +209,7 @@ func (os *OS) getDeleteCommand() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func installBuildEssentials(os *OS, sudoPassword string) error {
|
func InstallBuildEssentials(os *OS, sudoPassword string) error {
|
||||||
var command string
|
var command string
|
||||||
switch os.PackageManager {
|
switch os.PackageManager {
|
||||||
case "pacman":
|
case "pacman":
|
||||||
|
|
@ -227,8 +223,8 @@ func installBuildEssentials(os *OS, sudoPassword string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Installiere Build Essentials für %s...\n", os.Name)
|
fmt.Printf("Installiere Build Essentials für %s...\n", os.Name)
|
||||||
if err := installPackage(command, "", sudoPassword); err != nil {
|
if err := InstallPackage(command, "", sudoPassword); err != nil {
|
||||||
return fmt.Errorf("fehler bei der Installation der Build Essentials: %v", err)
|
return fmt.Errorf("error installing Build Essentials: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -1,26 +1,20 @@
|
||||||
// osmanager_test.go
|
package packagemanager
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewOSManager(t *testing.T) {
|
func TestNewOSManager(t *testing.T) {
|
||||||
os := &OS{ID: "ubuntu", PackageManager: "apt"}
|
|
||||||
sudoPassword := "testpassword"
|
sudoPassword := "testpassword"
|
||||||
packages := []string{"git", "curl"}
|
|
||||||
|
|
||||||
manager := NewOSManager(os, sudoPassword, packages)
|
manager := NewOSManager(sudoPassword)
|
||||||
|
|
||||||
if manager.OS != os {
|
if manager.OS == nil {
|
||||||
t.Errorf("Expected OS to be %v, got %v", os, manager.OS)
|
t.Error("Expected OS to be non-nil")
|
||||||
}
|
}
|
||||||
if manager.SudoPassword != sudoPassword {
|
if manager.SudoPassword != sudoPassword {
|
||||||
t.Errorf("Expected SudoPassword to be %s, got %s", sudoPassword, manager.SudoPassword)
|
t.Errorf("Expected SudoPassword to be %s, got %s", sudoPassword, manager.SudoPassword)
|
||||||
}
|
}
|
||||||
if len(manager.Packages) != len(packages) {
|
|
||||||
t.Errorf("Expected Packages length to be %d, got %d", len(packages), len(manager.Packages))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOSManagerName(t *testing.T) {
|
func TestOSManagerName(t *testing.T) {
|
||||||
|
|
@ -47,4 +41,13 @@ 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Packages struct {
|
type Packages struct {
|
||||||
|
|
@ -10,26 +12,17 @@ type Packages struct {
|
||||||
NonHeadless []string `mapstructure:"non_headless"`
|
NonHeadless []string `mapstructure:"non_headless"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func installPackage(cmd, pkg, sudoPassword string) error {
|
func InstallPackage(cmd, pkg, sudoPassword string) error {
|
||||||
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
|
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
|
||||||
command := execCommand("sudo", "-S", "sh", "-c", fullCmd)
|
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
|
||||||
command.Stdin = strings.NewReader(sudoPassword + "\n")
|
command.Stdin = strings.NewReader(sudoPassword + "\n")
|
||||||
output, err := command.CombinedOutput()
|
output, err := command.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(string(output), "not found") || strings.Contains(string(output), "no matching package") || strings.Contains(string(output), "Keine Übereinstimmung") || strings.Contains(string(output), "Ziel nicht gefunden") {
|
if strings.Contains(string(output), "not found") || strings.Contains(string(output), "no matching package") || strings.Contains(string(output), "Keine Übereinstimmung") || strings.Contains(string(output), "Ziel nicht gefunden") {
|
||||||
unavailablePackages = append(unavailablePackages, pkg)
|
log.Printf("Package %s not available\n", pkg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to install %s: %v\n%s", pkg, err, string(output))
|
return fmt.Errorf("failed to install %s: %v\n%s", pkg, err, string(output))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printUnavailablePackages() {
|
|
||||||
if len(unavailablePackages) > 0 {
|
|
||||||
fmt.Println("\nFolgende Pakete waren nicht verfügbar:")
|
|
||||||
for _, pkg := range unavailablePackages {
|
|
||||||
fmt.Printf("- %s\n", pkg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
type PackageManager interface {
|
type PackageManager interface {
|
||||||
Install(packages []string) error
|
Install(packages []string) error
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
package main
|
package packagemanager
|
||||||
|
|
||||||
|
import "system_setup_tool/internal/shell"
|
||||||
|
|
||||||
type PipxManager struct{}
|
type PipxManager struct{}
|
||||||
|
|
||||||
|
|
@ -7,7 +9,7 @@ func (p *PipxManager) Install(packages []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := installWithProgress(p, packages)
|
err := InstallWithProgress(p, packages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -19,25 +21,25 @@ func (p *PipxManager) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PipxManager) InstallManager() error {
|
func (p *PipxManager) InstallManager() error {
|
||||||
if _, err := execLookPath("brew"); err != nil {
|
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||||
installHomebrew()
|
installHomebrew()
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := execLookPath("pipx"); err == nil {
|
if _, err := shell.ExecLookPath("pipx"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := execCommand("brew", "install", "pipx")
|
cmd := shell.ExecCommand("brew", "install", "pipx")
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PipxManager) InstallPackage(pkg string) error {
|
func (p *PipxManager) InstallPackage(pkg string) error {
|
||||||
cmd := execCommand("pipx", "install", pkg)
|
cmd := shell.ExecCommand("pipx", "install", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PipxManager) RemovePackage(pkg string) error {
|
func (p *PipxManager) RemovePackage(pkg string) error {
|
||||||
cmd := execCommand("pipx", "uninstall", pkg)
|
cmd := shell.ExecCommand("pipx", "uninstall", pkg)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// pipx_test.go
|
package packagemanager
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,13 +17,13 @@ func TestPipxManager_InstallManager(t *testing.T) {
|
||||||
pm := &PipxManager{}
|
pm := &PipxManager{}
|
||||||
|
|
||||||
// Mock exec.LookPath
|
// Mock exec.LookPath
|
||||||
execLookPath = func(file string) (string, error) {
|
shell.ExecLookPath = func(file string) (string, error) {
|
||||||
if file == "pipx" {
|
if file == "pipx" {
|
||||||
return "/usr/bin/pipx", nil
|
return "/usr/bin/pipx", nil
|
||||||
}
|
}
|
||||||
return "", exec.ErrNotFound
|
return "", exec.ErrNotFound
|
||||||
}
|
}
|
||||||
defer func() { execLookPath = exec.LookPath }()
|
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||||
|
|
||||||
if err := pm.InstallManager(); err != nil {
|
if err := pm.InstallManager(); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
|
@ -34,10 +34,10 @@ func TestPipxManager_InstallPackage(t *testing.T) {
|
||||||
pm := &PipxManager{}
|
pm := &PipxManager{}
|
||||||
|
|
||||||
// Mock exec.Command
|
// Mock exec.Command
|
||||||
execCommand = func(name string, arg ...string) *exec.Cmd {
|
shell.ExecCommand = func(name string, arg ...string) *exec.Cmd {
|
||||||
return exec.Command("echo", "mocked pipx install")
|
return exec.Command("echo", "mocked pipx install")
|
||||||
}
|
}
|
||||||
defer func() { execCommand = exec.Command }()
|
defer func() { shell.ExecCommand = exec.Command }()
|
||||||
|
|
||||||
if err := pm.InstallPackage("test-package"); err != nil {
|
if err := pm.InstallPackage("test-package"); err != nil {
|
||||||
t.Errorf("Expected no error, got %v", err)
|
t.Errorf("Expected no error, got %v", err)
|
||||||
19
packagemanager/utils.go
Normal file
19
packagemanager/utils.go
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package packagemanager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/schollz/progressbar/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InstallWithProgress(manager PackageManager, packages []string) error {
|
||||||
|
bar := progressbar.Default(int64(len(packages)), "Installiere "+manager.Name()+"-Pakete...")
|
||||||
|
for _, pkg := range packages {
|
||||||
|
err := manager.InstallPackage(pkg)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("\nError installing %s: %v\n", pkg, err)
|
||||||
|
}
|
||||||
|
bar.Add(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
146
tui.go
146
tui.go
|
|
@ -1,146 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/huh"
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
|
||||||
"github.com/mitchellh/mapstructure"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
currentPkgNameStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("211"))
|
|
||||||
doneStyle = lipgloss.NewStyle().Margin(1, 2)
|
|
||||||
checkMark = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓")
|
|
||||||
unavailablePackages []string
|
|
||||||
)
|
|
||||||
|
|
||||||
type installedPkgMsg string
|
|
||||||
|
|
||||||
func run(cmd *cobra.Command, args []string) {
|
|
||||||
os, err := getLinuxDistribution()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sudoPassword, err := getSudoPassword()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var cfg Config
|
|
||||||
if err := viper.Unmarshal(&cfg); err != nil {
|
|
||||||
log.Fatalf("Fehler beim Lesen der Konfiguration: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
form := huh.NewForm(
|
|
||||||
huh.NewGroup(
|
|
||||||
huh.NewConfirm().
|
|
||||||
Title("Möchten Sie eine headless Installation durchführen?").
|
|
||||||
Value(&cfg.Headless),
|
|
||||||
),
|
|
||||||
).WithTheme(huh.ThemeCatppuccin())
|
|
||||||
|
|
||||||
if err := form.Run(); err != nil {
|
|
||||||
log.Fatalf("Fehler bei der Benutzerabfrage: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
unavailablePackages = []string{}
|
|
||||||
osManager := NewOSManager(os, sudoPassword, cfg.Packages.Headless)
|
|
||||||
|
|
||||||
if err := osManager.Install(cfg.Packages.Headless); err != nil {
|
|
||||||
log.Printf("Warnung bei der Installation der Headless-Pakete: %v", err)
|
|
||||||
}
|
|
||||||
if !cfg.Headless {
|
|
||||||
if err := osManager.Install(cfg.Packages.NonHeadless); err != nil {
|
|
||||||
log.Printf("Warnung bei der Installation der Non-Headless-Pakete: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printUnavailablePackages()
|
|
||||||
|
|
||||||
var installBuild bool
|
|
||||||
form = huh.NewForm(
|
|
||||||
huh.NewGroup(
|
|
||||||
huh.NewConfirm().
|
|
||||||
Title("Möchten Sie die Build Essentials installieren?").
|
|
||||||
Value(&installBuild),
|
|
||||||
),
|
|
||||||
).WithTheme(huh.ThemeCatppuccin())
|
|
||||||
|
|
||||||
err = form.Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if installBuild {
|
|
||||||
if err := osManager.InstallBuildEssentials(); err != nil {
|
|
||||||
log.Printf("Warnung: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var installShellExtensions bool
|
|
||||||
form = huh.NewForm(
|
|
||||||
huh.NewGroup(
|
|
||||||
huh.NewConfirm().
|
|
||||||
Title("Möchten Sie die Shell-Extensions installieren?").
|
|
||||||
Value(&installShellExtensions),
|
|
||||||
),
|
|
||||||
).WithTheme(huh.ThemeCatppuccin())
|
|
||||||
|
|
||||||
err = form.Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if installShellExtensions {
|
|
||||||
if err := osManager.InstallSpecialSoftware(); err != nil {
|
|
||||||
log.Printf("Warnung bei der Installation spezieller Software: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, config := range cfg.PackageManagers {
|
|
||||||
if config.Enable {
|
|
||||||
var manager PackageManager
|
|
||||||
switch name {
|
|
||||||
case "homebrew":
|
|
||||||
manager = &HomebrewManager{}
|
|
||||||
case "go":
|
|
||||||
manager = &GolangManager{}
|
|
||||||
case "cargo":
|
|
||||||
manager = &CargoManager{}
|
|
||||||
case "pipx":
|
|
||||||
manager = &PipxManager{}
|
|
||||||
case "flatpak":
|
|
||||||
flatpakConfig := FlatpakConfig{}
|
|
||||||
if err := mapstructure.Decode(config, &flatpakConfig); err != nil {
|
|
||||||
log.Printf("Fehler beim Dekodieren der Flatpak-Konfiguration: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
manager = &FlatpakManager{
|
|
||||||
OS: os,
|
|
||||||
SudoPassword: sudoPassword,
|
|
||||||
Config: flatpakConfig,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.Printf("Unbekannter Paketmanager: %s", name)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := manager.InstallManager(); err != nil {
|
|
||||||
log.Printf("Warnung Packagemanager %s nicht vorhanden und konnte nicht installiert werden: %v", manager.Name(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := manager.Install(config.Packages); err != nil {
|
|
||||||
log.Printf("Warnung bei %s-Paketen: %v", manager.Name(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cfg.Dotfiles.Enable {
|
|
||||||
fmt.Println("\nKonfiguriere Dotfiles...")
|
|
||||||
if err := setupDotfiles(cfg.Dotfiles); err != nil {
|
|
||||||
log.Printf("Warnung bei Dotfiles-Setup: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
tui/tui.go
Normal file
115
tui/tui.go
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
package tui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"system_setup_tool/config"
|
||||||
|
"system_setup_tool/dotfiles"
|
||||||
|
"system_setup_tool/utils"
|
||||||
|
|
||||||
|
pm "system_setup_tool/packagemanager"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/huh"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type installedPkgMsg string
|
||||||
|
|
||||||
|
func Run(cmd *cobra.Command, args []string) {
|
||||||
|
sudoPassword, err := utils.GetSudoPassword()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg config.Config
|
||||||
|
if err := viper.Unmarshal(&cfg); err != nil {
|
||||||
|
log.Fatalf("Fehler beim Lesen der Konfiguration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// form := huh.NewForm(
|
||||||
|
// huh.NewGroup(
|
||||||
|
// huh.NewConfirm().
|
||||||
|
// Title("Möchten Sie eine headless Installation durchführen?").
|
||||||
|
// Value(&cfg.Headless),
|
||||||
|
// ),
|
||||||
|
// ).WithTheme(huh.ThemeCatppuccin())
|
||||||
|
//
|
||||||
|
// if err := form.Run(); err != nil {
|
||||||
|
// log.Fatalf("Fehler bei der Benutzerabfrage: %v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// osManager := pm.NewOSManager(sudoPassword)
|
||||||
|
//
|
||||||
|
// if err := osManager.Install(cfg.Packages.Headless); err != nil {
|
||||||
|
// log.Printf("Warnung bei der Installation der Headless-Pakete: %v", err)
|
||||||
|
// }
|
||||||
|
// if !cfg.Headless {
|
||||||
|
// if err := osManager.Install(cfg.Packages.NonHeadless); err != nil {
|
||||||
|
// log.Printf("Warnung bei der Installation der Non-Headless-Pakete: %v", err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
for name, config := range cfg.PackageManagers {
|
||||||
|
if config.Enable {
|
||||||
|
var manager pm.PackageManager
|
||||||
|
switch name {
|
||||||
|
case "os":
|
||||||
|
manager = pm.NewOSManager(sudoPassword)
|
||||||
|
case "homebrew":
|
||||||
|
manager = &pm.HomebrewManager{}
|
||||||
|
case "go":
|
||||||
|
manager = &pm.GolangManager{}
|
||||||
|
case "cargo":
|
||||||
|
manager = &pm.CargoManager{}
|
||||||
|
case "pipx":
|
||||||
|
manager = &pm.PipxManager{}
|
||||||
|
case "flatpak":
|
||||||
|
flatpakConfig := pm.FlatpakConfig{}
|
||||||
|
if err := mapstructure.Decode(config, &flatpakConfig); err != nil {
|
||||||
|
log.Printf("error decoding flatpak config: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
manager = pm.NewFlatpakManager(sudoPassword, flatpakConfig)
|
||||||
|
default:
|
||||||
|
log.Printf("unknown packagemanager: %s", name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := manager.InstallManager(); err != nil {
|
||||||
|
log.Printf("warning packagemanager %s not installed and could not be installed: %v", manager.Name(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.Install(config.Packages); err != nil {
|
||||||
|
log.Printf("warning at %s-packages: %v", manager.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
osManager := pm.NewOSManager(sudoPassword)
|
||||||
|
var installBuild bool
|
||||||
|
form := huh.NewForm(
|
||||||
|
huh.NewGroup(
|
||||||
|
huh.NewConfirm().
|
||||||
|
Title("Möchten Sie die Build Essentials installieren?").
|
||||||
|
Value(&installBuild),
|
||||||
|
),
|
||||||
|
).WithTheme(huh.ThemeCatppuccin())
|
||||||
|
|
||||||
|
err = form.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if installBuild {
|
||||||
|
if err := osManager.InstallBuildEssentials(); err != nil {
|
||||||
|
log.Printf("Warnung: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.Dotfiles.Enable {
|
||||||
|
fmt.Println("\nconfiguring dotfiles...")
|
||||||
|
if err := dotfiles.SetupDotfiles(cfg.Dotfiles); err != nil {
|
||||||
|
log.Printf("Warnung bei Dotfiles-Setup: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
utils.go
64
utils.go
|
|
@ -1,64 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/huh"
|
|
||||||
"github.com/schollz/progressbar/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
execCommand = exec.Command
|
|
||||||
execLookPath = exec.LookPath
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func executeShellCommand(command string, env string) error {
|
|
||||||
cmd := execCommand("bash", "-c", command)
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
cmd.Env = append(cmd.Env, env)
|
|
||||||
output, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("befehl fehlgeschlagen: %v\nAusgabe: %s", err, output)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func installWithProgress(manager PackageManager, packages []string) error {
|
|
||||||
bar := progressbar.Default(int64(len(packages)), "Installiere "+manager.Name()+"-Pakete...")
|
|
||||||
for _, pkg := range packages {
|
|
||||||
err := manager.InstallPackage(pkg)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("\nError installing %s: %v\n", pkg, err)
|
|
||||||
}
|
|
||||||
bar.Add(1)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
32
utils/utils.go
Normal file
32
utils/utils.go
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
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
|
||||||
|
}
|
||||||
40
utils/utils_test.go
Normal file
40
utils/utils_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"system_setup_tool/internal/shell"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMax(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
a, b, want int
|
||||||
|
}{
|
||||||
|
{1, 2, 2},
|
||||||
|
{5, 3, 5},
|
||||||
|
{0, 0, 0},
|
||||||
|
{-1, -5, -1},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := max(tt.a, tt.b)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("max(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecuteShellCommand(t *testing.T) {
|
||||||
|
// Mock execCommand
|
||||||
|
oldExecCommand := shell.ExecCommand
|
||||||
|
defer func() { shell.ExecCommand = oldExecCommand }()
|
||||||
|
|
||||||
|
shell.ExecCommand = func(command string, args ...string) *exec.Cmd {
|
||||||
|
return exec.Command("echo", "mocked command")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := shell.ExecuteShellCommand("test command", "TEST_ENV=value")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("executeShellCommand() error = %v; want nil", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMax(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
a, b, want int
|
|
||||||
}{
|
|
||||||
{1, 2, 2},
|
|
||||||
{5, 3, 5},
|
|
||||||
{0, 0, 0},
|
|
||||||
{-1, -5, -1},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
got := max(tt.a, tt.b)
|
|
||||||
if got != tt.want {
|
|
||||||
t.Errorf("max(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExecuteShellCommand(t *testing.T) {
|
|
||||||
// Mock execCommand
|
|
||||||
oldExecCommand := execCommand
|
|
||||||
defer func() { execCommand = oldExecCommand }()
|
|
||||||
|
|
||||||
execCommand = func(command string, args ...string) *exec.Cmd {
|
|
||||||
return exec.Command("echo", "mocked command")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := executeShellCommand("test command", "TEST_ENV=value")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("executeShellCommand() error = %v; want nil", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallWithProgress(t *testing.T) {
|
|
||||||
mockManager := &MockPackageManager{
|
|
||||||
packages: []string{"pkg1", "pkg2"},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := installWithProgress(mockManager, mockManager.packages)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("installWithProgress() error = %v; want nil", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(mockManager.installedPackages) != len(mockManager.packages) {
|
|
||||||
t.Errorf("installWithProgress() installed %d packages; want %d", len(mockManager.installedPackages), len(mockManager.packages))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MockPackageManager struct {
|
|
||||||
packages []string
|
|
||||||
installedPackages []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) Install(packages []string) error {
|
|
||||||
m.installedPackages = append(m.installedPackages, packages...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) InstallPackage(pkg string) error {
|
|
||||||
m.installedPackages = append(m.installedPackages, pkg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) InstallManager() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) Name() string {
|
|
||||||
return "MockManager"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) RemovePackage(pkg string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockPackageManager) SearchPackage(pkg string) []string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue