feat: rsync installer

This commit is contained in:
2024-12-24 01:27:27 +02:00
parent e2f0a35200
commit d1f3de3d8c
7 changed files with 153 additions and 21 deletions

View File

@@ -41,6 +41,7 @@ const (
InstallerTypeBrew InstallerType = "brew"
InstallerTypeApt InstallerType = "apt"
InstallerTypeGit InstallerType = "git"
InstallerTypeRsync InstallerType = "rsync"
)
type Platforms struct {

View File

@@ -1,9 +1,6 @@
package installer
import (
"encoding/json"
"slices"
"github.com/chenasraf/sofmani/appconfig"
"github.com/chenasraf/sofmani/utils"
)
@@ -36,24 +33,11 @@ func (i *BrewInstaller) CheckNeedsUpdate() (error, bool) {
if i.GetInfo().CheckHasUpdate != nil {
return utils.RunCmdGetSuccess("sh", "-c", *i.GetInfo().CheckHasUpdate)
}
out, err := utils.RunCmdGetOutput("brew", "outdated", "--json", *i.Info.Name)
err, success := utils.RunCmdGetSuccess("brew", "outdated", "--json", *i.Info.Name)
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
return nil, !success
}
// CheckIsInstalled implements IInstaller.

View File

@@ -26,6 +26,8 @@ func GetInstaller(config *appconfig.AppConfig, installer *appconfig.Installer) (
return nil, NewBrewInstaller(config, installer)
case appconfig.InstallerTypeShell:
return nil, NewShellInstaller(config, installer)
case appconfig.InstallerTypeRsync:
return nil, NewRsyncInstaller(config, installer)
}
return nil, nil
}
@@ -95,7 +97,7 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error {
if installed {
logger.Debug("%s is already installed", name)
if config.CheckUpdates {
logger.Debug("Checking if %s needs an update", name)
logger.Info("Checking if %s needs an update", name)
err, needsUpdate := installer.CheckNeedsUpdate()
if err != nil {
return err
@@ -119,6 +121,7 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error {
}
}
}
return nil
} else {
return nil
}

View File

@@ -0,0 +1,100 @@
package installer
import (
"strings"
"github.com/chenasraf/sofmani/appconfig"
"github.com/chenasraf/sofmani/logger"
"github.com/chenasraf/sofmani/utils"
)
type RsyncInstaller struct {
Config *appconfig.AppConfig
Info *appconfig.Installer
}
type RsyncOpts struct {
Source *string
Destination *string
Flags *string
}
// Install implements IInstaller.
func (i *RsyncInstaller) Install() error {
defaultFlags := "-tr"
if i.Config.Debug {
defaultFlags += "v"
}
flags := []string{defaultFlags}
if i.GetOpts().Flags != nil {
for _, flag := range strings.Split(*i.GetOpts().Flags, " ") {
flags = append(flags, flag)
}
}
src := utils.GetRealPath(*i.GetOpts().Source)
dest := utils.GetRealPath(*i.GetOpts().Destination)
flags = append(flags, src)
flags = append(flags, dest)
logger.Debug("rsync %s to %s", src, dest)
return utils.RunCmdPassThrough("rsync", flags...)
}
// Update implements IInstaller.
func (i *RsyncInstaller) Update() error {
return i.Install()
}
// CheckNeedsUpdate implements IInstaller.
func (i *RsyncInstaller) CheckNeedsUpdate() (error, bool) {
if i.GetInfo().CheckHasUpdate != nil {
return utils.RunCmdGetSuccess("sh", "-c", *i.GetInfo().CheckHasUpdate)
}
return nil, true
}
// CheckIsInstalled implements IInstaller.
func (i *RsyncInstaller) CheckIsInstalled() (error, bool) {
return utils.RunCmdGetSuccess("which", i.GetBinName())
}
// GetInfo implements IInstaller.
func (i *RsyncInstaller) GetInfo() *appconfig.Installer {
return i.Info
}
func (i *RsyncInstaller) GetOpts() *RsyncOpts {
opts := &RsyncOpts{}
info := i.Info
if info.Opts != nil {
if src, ok := (*info.Opts)["source"].(string); ok {
opts.Source = &src
}
if dest, ok := (*info.Opts)["destination"].(string); ok {
opts.Destination = &dest
}
if flags, ok := (*info.Opts)["flags"].(string); ok {
opts.Flags = &flags
}
}
return opts
}
func (i *RsyncInstaller) GetBinName() string {
info := i.GetInfo()
if info.BinName != nil && len(*info.BinName) > 0 {
return *info.BinName
}
return *info.Name
}
func NewRsyncInstaller(cfg *appconfig.AppConfig, installer *appconfig.Installer) *RsyncInstaller {
i := &RsyncInstaller{
Config: cfg,
Info: installer,
}
return i
}

View File

@@ -20,7 +20,7 @@ type ShellOpts struct {
// Install implements IInstaller.
func (i *ShellInstaller) Install() error {
tmpdir := os.TempDir()
tmpfile := fmt.Sprintf("%s/%s", tmpdir, "install.sh")
tmpfile := fmt.Sprintf("%s%s", tmpdir, "install.sh")
commandStr := fmt.Sprintf("#!/bin/bash\n%s\n", *i.GetOpts().Command)
err := os.WriteFile(tmpfile, []byte(commandStr), 0755)
if err != nil {

View File

@@ -1,4 +1,5 @@
debug: true
check_updates: true
defaults:
type:
brew:
@@ -6,10 +7,27 @@ defaults:
only: ['macos']
install:
- name: nvim
type: rsync
opts:
source: ~/.dotfiles/.config/nvim/
destination: ~/.config/nvim/
flags: --delete --exclude .git --exclude .DS_Store
- name: lazygit
type: rsync
opts:
source: ~/.dotfiles/.config/lazygit.yml
destination: ~/Library/ApplicationSupport/lazygit/config.yml
- name: config
type: rsync
opts:
source: ~/.dotfiles/.config
destination: ~/.config
flags: --exclude lazygit.yml --exclude nvim --exclude .git --exclude .DS_Store
- name: treelike
type: brew
opts:
tap: chenasraf/tap/treelike
tap: chenasraf/tap
- name: lazygit
type: group
steps:

26
utils/os.go Normal file
View File

@@ -0,0 +1,26 @@
package utils
import (
"fmt"
"os"
"path/filepath"
"strings"
)
func GetRealPath(path string) string {
if strings.HasPrefix(path, fmt.Sprintf("~%s", string(filepath.Separator))) {
homedir, err := os.UserHomeDir()
if err != nil {
return path
}
isDir := false
if strings.HasSuffix(path, string(filepath.Separator)) {
isDir = true
}
path = filepath.Join(homedir, path[2:])
if isDir {
path += string(filepath.Separator)
}
}
return path
}