mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
refactor: platform
This commit is contained in:
@@ -6,10 +6,10 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/chenasraf/sofmani/logger"
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/eschao/config"
|
||||
)
|
||||
|
||||
@@ -34,20 +34,20 @@ type AppConfigDefaults struct {
|
||||
}
|
||||
|
||||
type Installer struct {
|
||||
Name *string `json:"name" yaml:"name"`
|
||||
Type InstallerType `json:"type" yaml:"type"`
|
||||
Env *map[string]string `json:"env" yaml:"env"`
|
||||
Platforms *Platforms `json:"platforms" yaml:"platforms"`
|
||||
Steps *[]Installer `json:"steps" yaml:"steps"`
|
||||
Opts *map[string]any `json:"opts" yaml:"opts"`
|
||||
BinName *string `json:"bin_name" yaml:"bin_name"`
|
||||
CheckHasUpdate *string `json:"check_has_update" yaml:"check_has_update"`
|
||||
CheckInstalled *string `json:"check_installed" yaml:"check_installed"`
|
||||
PostInstall *string `json:"post_install" yaml:"post_install"`
|
||||
PreInstall *string `json:"pre_install" yaml:"pre_install"`
|
||||
PostUpdate *string `json:"post_update" yaml:"post_update"`
|
||||
PreUpdate *string `json:"pre_update" yaml:"pre_update"`
|
||||
EnvShell *PlatformMap[string] `json:"env_shell" yaml:"env_shell"`
|
||||
Name *string `json:"name" yaml:"name"`
|
||||
Type InstallerType `json:"type" yaml:"type"`
|
||||
Env *map[string]string `json:"env" yaml:"env"`
|
||||
Platforms *platform.Platforms `json:"platforms" yaml:"platforms"`
|
||||
Steps *[]Installer `json:"steps" yaml:"steps"`
|
||||
Opts *map[string]any `json:"opts" yaml:"opts"`
|
||||
BinName *string `json:"bin_name" yaml:"bin_name"`
|
||||
CheckHasUpdate *string `json:"check_has_update" yaml:"check_has_update"`
|
||||
CheckInstalled *string `json:"check_installed" yaml:"check_installed"`
|
||||
PostInstall *string `json:"post_install" yaml:"post_install"`
|
||||
PreInstall *string `json:"pre_install" yaml:"pre_install"`
|
||||
PostUpdate *string `json:"post_update" yaml:"post_update"`
|
||||
PreUpdate *string `json:"pre_update" yaml:"pre_update"`
|
||||
EnvShell *platform.PlatformMap[string] `json:"env_shell" yaml:"env_shell"`
|
||||
}
|
||||
|
||||
type InstallerType string
|
||||
@@ -65,55 +65,6 @@ const (
|
||||
InstallerTypeManifest InstallerType = "manifest"
|
||||
)
|
||||
|
||||
type Platforms struct {
|
||||
Only *[]Platform `json:"only" yaml:"only"`
|
||||
Except *[]Platform `json:"except" yaml:"except"`
|
||||
}
|
||||
|
||||
type Platform string
|
||||
|
||||
const (
|
||||
PlatformMacos Platform = "macos"
|
||||
PlatformLinux Platform = "linux"
|
||||
PlatformWindows Platform = "windows"
|
||||
)
|
||||
|
||||
type PlatformMap[T any] struct {
|
||||
MacOS *T `json:"macos" yaml:"macos"`
|
||||
Linux *T `json:"linux" yaml:"linux"`
|
||||
Windows *T `json:"windows" yaml:"windows"`
|
||||
}
|
||||
|
||||
func (p *PlatformMap[T]) Resolve() *T {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
if p.MacOS != nil {
|
||||
return p.MacOS
|
||||
}
|
||||
return nil
|
||||
case "linux":
|
||||
if p.Linux != nil {
|
||||
return p.Linux
|
||||
}
|
||||
return nil
|
||||
case "windows":
|
||||
if p.Windows != nil {
|
||||
return p.Windows
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PlatformMap[T]) ResolveWithFallback(fallback PlatformMap[T]) T {
|
||||
val := o.Resolve()
|
||||
if val == nil {
|
||||
return *fallback.Resolve()
|
||||
}
|
||||
return *val
|
||||
}
|
||||
|
||||
func (c *AppConfig) Environ() []string {
|
||||
if c.Env == nil {
|
||||
return []string{}
|
||||
@@ -136,7 +87,7 @@ func (i *Installer) Environ() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
func ContainsPlatform(platforms *[]Platform, platform Platform) bool {
|
||||
func ContainsPlatform(platforms *[]platform.Platform, platform platform.Platform) bool {
|
||||
for _, p := range *platforms {
|
||||
if p == platform {
|
||||
return true
|
||||
|
||||
@@ -3,10 +3,10 @@ package appconfig
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -23,10 +23,8 @@ func TestPlatformMapResolve(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if runtime.GOOS != tt.platform {
|
||||
t.Skipf("Skipping test on %s", runtime.GOOS)
|
||||
}
|
||||
pm := PlatformMap[string]{
|
||||
platform.SetOS(tt.platform)
|
||||
pm := platform.PlatformMap[string]{
|
||||
MacOS: strPtr("macos"),
|
||||
Linux: strPtr("linux"),
|
||||
Windows: strPtr("windows"),
|
||||
@@ -51,9 +49,9 @@ func TestInstallerEnviron(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContainsPlatform(t *testing.T) {
|
||||
platforms := []Platform{PlatformMacos, PlatformLinux}
|
||||
assert.True(t, ContainsPlatform(&platforms, PlatformMacos))
|
||||
assert.False(t, ContainsPlatform(&platforms, PlatformWindows))
|
||||
platforms := []platform.Platform{platform.PlatformMacos, platform.PlatformLinux}
|
||||
assert.True(t, ContainsPlatform(&platforms, platform.PlatformMacos))
|
||||
assert.False(t, ContainsPlatform(&platforms, platform.PlatformWindows))
|
||||
}
|
||||
|
||||
func TestParseConfig(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package installer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/chenasraf/sofmani/appconfig"
|
||||
"github.com/chenasraf/sofmani/logger"
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/chenasraf/sofmani/utils"
|
||||
)
|
||||
|
||||
@@ -84,23 +82,11 @@ func InstallerWithDefaults(
|
||||
return installer
|
||||
}
|
||||
|
||||
func GetCurrentPlatform() appconfig.Platform {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
return appconfig.PlatformMacos
|
||||
case "linux":
|
||||
return appconfig.PlatformLinux
|
||||
case "windows":
|
||||
return appconfig.PlatformWindows
|
||||
}
|
||||
panic(fmt.Sprintf("Unsupported platform %s", runtime.GOOS))
|
||||
}
|
||||
|
||||
func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error {
|
||||
info := installer.GetInfo()
|
||||
name := *info.Name
|
||||
logger.Debug("Checking if %s (%s) should run on %s", name, info.Type, GetCurrentPlatform())
|
||||
curOS := GetCurrentPlatform()
|
||||
curOS := platform.GetPlatform()
|
||||
logger.Debug("Checking if %s (%s) should run on %s", name, info.Type, curOS)
|
||||
env := config.Environ()
|
||||
if !GetShouldRunOnOS(installer, curOS) {
|
||||
logger.Debug("%s should not run on %s, skipping", name, curOS)
|
||||
@@ -170,7 +156,7 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetShouldRunOnOS(installer IInstaller, curOS appconfig.Platform) bool {
|
||||
func GetShouldRunOnOS(installer IInstaller, curOS platform.Platform) bool {
|
||||
platforms := installer.GetInfo().Platforms
|
||||
if platforms == nil {
|
||||
return true
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package installer
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/chenasraf/sofmani/appconfig"
|
||||
"github.com/chenasraf/sofmani/logger"
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -40,6 +42,7 @@ func (m *MockInstaller) Update() error {
|
||||
|
||||
func TestGetInstaller(t *testing.T) {
|
||||
config := &appconfig.AppConfig{}
|
||||
platform.SetOS(runtime.GOOS)
|
||||
logger.InitLogger(config.Debug)
|
||||
installer := &appconfig.Installer{Type: appconfig.InstallerTypeBrew}
|
||||
err, inst := GetInstaller(config, installer)
|
||||
@@ -60,8 +63,9 @@ func TestInstallerWithDefaults(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCurrentPlatform(t *testing.T) {
|
||||
platform := GetCurrentPlatform()
|
||||
assert.Contains(t, []appconfig.Platform{appconfig.PlatformMacos, appconfig.PlatformLinux, appconfig.PlatformWindows}, platform)
|
||||
platform.SetOS(runtime.GOOS)
|
||||
pl := platform.GetPlatform()
|
||||
assert.Contains(t, []platform.Platform{platform.PlatformMacos, platform.PlatformLinux, platform.PlatformWindows}, pl)
|
||||
}
|
||||
|
||||
func TestRunInstaller(t *testing.T) {
|
||||
@@ -77,13 +81,13 @@ func TestRunInstaller(t *testing.T) {
|
||||
func TestGetShouldRunOnOS(t *testing.T) {
|
||||
installer := &MockInstaller{
|
||||
info: &appconfig.Installer{
|
||||
Platforms: &appconfig.Platforms{
|
||||
Only: &[]appconfig.Platform{appconfig.PlatformMacos},
|
||||
Platforms: &platform.Platforms{
|
||||
Only: &[]platform.Platform{platform.PlatformMacos},
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.True(t, GetShouldRunOnOS(installer, appconfig.PlatformMacos))
|
||||
assert.False(t, GetShouldRunOnOS(installer, appconfig.PlatformLinux))
|
||||
assert.True(t, GetShouldRunOnOS(installer, platform.PlatformMacos))
|
||||
assert.False(t, GetShouldRunOnOS(installer, platform.PlatformLinux))
|
||||
}
|
||||
|
||||
func strPtr(s string) *string {
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
@@ -22,17 +22,17 @@ var logger *Logger
|
||||
|
||||
func GetLogDir() string {
|
||||
var logDir string
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformLinux:
|
||||
logDir = filepath.Join("var", "log", "sofmani")
|
||||
case "darwin":
|
||||
case platform.PlatformMacos:
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
fmt.Printf("Could not get user home directory: %v\n", err)
|
||||
panic(err)
|
||||
}
|
||||
logDir = filepath.Join(home, "Library", "Logs", "sofmani")
|
||||
case "windows":
|
||||
case platform.PlatformWindows:
|
||||
appData := os.Getenv("APPDATA")
|
||||
logDir = filepath.Join(appData, "sofmani", "Logs")
|
||||
}
|
||||
|
||||
3
main.go
3
main.go
@@ -4,17 +4,20 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/chenasraf/sofmani/appconfig"
|
||||
"github.com/chenasraf/sofmani/installer"
|
||||
"github.com/chenasraf/sofmani/logger"
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
)
|
||||
|
||||
//go:embed version.txt
|
||||
var appVersion []byte
|
||||
|
||||
func main() {
|
||||
platform.SetOS(runtime.GOOS)
|
||||
appconfig.SetVersion(strings.TrimSpace(string(appVersion)))
|
||||
cfg, err := LoadConfig()
|
||||
if err != nil {
|
||||
|
||||
74
platform/platform.go
Normal file
74
platform/platform.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package platform
|
||||
|
||||
import "fmt"
|
||||
|
||||
var osValue string
|
||||
|
||||
func getOS() string {
|
||||
return osValue
|
||||
}
|
||||
|
||||
func SetOS(v string) {
|
||||
osValue = v
|
||||
}
|
||||
|
||||
func GetPlatform() Platform {
|
||||
switch getOS() {
|
||||
case "darwin":
|
||||
return PlatformMacos
|
||||
case "linux":
|
||||
return PlatformLinux
|
||||
case "windows":
|
||||
return PlatformWindows
|
||||
}
|
||||
panic(fmt.Sprintf("Unsupported platform %s", getOS()))
|
||||
}
|
||||
|
||||
type Platforms struct {
|
||||
Only *[]Platform `json:"only" yaml:"only"`
|
||||
Except *[]Platform `json:"except" yaml:"except"`
|
||||
}
|
||||
|
||||
type Platform string
|
||||
|
||||
const (
|
||||
PlatformMacos Platform = "macos"
|
||||
PlatformLinux Platform = "linux"
|
||||
PlatformWindows Platform = "windows"
|
||||
)
|
||||
|
||||
type PlatformMap[T any] struct {
|
||||
MacOS *T `json:"macos" yaml:"macos"`
|
||||
Linux *T `json:"linux" yaml:"linux"`
|
||||
Windows *T `json:"windows" yaml:"windows"`
|
||||
}
|
||||
|
||||
func (p *PlatformMap[T]) Resolve() *T {
|
||||
switch getOS() {
|
||||
case "darwin":
|
||||
if p.MacOS != nil {
|
||||
return p.MacOS
|
||||
}
|
||||
return nil
|
||||
case "linux":
|
||||
if p.Linux != nil {
|
||||
return p.Linux
|
||||
}
|
||||
return nil
|
||||
case "windows":
|
||||
if p.Windows != nil {
|
||||
return p.Windows
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PlatformMap[T]) ResolveWithFallback(fallback PlatformMap[T]) T {
|
||||
val := o.Resolve()
|
||||
if val == nil {
|
||||
return *fallback.Resolve()
|
||||
}
|
||||
return *val
|
||||
}
|
||||
@@ -6,11 +6,10 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/chenasraf/sofmani/appconfig"
|
||||
"github.com/chenasraf/sofmani/logger"
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
)
|
||||
|
||||
const UNIX_DEFAULT_SHELL string = "bash"
|
||||
@@ -63,23 +62,23 @@ func RunCmdGetOutput(env []string, bin string, args ...string) ([]byte, error) {
|
||||
|
||||
func getShellScript(dir string) string {
|
||||
var filename string
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformWindows:
|
||||
filename = "install.bat"
|
||||
case "linux", "darwin":
|
||||
case platform.PlatformLinux, platform.PlatformMacos:
|
||||
filename = "install"
|
||||
}
|
||||
tmpfile := filepath.Join(dir, filename)
|
||||
return tmpfile
|
||||
}
|
||||
|
||||
func getScriptContents(script string, envShell *appconfig.PlatformMap[string]) (string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
func getScriptContents(script string, envShell *platform.PlatformMap[string]) (string, error) {
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformWindows:
|
||||
preScript := "@echo off"
|
||||
postScript := "exit /b %ERRORLEVEL%"
|
||||
return fmt.Sprintf("%s\n%s\n\n%s\n", preScript, script, postScript), nil
|
||||
case "linux", "darwin":
|
||||
case platform.PlatformLinux, platform.PlatformMacos:
|
||||
shell := GetOSShell(envShell)
|
||||
preScript := fmt.Sprintf("#!/usr/bin/env %s", shell)
|
||||
home, err := os.UserHomeDir()
|
||||
@@ -90,10 +89,10 @@ func getScriptContents(script string, envShell *appconfig.PlatformMap[string]) (
|
||||
postScript := "exit $?"
|
||||
return fmt.Sprintf("%s\n%s\n\n%s\n", preScript, script, postScript), nil
|
||||
}
|
||||
return "", fmt.Errorf("unsupported OS: %s", runtime.GOOS)
|
||||
return "", fmt.Errorf("unsupported OS: %s", platform.GetPlatform())
|
||||
}
|
||||
|
||||
func RunCmdAsFile(env []string, contents string, envShell *appconfig.PlatformMap[string]) error {
|
||||
func RunCmdAsFile(env []string, contents string, envShell *platform.PlatformMap[string]) error {
|
||||
tmpdir := os.TempDir()
|
||||
tmpfile := getShellScript(tmpdir)
|
||||
commandStr, err := getScriptContents(contents, envShell)
|
||||
@@ -112,26 +111,26 @@ func RunCmdAsFile(env []string, contents string, envShell *appconfig.PlatformMap
|
||||
}
|
||||
|
||||
func GetShellWhich() string {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformWindows:
|
||||
return "where"
|
||||
case "linux", "darwin":
|
||||
case platform.PlatformLinux, platform.PlatformMacos:
|
||||
return "which"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetOSShell(envShell *appconfig.PlatformMap[string]) string {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
func GetOSShell(envShell *platform.PlatformMap[string]) string {
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformWindows:
|
||||
return "cmd"
|
||||
case "linux", "darwin":
|
||||
case platform.PlatformLinux, platform.PlatformMacos:
|
||||
def := os.Getenv("SHELL")
|
||||
if def == "" {
|
||||
def = UNIX_DEFAULT_SHELL
|
||||
}
|
||||
if envShell != nil {
|
||||
return envShell.ResolveWithFallback(appconfig.PlatformMap[string]{Linux: &def, MacOS: &def})
|
||||
return envShell.ResolveWithFallback(platform.PlatformMap[string]{Linux: &def, MacOS: &def})
|
||||
}
|
||||
return def
|
||||
}
|
||||
@@ -139,10 +138,10 @@ func GetOSShell(envShell *appconfig.PlatformMap[string]) string {
|
||||
}
|
||||
|
||||
func GetOSShellArgs(cmd string) []string {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
switch platform.GetPlatform() {
|
||||
case platform.PlatformWindows:
|
||||
return []string{"/C", cmd + " & exit %ERRORLEVEL%"}
|
||||
case "linux", "darwin":
|
||||
case platform.PlatformLinux, platform.PlatformMacos:
|
||||
return []string{"-c", cmd + "; exit $?"}
|
||||
}
|
||||
return []string{}
|
||||
|
||||
Reference in New Issue
Block a user