feat: basic brew installer

This commit is contained in:
2024-12-22 03:44:00 +02:00
parent 66b2fb0467
commit 285f278e09
5 changed files with 108 additions and 18 deletions

View File

@@ -11,6 +11,8 @@ type AppConfig struct {
Debug any `pkl:"debug"`
Install []*Installer `pkl:"install"`
CheckUpdates *bool `pkl:"check_updates"`
}
// LoadFromPath loads the pkl module at the given path and evaluates it into a AppConfig

View File

@@ -1,33 +1,85 @@
package installer
import (
"bufio"
"fmt"
"encoding/json"
"io"
"os"
"os/exec"
"slices"
"github.com/chenasraf/sofmani/appconfig"
)
type BrewInstaller struct {
Config *appconfig.AppConfig
Installer *appconfig.Installer
Config *appconfig.AppConfig
Info *appconfig.Installer
}
// Install implements IInstaller.
func (i *BrewInstaller) Install() error {
cmd := exec.Command("brew", "install", i.Installer.Name)
cmd := exec.Command("brew", "install", i.Info.Name)
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
cmd.Start()
scanner := bufio.NewScanner(stderr)
scanner.Split(bufio.ScanRunes)
for scanner.Scan() {
fmt.Print(scanner.Text())
}
go io.Copy(os.Stdout, stdout)
go io.Copy(os.Stderr, stderr)
cmd.Wait()
return nil
}
// Update implements IInstaller.
func (i *BrewInstaller) Update() error {
cmd := exec.Command("brew", "upgrade", i.Info.Name)
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
cmd.Start()
go io.Copy(os.Stdout, stdout)
go io.Copy(os.Stderr, stderr)
cmd.Wait()
return nil
}
// CheckNeedsUpdate implements IInstaller.
func (i *BrewInstaller) CheckNeedsUpdate() (error, bool) {
cmd := exec.Command("brew", "outdated", "--json", i.Info.Name)
out, err := cmd.Output()
if err != nil {
return err, false
}
jsonOut := make(map[string]interface{})
err = json.Unmarshal(out, &jsonOut)
if err != nil {
return err, false
}
var formulae []interface{} = jsonOut["formulae"].([]interface{})
strFormulae := make([]string, len(formulae))
for i, v := range formulae {
strFormulae[i] = v.(string)
}
if slices.Contains(strFormulae, i.Info.Name) {
return nil, true
}
return nil, false
}
// CheckIsInstalled implements IInstaller.
func (i *BrewInstaller) CheckIsInstalled() (error, bool) {
cmd := exec.Command("brew", "list", i.Info.Name)
err := cmd.Run()
if err != nil {
return nil, false
}
return nil, true
}
// GetInfo implements IInstaller.
func (i *BrewInstaller) GetInfo() *appconfig.Installer {
return i.Info
}
func NewBrewInstaller(cfg *appconfig.AppConfig, installer *appconfig.Installer) *BrewInstaller {
return &BrewInstaller{
Config: cfg,
Installer: installer,
Config: cfg,
Info: installer,
}
}

View File

@@ -1,18 +1,48 @@
package installer
import (
"fmt"
"github.com/chenasraf/sofmani/appconfig"
"github.com/chenasraf/sofmani/appconfig/installertype"
)
type InstallerImpl struct {
Config *appconfig.AppConfig
}
type IInstaller interface {
GetInfo() *appconfig.Installer
CheckIsInstalled() (error, bool)
CheckNeedsUpdate() (error, bool)
Install() error
Update() error
}
func RunInstaller(installer IInstaller) error {
func GetInstaller(config *appconfig.AppConfig, installer *appconfig.Installer) (error, IInstaller) {
switch installer.Type {
case installertype.Brew:
return nil, NewBrewInstaller(config, installer)
}
return fmt.Errorf("Installer type %s is not supported", installer.Type), nil
}
func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error {
err, installed := installer.CheckIsInstalled()
if err != nil {
return err
}
if installed {
fmt.Printf("%s is already installed\n", installer.GetInfo().Name)
// if *config.CheckUpdates {
err, needsUpdate := installer.CheckNeedsUpdate()
if err != nil {
return err
}
if needsUpdate {
fmt.Printf("%s needs an update\n", installer.GetInfo().Name)
installer.Update()
}
} else {
return nil
}
// }
installer.Install()
return nil
}

View File

@@ -16,6 +16,11 @@ func main() {
fmt.Println("Installing...")
for _, i := range cfg.Install {
fmt.Println(fmt.Sprintf("Installing %s", i.Name))
installer.RunInstaller(installer.NewBrewInstaller(cfg, i))
err, installerInstance := installer.GetInstaller(cfg, i)
if err != nil {
fmt.Println(err)
return
}
installer.RunInstaller(cfg, installerInstance)
}
}

View File

@@ -25,3 +25,4 @@ class Platforms {
debug = false
install: Listing<Installer>
check_updates: Boolean? = false