Merge branch 'dev/clean-up-repo-structure' into development
* dev/clean-up-repo-structure: refactor: move main.go back to project root refactor: seperate files, function and structs into seperate packages
This commit is contained in:
commit
a90c3d52f9
37 changed files with 547 additions and 677 deletions
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
version: 2
|
||||
|
||||
env:
|
||||
- GITHUB_TOKEN={{ .Env.CODEBERG_TOKEN }}
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"system_setup_tool/tui"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "system_setup_tool",
|
||||
Short: "Installs packages based on TOML configuration",
|
||||
Run: run,
|
||||
Run: tui.Run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
rootCmd.PersistentFlags().StringP("config", "c", "", "Path to the configuration file")
|
||||
viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
|
||||
RootCmd.PersistentFlags().StringP("config", "c", "", "Path to the configuration file")
|
||||
viper.BindPFlag("config", RootCmd.PersistentFlags().Lookup("config"))
|
||||
|
||||
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)")
|
||||
|
|
@ -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)")
|
||||
|
||||
packageCmd.AddCommand(addCmd, deleteCmd, showCmd, enableCmd)
|
||||
rootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd)
|
||||
RootCmd.AddCommand(packageCmd, searchCmd, installCmd, removeCmd)
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"system_setup_tool/utils"
|
||||
|
||||
pm "system_setup_tool/packagemanager"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -14,29 +17,25 @@ var installCmd = &cobra.Command{
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
packageName := args[0]
|
||||
managerName, _ := cmd.Flags().GetString("manager")
|
||||
var manager PackageManager
|
||||
var manager pm.PackageManager
|
||||
switch managerName {
|
||||
case "os":
|
||||
opSys, err := getLinuxDistribution()
|
||||
if err != nil {
|
||||
log.Printf("error getting OS information: %v", err)
|
||||
}
|
||||
sudoPassword, err := getSudoPassword()
|
||||
sudoPassword, err := utils.GetSudoPassword()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
osManager := NewOSManager(opSys, sudoPassword, []string{packageName})
|
||||
osManager := pm.NewOSManager(sudoPassword)
|
||||
if err := osManager.Install([]string{packageName}); err != nil {
|
||||
log.Printf("error: %v\n", err)
|
||||
}
|
||||
case "homebrew":
|
||||
manager = &HomebrewManager{}
|
||||
manager = &pm.HomebrewManager{}
|
||||
case "cargo":
|
||||
manager = &CargoManager{}
|
||||
manager = &pm.CargoManager{}
|
||||
case "pipx":
|
||||
manager = &PipxManager{}
|
||||
manager = &pm.PipxManager{}
|
||||
case "flatpak":
|
||||
manager = &FlatpakManager{}
|
||||
manager = &pm.FlatpakManager{}
|
||||
default:
|
||||
fmt.Println("No PackageManager found")
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
"system_setup_tool/utils"
|
||||
|
||||
pm "system_setup_tool/packagemanager"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -13,29 +16,25 @@ var removeCmd = &cobra.Command{
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
packageName := args[0]
|
||||
managerName, _ := cmd.Flags().GetString("manager")
|
||||
var manager PackageManager
|
||||
var manager pm.PackageManager
|
||||
switch managerName {
|
||||
case "os":
|
||||
opSys, err := getLinuxDistribution()
|
||||
if err != nil {
|
||||
log.Printf("error getting OS information: %v", err)
|
||||
}
|
||||
sudoPassword, err := getSudoPassword()
|
||||
sudoPassword, err := utils.GetSudoPassword()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
osManager := NewOSManager(opSys, sudoPassword, []string{packageName})
|
||||
osManager := pm.NewOSManager(sudoPassword)
|
||||
if err := osManager.Install([]string{packageName}); err != nil {
|
||||
log.Printf("error: %v\n", err)
|
||||
}
|
||||
case "homebrew":
|
||||
manager = &HomebrewManager{}
|
||||
manager = &pm.HomebrewManager{}
|
||||
case "cargo":
|
||||
manager = &CargoManager{}
|
||||
manager = &pm.CargoManager{}
|
||||
case "pipx":
|
||||
manager = &PipxManager{}
|
||||
manager = &pm.PipxManager{}
|
||||
case "flatpak":
|
||||
manager = &FlatpakManager{}
|
||||
manager = &pm.FlatpakManager{}
|
||||
default:
|
||||
}
|
||||
if err := manager.RemovePackage(packageName); err != nil {
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
pm "system_setup_tool/packagemanager"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -18,16 +19,11 @@ var searchCmd = &cobra.Command{
|
|||
if managerName == "os" {
|
||||
managerName = "OS Package Manager"
|
||||
}
|
||||
opSys, err := getLinuxDistribution()
|
||||
if err != nil {
|
||||
log.Printf("error getting OS information: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
managers := []PackageManager{
|
||||
NewOSManager(opSys, "", nil),
|
||||
&HomebrewManager{},
|
||||
&FlatpakManager{},
|
||||
managers := []pm.PackageManager{
|
||||
pm.NewOSManager(""),
|
||||
&pm.HomebrewManager{},
|
||||
&pm.FlatpakManager{},
|
||||
}
|
||||
|
||||
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())
|
||||
results := manager.SearchPackage(packageName)
|
||||
displayResults(results, manager.Name())
|
||||
99
config.toml
99
config.toml
|
|
@ -12,20 +12,107 @@ 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']
|
||||
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']
|
||||
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 = ['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]
|
||||
enable = true
|
||||
packages = ['euporie']
|
||||
|
||||
[packages]
|
||||
headless = ['git', 'curl', 'wget', 'biber', 'bear', 'docker', 'docker-compose', 'zsh', 'npm', 'task', 'tree-sitter-cli', 'python3-pip', 'latexmk', 'luarocks']
|
||||
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']
|
||||
[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',
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
package main
|
||||
package config
|
||||
|
||||
import (
|
||||
"system_setup_tool/dotfiles"
|
||||
pm "system_setup_tool/packagemanager"
|
||||
)
|
||||
|
||||
type PackageManagerConfig struct {
|
||||
Enable bool `mapstructure:"enable"`
|
||||
|
|
@ -7,7 +12,7 @@ type PackageManagerConfig struct {
|
|||
|
||||
type Config struct {
|
||||
Headless bool `mapstructure:"headless"`
|
||||
Packages Packages `mapstructure:"packages"`
|
||||
Packages pm.Packages `mapstructure:"packages"`
|
||||
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
|
||||
|
||||
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/lipgloss v1.0.0
|
||||
github.com/magefile/mage v1.15.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/schollz/progressbar/v3 v3.18.0
|
||||
|
|
@ -18,7 +15,9 @@ require (
|
|||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // 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/exp/strings v0.0.0-20240722160745-212f7b056ed0 // 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/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
|
||||
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/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
|
||||
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
|
||||
// +build mage
|
||||
|
||||
package main
|
||||
|
||||
|
|
|
|||
3
main.go
3
main.go
|
|
@ -3,10 +3,11 @@ package main
|
|||
import (
|
||||
"log"
|
||||
"os"
|
||||
"system_setup_tool/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
if err := cmd.RootCmd.Execute(); err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
|
|||
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{}
|
||||
|
||||
|
|
@ -6,7 +8,7 @@ func (c *CargoManager) Install(packages []string) error {
|
|||
if len(packages) == 0 {
|
||||
return nil
|
||||
}
|
||||
err := installWithProgress(c, packages)
|
||||
err := InstallWithProgress(c, packages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -18,25 +20,25 @@ func (c *CargoManager) Name() string {
|
|||
}
|
||||
|
||||
func (c *CargoManager) InstallManager() error {
|
||||
if _, err := execLookPath("brew"); err != nil {
|
||||
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||
installHomebrew()
|
||||
}
|
||||
|
||||
if _, err := execLookPath("cargo"); err == nil {
|
||||
if _, err := shell.ExecLookPath("cargo"); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := execCommand("brew", "install", "rust")
|
||||
cmd := shell.ExecCommand("brew", "install", "rust")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (c *CargoManager) InstallPackage(pkg string) error {
|
||||
cmd := execCommand("cargo", "install", pkg)
|
||||
cmd := shell.ExecCommand("cargo", "install", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (c *CargoManager) RemovePackage(pkg string) error {
|
||||
cmd := execCommand("cargo", "uninstall", pkg)
|
||||
cmd := shell.ExecCommand("cargo", "uninstall", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
// cargo_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"system_setup_tool/internal/shell"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -17,13 +18,13 @@ func TestCargoManager_InstallManager(t *testing.T) {
|
|||
cm := &CargoManager{}
|
||||
|
||||
// Mock exec.LookPath
|
||||
execLookPath = func(file string) (string, error) {
|
||||
shell.ExecLookPath = func(file string) (string, error) {
|
||||
if file == "cargo" {
|
||||
return "/usr/bin/cargo", nil
|
||||
}
|
||||
return "", exec.ErrNotFound
|
||||
}
|
||||
defer func() { execLookPath = exec.LookPath }()
|
||||
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||
|
||||
if err := cm.InstallManager(); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -34,10 +35,10 @@ func TestCargoManager_InstallPackage(t *testing.T) {
|
|||
cm := &CargoManager{}
|
||||
|
||||
// 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")
|
||||
}
|
||||
defer func() { execCommand = exec.Command }()
|
||||
defer func() { shell.ExecCommand = exec.Command }()
|
||||
|
||||
if err := cm.InstallPackage("test-package"); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"system_setup_tool/internal/shell"
|
||||
)
|
||||
|
||||
type FlatpakManager struct {
|
||||
|
|
@ -13,11 +13,23 @@ type FlatpakManager struct {
|
|||
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 {
|
||||
if len(packages) == 0 {
|
||||
return nil
|
||||
}
|
||||
err := installWithProgress(f, packages)
|
||||
err := InstallWithProgress(f, packages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -29,7 +41,7 @@ func (f *FlatpakManager) Name() string {
|
|||
}
|
||||
|
||||
func (f *FlatpakManager) InstallManager() error {
|
||||
if _, err := exec.LookPath("flatpak"); err == nil {
|
||||
if _, err := shell.ExecLookPath("flatpak"); err == 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)
|
||||
}
|
||||
|
||||
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 nil
|
||||
|
|
@ -77,7 +89,7 @@ func installFlatpak(os *OS, sudoPassword string) error {
|
|||
|
||||
func addFlatpakRemotes(remotes []Remote) error {
|
||||
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 {
|
||||
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 {
|
||||
cmd := execCommand("flatpak", "install", "-y", pkg)
|
||||
cmd := shell.ExecCommand("flatpak", "install", "-y", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (f *FlatpakManager) RemovePackage(pkg string) error {
|
||||
cmd := execCommand("flatpak", "uninstall", "-y", pkg)
|
||||
cmd := shell.ExecCommand("flatpak", "uninstall", "-y", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (f *FlatpakManager) SearchPackage(pkg string) []string {
|
||||
cmd := execCommand("flatpak", "search", pkg)
|
||||
cmd := shell.ExecCommand("flatpak", "search", pkg)
|
||||
packages, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Printf("error fetching %s packages: %v", f.Name(), err)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// flatpak_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"system_setup_tool/internal/shell"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -33,10 +33,10 @@ func TestFlatpakManager_InstallPackage(t *testing.T) {
|
|||
fm := &FlatpakManager{}
|
||||
|
||||
// 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")
|
||||
}
|
||||
defer func() { execCommand = exec.Command }()
|
||||
defer func() { shell.ExecCommand = exec.Command }()
|
||||
|
||||
if err := fm.InstallPackage("test-package"); err != nil {
|
||||
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{}
|
||||
|
||||
|
|
@ -6,7 +8,7 @@ func (g *GolangManager) Install(packages []string) error {
|
|||
if len(packages) == 0 {
|
||||
return nil
|
||||
}
|
||||
err := installWithProgress(g, packages)
|
||||
err := InstallWithProgress(g, packages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -18,25 +20,25 @@ func (g *GolangManager) Name() string {
|
|||
}
|
||||
|
||||
func (g *GolangManager) InstallManager() error {
|
||||
if _, err := execLookPath("brew"); err != nil {
|
||||
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||
installHomebrew()
|
||||
}
|
||||
|
||||
if _, err := execLookPath("go"); err == nil {
|
||||
if _, err := shell.ExecLookPath("go"); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := execCommand("brew", "install", "golang")
|
||||
cmd := shell.ExecCommand("brew", "install", "golang")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (g *GolangManager) InstallPackage(pkg string) error {
|
||||
cmd := execCommand("go", "install", pkg+"@latest")
|
||||
cmd := shell.ExecCommand("go", "install", pkg+"@latest")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (g *GolangManager) RemovePackage(pkg string) error {
|
||||
cmd := execCommand("go", "uninstall", pkg)
|
||||
cmd := shell.ExecCommand("go", "uninstall", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// golang_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"system_setup_tool/internal/shell"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -17,13 +17,13 @@ func TestGolangManager_InstallManager(t *testing.T) {
|
|||
gm := &GolangManager{}
|
||||
|
||||
// Mock exec.LookPath
|
||||
execLookPath = func(file string) (string, error) {
|
||||
shell.ExecLookPath = func(file string) (string, error) {
|
||||
if file == "go" {
|
||||
return "/usr/local/go/bin/go", nil
|
||||
}
|
||||
return "", exec.ErrNotFound
|
||||
}
|
||||
defer func() { execLookPath = exec.LookPath }()
|
||||
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||
|
||||
if err := gm.InstallManager(); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -34,10 +34,10 @@ func TestGolangManager_InstallPackage(t *testing.T) {
|
|||
gm := &GolangManager{}
|
||||
|
||||
// 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")
|
||||
}
|
||||
defer func() { execCommand = exec.Command }()
|
||||
defer func() { shell.ExecCommand = exec.Command }()
|
||||
|
||||
if err := gm.InstallPackage("github.com/test/package"); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"system_setup_tool/internal/shell"
|
||||
)
|
||||
|
||||
type HomebrewManager struct{}
|
||||
|
|
@ -12,7 +13,7 @@ func (h *HomebrewManager) Install(packages []string) error {
|
|||
if len(packages) == 0 {
|
||||
return nil
|
||||
}
|
||||
err := installWithProgress(h, packages)
|
||||
err := InstallWithProgress(h, packages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -24,7 +25,7 @@ func (h *HomebrewManager) Name() string {
|
|||
}
|
||||
|
||||
func (h *HomebrewManager) InstallManager() error {
|
||||
if _, err := execLookPath("brew"); err == nil {
|
||||
if _, err := shell.ExecLookPath("brew"); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ func (h *HomebrewManager) InstallManager() 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 {
|
||||
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 {
|
||||
cmd := execCommand("brew", "install", pkg)
|
||||
cmd := shell.ExecCommand("brew", "install", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (h *HomebrewManager) RemovePackage(pkg string) error {
|
||||
cmd := execCommand("brew", "uninstall", pkg)
|
||||
cmd := shell.ExecCommand("brew", "uninstall", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (h *HomebrewManager) SearchPackage(pkg string) []string {
|
||||
cmd := execCommand("brew", "search", pkg)
|
||||
cmd := shell.ExecCommand("brew", "search", pkg)
|
||||
packages, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Printf("error fetching %s packages: %v", h.Name(), err)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// homebrew_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"system_setup_tool/internal/shell"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -17,13 +17,13 @@ func TestHomebrewManager_InstallManager(t *testing.T) {
|
|||
hm := &HomebrewManager{}
|
||||
|
||||
// Mock exec.LookPath and executeShellCommand
|
||||
execLookPath = func(file string) (string, error) {
|
||||
shell.ExecLookPath = func(file string) (string, error) {
|
||||
if file == "brew" {
|
||||
return "/usr/local/bin/brew", nil
|
||||
}
|
||||
return "", exec.ErrNotFound
|
||||
}
|
||||
defer func() { execLookPath = exec.LookPath }()
|
||||
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||
|
||||
if err := hm.InstallManager(); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -34,10 +34,10 @@ func TestHomebrewManager_InstallPackage(t *testing.T) {
|
|||
hm := &HomebrewManager{}
|
||||
|
||||
// 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")
|
||||
}
|
||||
defer func() { execCommand = exec.Command }()
|
||||
defer func() { shell.ExecCommand = exec.Command }()
|
||||
|
||||
if err := hm.InstallPackage("test-package"); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -1,27 +1,26 @@
|
|||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"system_setup_tool/internal/shell"
|
||||
)
|
||||
|
||||
type OSManager struct {
|
||||
OS *OS
|
||||
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{
|
||||
OS: os,
|
||||
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) Install(packages []string) error {
|
||||
o.Packages = packages
|
||||
o.Model = newModel(packages, o.SudoPassword, o.OS)
|
||||
|
||||
p := tea.NewProgram(o.Model)
|
||||
_, err := p.Run()
|
||||
return err
|
||||
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)
|
||||
return InstallPackage(o.OS.InstallCommand, pkg, o.SudoPassword)
|
||||
}
|
||||
|
||||
func (o *OSManager) InstallBuildEssentials() error {
|
||||
return installBuildEssentials(o.OS, o.SudoPassword)
|
||||
}
|
||||
|
||||
func (o *OSManager) InstallSpecialSoftware() error {
|
||||
return o.Model.installSpecialSoftware()
|
||||
return InstallBuildEssentials(o.OS, o.SudoPassword)
|
||||
}
|
||||
|
||||
func (o *OSManager) RemovePackage(pkg string) error {
|
||||
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")
|
||||
return command.Run()
|
||||
}
|
||||
|
||||
func (o *OSManager) SearchPackage(pkg string) []string {
|
||||
|
||||
cmdParts := strings.Fields(o.OS.SearchCommand)
|
||||
if len(cmdParts) == 0 {
|
||||
log.Printf("Invalid search command for OS package manager")
|
||||
return []string{}
|
||||
}
|
||||
|
||||
cmd := execCommand(cmdParts[0], append(cmdParts[1:], pkg)...)
|
||||
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)
|
||||
|
|
@ -127,7 +123,7 @@ func parseOsRelease(osRelease string) *OS {
|
|||
return &result
|
||||
}
|
||||
|
||||
func getLinuxDistribution() (*OS, error) {
|
||||
func GetLinuxDistribution() (*OS, error) {
|
||||
_, err := os.Stat("/etc/os-release")
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("unable to read system information")
|
||||
|
|
@ -155,7 +151,7 @@ func (os *OS) getPackageManager() error {
|
|||
"pacman",
|
||||
}
|
||||
for _, pmname := range pmcommands {
|
||||
_, err := execLookPath(pmname)
|
||||
_, err := shell.ExecLookPath(pmname)
|
||||
if err == nil {
|
||||
os.PackageManager = pmname
|
||||
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
|
||||
switch os.PackageManager {
|
||||
case "pacman":
|
||||
|
|
@ -227,8 +223,8 @@ func installBuildEssentials(os *OS, sudoPassword string) error {
|
|||
}
|
||||
|
||||
fmt.Printf("Installiere Build Essentials für %s...\n", os.Name)
|
||||
if err := installPackage(command, "", sudoPassword); err != nil {
|
||||
return fmt.Errorf("fehler bei der Installation der Build Essentials: %v", err)
|
||||
if err := InstallPackage(command, "", sudoPassword); err != nil {
|
||||
return fmt.Errorf("error installing Build Essentials: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,26 +1,20 @@
|
|||
// osmanager_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewOSManager(t *testing.T) {
|
||||
os := &OS{ID: "ubuntu", PackageManager: "apt"}
|
||||
sudoPassword := "testpassword"
|
||||
packages := []string{"git", "curl"}
|
||||
|
||||
manager := NewOSManager(os, sudoPassword, packages)
|
||||
manager := NewOSManager(sudoPassword)
|
||||
|
||||
if manager.OS != os {
|
||||
t.Errorf("Expected OS to be %v, got %v", os, manager.OS)
|
||||
if manager.OS == nil {
|
||||
t.Error("Expected OS to be non-nil")
|
||||
}
|
||||
if manager.SudoPassword != 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) {
|
||||
|
|
@ -47,4 +41,13 @@ VERSION_ID="20.04"
|
|||
if os.Version != "20.04" {
|
||||
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 (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"system_setup_tool/internal/shell"
|
||||
)
|
||||
|
||||
type Packages struct {
|
||||
|
|
@ -10,26 +12,17 @@ type Packages struct {
|
|||
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)
|
||||
command := execCommand("sudo", "-S", "sh", "-c", fullCmd)
|
||||
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
|
||||
command.Stdin = strings.NewReader(sudoPassword + "\n")
|
||||
output, err := command.CombinedOutput()
|
||||
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") {
|
||||
unavailablePackages = append(unavailablePackages, pkg)
|
||||
log.Printf("Package %s not available\n", pkg)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to install %s: %v\n%s", pkg, err, string(output))
|
||||
}
|
||||
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 {
|
||||
Install(packages []string) error
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
package main
|
||||
package packagemanager
|
||||
|
||||
import "system_setup_tool/internal/shell"
|
||||
|
||||
type PipxManager struct{}
|
||||
|
||||
|
|
@ -7,7 +9,7 @@ func (p *PipxManager) Install(packages []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
err := installWithProgress(p, packages)
|
||||
err := InstallWithProgress(p, packages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -19,25 +21,25 @@ func (p *PipxManager) Name() string {
|
|||
}
|
||||
|
||||
func (p *PipxManager) InstallManager() error {
|
||||
if _, err := execLookPath("brew"); err != nil {
|
||||
if _, err := shell.ExecLookPath("brew"); err != nil {
|
||||
installHomebrew()
|
||||
}
|
||||
|
||||
if _, err := execLookPath("pipx"); err == nil {
|
||||
if _, err := shell.ExecLookPath("pipx"); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := execCommand("brew", "install", "pipx")
|
||||
cmd := shell.ExecCommand("brew", "install", "pipx")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (p *PipxManager) InstallPackage(pkg string) error {
|
||||
cmd := execCommand("pipx", "install", pkg)
|
||||
cmd := shell.ExecCommand("pipx", "install", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (p *PipxManager) RemovePackage(pkg string) error {
|
||||
cmd := execCommand("pipx", "uninstall", pkg)
|
||||
cmd := shell.ExecCommand("pipx", "uninstall", pkg)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// pipx_test.go
|
||||
package main
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"system_setup_tool/internal/shell"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -17,13 +17,13 @@ func TestPipxManager_InstallManager(t *testing.T) {
|
|||
pm := &PipxManager{}
|
||||
|
||||
// Mock exec.LookPath
|
||||
execLookPath = func(file string) (string, error) {
|
||||
shell.ExecLookPath = func(file string) (string, error) {
|
||||
if file == "pipx" {
|
||||
return "/usr/bin/pipx", nil
|
||||
}
|
||||
return "", exec.ErrNotFound
|
||||
}
|
||||
defer func() { execLookPath = exec.LookPath }()
|
||||
defer func() { shell.ExecLookPath = exec.LookPath }()
|
||||
|
||||
if err := pm.InstallManager(); err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
|
|
@ -34,10 +34,10 @@ func TestPipxManager_InstallPackage(t *testing.T) {
|
|||
pm := &PipxManager{}
|
||||
|
||||
// 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")
|
||||
}
|
||||
defer func() { execCommand = exec.Command }()
|
||||
defer func() { shell.ExecCommand = exec.Command }()
|
||||
|
||||
if err := pm.InstallPackage("test-package"); err != nil {
|
||||
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