feat(config,cli): add progressbar to specialPack

This commit is contained in:
Patryk Hegenberg 2024-12-27 10:53:29 +01:00
parent 56f6ef28d5
commit 43cf46300f
2 changed files with 197 additions and 46 deletions

View file

@ -13,9 +13,9 @@ headless = [
"docker",
"docker-compose",
"fd",
"bat",
"lsd",
"zsh",
"oh-my-posh",
"jq",
"neofetch",
"neovim",
@ -24,11 +24,14 @@ headless = [
"stow",
"task",
"timew",
"typst",
"typst-lsp",
"tree-sitter-cli",
"tmux",
"zoxide",
"python3-pip",
"pipx",
"golang",
"rustup",
]
non_headless = [
@ -74,10 +77,12 @@ go = [
cargo = [
"git-cliff",
"bottom",
"typst-cli",
]
pipx = [
"harlequin",
"posting",
"euporie",
# "harlequin",
# "posting",
# "euporie",
]

228
main.go
View file

@ -109,13 +109,124 @@ func getInstallCommand(pm string) (string, error) {
case "pacman":
return "pacman -S --noconfirm --needed", nil
case "dnf":
// return "dnf install -y --best", nil
return "dnf install -y --skip-unavailable --best", nil
return "dnf install -y --best", nil
default:
return "", fmt.Errorf("no install command found for package manager: %s", pm)
}
}
type specialSoftwareModel struct {
items []string
index int
spinner spinner.Model
progress progress.Model
done bool
sudoPassword string
}
func newSpecialSoftwareModel(sudoPassword string) specialSoftwareModel {
// Definiere die zu installierenden Items
items := []string{"oh-my-posh", "golang", "rust"}
p := progress.New(
progress.WithDefaultGradient(),
progress.WithWidth(40),
progress.WithoutPercentage(),
)
s := spinner.New()
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
return specialSoftwareModel{
items: items,
spinner: s,
progress: p,
sudoPassword: sudoPassword,
}
}
func (m specialSoftwareModel) Init() tea.Cmd {
return tea.Batch(m.installItemCmd(m.items[m.index]), m.spinner.Tick)
}
func (m specialSoftwareModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "esc", "q":
return m, tea.Quit
}
case installedItemMsg:
if m.index >= len(m.items)-1 {
m.done = true
return m, tea.Quit
}
m.index++
progressCmd := m.progress.SetPercent(float64(m.index) / float64(len(m.items)))
return m, tea.Batch(
progressCmd,
tea.Printf("%s %s", checkMark, m.items[m.index-1]),
m.installItemCmd(m.items[m.index]),
)
case spinner.TickMsg:
var cmd tea.Cmd
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
}
return m, nil
}
func (m specialSoftwareModel) View() string {
if m.done {
return doneStyle.Render(fmt.Sprintf("Spezielle Software Installation abgeschlossen!\n"))
}
spin := m.spinner.View() + " "
prog := m.progress.View()
info := fmt.Sprintf("Installiere %s", m.items[m.index])
return spin + info + " " + prog
}
type installedItemMsg string
func (m specialSoftwareModel) installItemCmd(item string) tea.Cmd {
return func() tea.Msg {
switch item {
case "oh-my-posh":
if _, err := exec.LookPath("oh-my-posh"); err == nil {
return installedItemMsg(item)
}
poshCommand := "curl -s https://ohmyposh.dev/install.sh | bash -s"
if err := installPackage(poshCommand, "", ""); err != nil {
log.Printf("Fehler beim Installieren von oh-my-posh: %v", err)
}
case "golang":
if _, err := exec.LookPath("go"); err == nil {
return installedItemMsg(item)
}
golangVersion := "1.23.4"
if err := downloadGolang(golangVersion); err != nil {
log.Printf("Fehler beim Herunterladen von Go: %v", err)
}
golangCommand := fmt.Sprintf("sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go%s.linux-%s.tar.gz", golangVersion, runtime.GOARCH)
if err := installPackage(golangCommand, "", m.sudoPassword); err != nil {
log.Printf("Fehler beim Installieren von Go: %v", err)
}
case "rust":
if _, err := exec.LookPath("rustc"); err == nil {
return installedItemMsg(item)
}
rustupCommand := "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -q -y"
if err := installPackage(rustupCommand, "", ""); err != nil {
log.Printf("Fehler beim Installieren von Rust: %v", err)
}
}
return installedItemMsg(item)
}
}
var unavailablePackages []string
func installPackage(cmd, pkg, sudoPassword string) error {
@ -133,28 +244,6 @@ func installPackage(cmd, pkg, sudoPassword string) error {
return nil
}
// func installPackage(cmd, pkg, sudoPassword string) error {
// fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
// command := exec.Command("sudo", "-S", "sh", "-c", fullCmd)
// command.Stdin = strings.NewReader(sudoPassword + "\n")
// output, err := command.CombinedOutput()
// if err != nil {
// return fmt.Errorf("failed to install %s: %v\n%s", pkg, err, string(output))
// }
// return nil
// }
// func installPackage(cmd, pkg string) error {
// fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
// command := exec.Command("sudo", "sh", "-c", fullCmd)
// output, err := command.CombinedOutput()
// if err != nil {
// return fmt.Errorf("failed to install %s: %v\n%s", pkg, err, string(output))
// }
// return nil
// }
func downloadGolang(golangVersion string) error {
var link string
if runtime.GOARCH == "arm64" {
@ -187,6 +276,14 @@ func downloadGolang(golangVersion string) error {
}
func (m model) installSpecialSoftware() error {
if _, err := exec.LookPath("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
}
}
if _, err := exec.LookPath("go"); err == nil {
fmt.Println("Go ist bereits installiert.")
} else {
@ -209,14 +306,14 @@ func (m model) installSpecialSoftware() error {
}
}
if _, err := exec.LookPath("pipx"); err == nil {
fmt.Println("Pipx ist bereits installiert.")
} else {
pipXCommand := "python3 -m pip install --user pipx && python3 -m pipx ensurepath"
if err := installPackage(pipXCommand, "", ""); err != nil {
return err
}
}
// if _, err := exec.LookPath("pipx"); err == nil {
// fmt.Println("Pipx ist bereits installiert.")
// } else {
// pipXCommand := "python3 -m pip install --user pipx && python3 -m pipx ensurepath"
// if err := installPackage(pipXCommand, "", ""); err != nil {
// return err
// }
// }
return nil
}
@ -452,12 +549,16 @@ func run(cmd *cobra.Command, args []string) {
packages = append(packages, cfg.Packages.NonHeadless...)
}
unavailablePackages = []string{}
m := newModel(packages, sudoPassword)
p := tea.NewProgram(m)
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
printUnavailablePackages()
var installSpecial bool
form = huh.NewForm(
huh.NewGroup(
@ -473,19 +574,64 @@ func run(cmd *cobra.Command, args []string) {
}
if installSpecial {
if err := m.installSpecialSoftware(); err != nil {
log.Printf("Fehler beim Installieren der speziellen Software: %v", err)
} else {
fmt.Println("Spezielle Software erfolgreich installiert")
sm := newSpecialSoftwareModel(sudoPassword)
p = tea.NewProgram(sm)
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
} else {
fmt.Println("Installation der speziellen Pakete übersprungen")
}
if err := installSpecialPackages(cfg.SpecialPackages); err != nil {
log.Printf("Fehler bei der Installation spezieller Pakete: %v", err)
if len(cfg.SpecialPackages.Go) > 0 || len(cfg.SpecialPackages.Cargo) > 0 || len(cfg.SpecialPackages.Pipx) > 0 {
// Combine all special packages for the progress bar
var allSpecialPkgs []struct {
typ string
name string
command string
}
for _, pkg := range cfg.SpecialPackages.Go {
allSpecialPkgs = append(allSpecialPkgs, struct {
typ string
name string
command string
}{"go", pkg, "go install " + pkg + "@latest"})
}
for _, pkg := range cfg.SpecialPackages.Cargo {
allSpecialPkgs = append(allSpecialPkgs, struct {
typ string
name string
command string
}{"cargo", pkg, "cargo install " + pkg})
}
for _, pkg := range cfg.SpecialPackages.Pipx {
allSpecialPkgs = append(allSpecialPkgs, struct {
typ string
name string
command string
}{"pipx", pkg, "pipx install " + pkg})
}
if len(allSpecialPkgs) > 0 {
fmt.Println("\nInstalliere spezielle Pakete...")
p := progress.New(
progress.WithDefaultGradient(),
progress.WithWidth(40),
)
for i, pkg := range allSpecialPkgs {
p.SetPercent(float64(i) / float64(len(allSpecialPkgs)))
fmt.Printf("Installiere %s Paket: %s\n", pkg.typ, pkg.name)
cmd := exec.Command("sh", "-c", pkg.command)
if err := cmd.Run(); err != nil {
log.Printf("Fehler bei der Installation von %s: %v", pkg.name, err)
continue
}
}
}
}
printUnavailablePackages()
}
func printUnavailablePackages() {