feat(config,cli): add packages and fix os find
This commit is contained in:
parent
537c823015
commit
adce222433
2 changed files with 152 additions and 41 deletions
47
config.toml
47
config.toml
|
|
@ -5,24 +5,61 @@ headless = [
|
|||
"git",
|
||||
"curl",
|
||||
"wget",
|
||||
"zathura",
|
||||
"ripgrep",
|
||||
"bottom",
|
||||
"bat",
|
||||
"biber",
|
||||
"bear",
|
||||
"docker",
|
||||
"docker-compose",
|
||||
"fd",
|
||||
"bat",
|
||||
"lazygit",
|
||||
"lsd",
|
||||
]
|
||||
|
||||
non_headless = [
|
||||
"discord",
|
||||
"flameshot",
|
||||
"fuzzel",
|
||||
"google-chrome",
|
||||
"hyprcursor",
|
||||
"hypridle",
|
||||
"hyprland",
|
||||
"hyprland-qtutils",
|
||||
"hyprlock",
|
||||
"hyprpaper",
|
||||
"hyprutils",
|
||||
"kitty",
|
||||
"mako",
|
||||
"mpv",
|
||||
"neovide",
|
||||
"pidgin",
|
||||
"remmina",
|
||||
"spotify",
|
||||
"thunderbird",
|
||||
"thunderbird-i18n-de",
|
||||
"virt-manager",
|
||||
"vlc",
|
||||
"waybar",
|
||||
"xdg-desktop-portal-hyprland",
|
||||
"zathura",
|
||||
"zathura-mu-pdf",
|
||||
"zoom",
|
||||
"zotero",
|
||||
"android-studio"
|
||||
]
|
||||
|
||||
[special_packages]
|
||||
go = [
|
||||
"github.com/jesseduffield/lazygit",
|
||||
# "github.com/jesseduffield/lazygit",
|
||||
"github.com/stefanlogue/meteor",
|
||||
"golang.org/x/tools/gopls",
|
||||
"github.com/go-delve/delve/cmd/dlv",
|
||||
# "golangci-lint",
|
||||
]
|
||||
|
||||
cargo = [
|
||||
"ripgrep",
|
||||
"bat"
|
||||
"git-cliff",
|
||||
]
|
||||
|
||||
pipx = [
|
||||
|
|
|
|||
146
main.go
146
main.go
|
|
@ -19,23 +19,49 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func getLinuxDistribution() (string, error) {
|
||||
data, err := os.ReadFile("/etc/os-release")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "ID=") {
|
||||
return strings.Trim(strings.TrimPrefix(line, "ID="), "\""), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Linux distribution not found")
|
||||
type OS struct {
|
||||
ID string
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
|
||||
func getPackageManager(os string) (string, error) {
|
||||
switch os {
|
||||
func parseOsRelease(osRelease string) *OS {
|
||||
var result OS
|
||||
result.ID = "Unknown"
|
||||
result.Name = "Unknown"
|
||||
result.Version = "Unknown"
|
||||
|
||||
lines := strings.Split(osRelease, "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
splitLine := strings.SplitN(line, "=", 2)
|
||||
if len(splitLine) != 2 {
|
||||
continue
|
||||
}
|
||||
switch splitLine[0] {
|
||||
case "ID":
|
||||
result.ID = strings.ToLower(strings.Trim(splitLine[1], "\""))
|
||||
case "NAME":
|
||||
result.Name = strings.Trim(splitLine[1], "\"")
|
||||
case "VERSION_ID":
|
||||
result.Version = strings.Trim(splitLine[1], "\"")
|
||||
}
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
func getLinuxDistribution() (*OS, error) {
|
||||
_, err := os.Stat("/etc/os-release")
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("unable to read system information")
|
||||
}
|
||||
|
||||
osRelease, _ := os.ReadFile("/etc/os-release")
|
||||
return parseOsRelease(string(osRelease)), nil
|
||||
}
|
||||
|
||||
func getPackageManager(os *OS) (string, error) {
|
||||
switch os.ID {
|
||||
case "debian", "ubuntu":
|
||||
return "apt", nil
|
||||
case "arch":
|
||||
|
|
@ -43,10 +69,39 @@ func getPackageManager(os string) (string, error) {
|
|||
case "fedora":
|
||||
return "dnf", nil
|
||||
default:
|
||||
var pmcommands = []string{
|
||||
"apt",
|
||||
"dnf",
|
||||
"pacman",
|
||||
}
|
||||
for _, pmname := range pmcommands {
|
||||
_, err := exec.LookPath(pmname)
|
||||
if err == nil {
|
||||
return pmname, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no packagemanager found for os: %s", os)
|
||||
}
|
||||
}
|
||||
|
||||
func getSudoPassword() (string, error) {
|
||||
var password string
|
||||
form := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewInput().
|
||||
Title("Bitte geben Sie Ihr sudo-Passwort ein").
|
||||
Password(true).
|
||||
Value(&password),
|
||||
),
|
||||
).WithTheme(huh.ThemeCatppuccin())
|
||||
|
||||
err := form.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Fehler bei der Passwortabfrage: %v", err)
|
||||
}
|
||||
return password, nil
|
||||
}
|
||||
|
||||
func getInstallCommand(pm string) (string, error) {
|
||||
switch pm {
|
||||
case "apt":
|
||||
|
|
@ -60,9 +115,11 @@ func getInstallCommand(pm string) (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func installPackage(cmd, pkg string) error {
|
||||
func installPackage(cmd, pkg, sudoPassword string) error {
|
||||
fullCmd := fmt.Sprintf("%s %s", cmd, pkg)
|
||||
command := exec.Command("sudo", "sh", "-c", fullCmd)
|
||||
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))
|
||||
|
|
@ -70,6 +127,16 @@ func installPackage(cmd, pkg string) error {
|
|||
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" {
|
||||
|
|
@ -110,7 +177,7 @@ func installSpecialSoftware() error {
|
|||
return fmt.Errorf("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, ""); err != nil {
|
||||
if err := installPackage(golangCommand, "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -119,7 +186,7 @@ func installSpecialSoftware() error {
|
|||
fmt.Println("Rust ist bereits installiert.")
|
||||
} else {
|
||||
rustupCommand := "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -- -q -y"
|
||||
if err := installPackage(rustupCommand, ""); err != nil {
|
||||
if err := installPackage(rustupCommand, "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +195,7 @@ func installSpecialSoftware() error {
|
|||
fmt.Println("Pipx ist bereits installiert.")
|
||||
} else {
|
||||
pipXCommand := "python3 -m pip install --user pipx && python3 -m pipx ensurepath"
|
||||
if err := installPackage(pipXCommand, ""); err != nil {
|
||||
if err := installPackage(pipXCommand, "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -137,13 +204,14 @@ func installSpecialSoftware() error {
|
|||
}
|
||||
|
||||
type model struct {
|
||||
packages []string
|
||||
index int
|
||||
width int
|
||||
height int
|
||||
spinner spinner.Model
|
||||
progress progress.Model
|
||||
done bool
|
||||
packages []string
|
||||
index int
|
||||
width int
|
||||
height int
|
||||
spinner spinner.Model
|
||||
progress progress.Model
|
||||
done bool
|
||||
sudoPassword string
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -152,7 +220,7 @@ var (
|
|||
checkMark = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓")
|
||||
)
|
||||
|
||||
func newModel(packages []string) model {
|
||||
func newModel(packages []string, sudoPassword string) model {
|
||||
p := progress.New(
|
||||
progress.WithDefaultGradient(),
|
||||
progress.WithWidth(40),
|
||||
|
|
@ -161,14 +229,15 @@ func newModel(packages []string) model {
|
|||
s := spinner.New()
|
||||
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
|
||||
return model{
|
||||
packages: packages,
|
||||
spinner: s,
|
||||
progress: p,
|
||||
packages: packages,
|
||||
spinner: s,
|
||||
progress: p,
|
||||
sudoPassword: sudoPassword,
|
||||
}
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd {
|
||||
return tea.Batch(installPackageCmd(m.packages[m.index]), m.spinner.Tick)
|
||||
return tea.Batch(m.installPackageCmd(m.packages[m.index]), m.spinner.Tick)
|
||||
}
|
||||
|
||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
|
@ -196,7 +265,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, tea.Batch(
|
||||
progressCmd,
|
||||
tea.Printf("%s %s", checkMark, pkg),
|
||||
installPackageCmd(m.packages[m.index]),
|
||||
m.installPackageCmd(m.packages[m.index]),
|
||||
)
|
||||
case spinner.TickMsg:
|
||||
var cmd tea.Cmd
|
||||
|
|
@ -237,9 +306,9 @@ func (m model) View() string {
|
|||
|
||||
type installedPkgMsg string
|
||||
|
||||
func installPackageCmd(pkg string) tea.Cmd {
|
||||
func (m model) installPackageCmd(pkg string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
if err := installPackage(installCommand, pkg); err != nil {
|
||||
if err := installPackage(installCommand, pkg, m.sudoPassword); err != nil {
|
||||
log.Printf("Fehler beim Installieren von %s: %v", pkg, err)
|
||||
}
|
||||
return installedPkgMsg(pkg)
|
||||
|
|
@ -337,6 +406,11 @@ func run(cmd *cobra.Command, args []string) {
|
|||
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)
|
||||
|
|
@ -360,7 +434,7 @@ func run(cmd *cobra.Command, args []string) {
|
|||
packages = append(packages, cfg.Packages.NonHeadless...)
|
||||
}
|
||||
|
||||
m := newModel(packages)
|
||||
m := newModel(packages, sudoPassword)
|
||||
p := tea.NewProgram(m)
|
||||
if _, err := p.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue