mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
feat: rsync installer
This commit is contained in:
@@ -41,6 +41,7 @@ const (
|
||||
InstallerTypeBrew InstallerType = "brew"
|
||||
InstallerTypeApt InstallerType = "apt"
|
||||
InstallerTypeGit InstallerType = "git"
|
||||
InstallerTypeRsync InstallerType = "rsync"
|
||||
)
|
||||
|
||||
type Platforms struct {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
100
installer/rsync_installer.go
Normal file
100
installer/rsync_installer.go
Normal 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
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
20
sofmani.yml
20
sofmani.yml
@@ -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
26
utils/os.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user