From 70dbb1c4fa7b5a632e427422631e5eaeb7a37089 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Fri, 4 Jul 2025 00:15:44 +0300 Subject: [PATCH] refactor: improve platform map parsing --- Makefile | 26 +++++++++++++++++ installer/docker_installer.go | 8 ++---- installer/github_release_installer.go | 14 ++-------- installer/installer_defaults.go | 21 ++++---------- platform/platform.go | 40 +++++++++++++++++++++++++-- 5 files changed, 74 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 3b83f1c..431bd66 100644 --- a/Makefile +++ b/Makefile @@ -17,3 +17,29 @@ install: build .PHONY: uninstall uninstall: rm -f ~/.local/bin/sofmani + +.PHONY: precommit-install +precommit-install: + @echo "Installing pre-commit hooks..." + @echo "#!/bin/sh\n\nmake precommit" > .git/hooks/pre-commit + @chmod +x .git/hooks/pre-commit + @echo "Pre-commit hooks installed." + +.PHONY: precommit +precommit: + @STAGED_FILES=$$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.go$$'); \ + if [ -z "$$STAGED_FILES" ]; then \ + echo "No staged Go files to check."; \ + else \ + echo "Running pre-commit checks..."; \ + echo "go fmt"; \ + go fmt ./...; \ + echo "go vet"; \ + go vet ./...; \ + echo "gofmt"; \ + gofmt -w ./...; \ + echo "golangci-lint"; \ + golangci-lint run ./...; \ + echo "go test"; \ + go test -v ./...; \ + fi diff --git a/installer/docker_installer.go b/installer/docker_installer.go index a07a6c5..ab70c09 100644 --- a/installer/docker_installer.go +++ b/installer/docker_installer.go @@ -112,12 +112,8 @@ func (i *DockerInstaller) GetOpts() *DockerOpts { if flags, ok := (*i.Info.Opts)["flags"].(string); ok { opts.Flags = &flags } - if platformMap, ok := (*i.Info.Opts)["platform"].(map[string]*string); ok { - opts.Platform = &platform.PlatformMap[string]{ - MacOS: platformMap["macos"], - Linux: platformMap["linux"], - Windows: platformMap["windows"], - } + if raw, ok := (*i.Info.Opts)["platform"]; ok && raw != nil { + opts.Platform = platform.NewPlatformMap[string](raw) } } if skip, ok := (*i.Info.Opts)["skip_if_unavailable"].(bool); ok { diff --git a/installer/github_release_installer.go b/installer/github_release_installer.go index 8cb54c1..379af27 100644 --- a/installer/github_release_installer.go +++ b/installer/github_release_installer.go @@ -298,18 +298,8 @@ func (i *GitHubReleaseInstaller) GetOpts() *GitHubReleaseOpts { destination = utils.GetRealPath(i.GetData().Environ(), destination) opts.Destination = &destination } - if filename, ok := (*info.Opts)["download_filename"].(string); ok { - opts.DownloadFilename = &platform.PlatformMap[string]{ - MacOS: &filename, - Linux: &filename, - Windows: &filename, - } - } else if filenameMap, ok := (*info.Opts)["download_filename"].(map[string]*string); ok { - opts.DownloadFilename = &platform.PlatformMap[string]{ - MacOS: filenameMap["macos"], - Linux: filenameMap["linux"], - Windows: filenameMap["windows"], - } + if filename, ok := (*info.Opts)["download_filename"]; ok { + opts.DownloadFilename = platform.NewPlatformMap[string](filename) } if strategy, ok := (*info.Opts)["strategy"].(string); ok { strat := GitHubReleaseInstallStrategy(strings.ToLower(strategy)) diff --git a/installer/installer_defaults.go b/installer/installer_defaults.go index 01aef2d..74c3355 100644 --- a/installer/installer_defaults.go +++ b/installer/installer_defaults.go @@ -4,6 +4,7 @@ import ( "github.com/chenasraf/sofmani/appconfig" "github.com/chenasraf/sofmani/logger" "github.com/chenasraf/sofmani/platform" + "maps" ) // InstallerWithDefaults applies default configurations to an installer data object. @@ -23,37 +24,27 @@ func InstallerWithDefaults( if override.Opts != nil { source := *override.Opts target := *data.Opts - for k, v := range source { - target[k] = v - } + maps.Copy(target, source) } if override.Env != nil { source := *override.Env target := *data.Env - for k, v := range source { - target[k] = v - } + maps.Copy(target, source) } if override.PlatformEnv != nil { source := *override.PlatformEnv targetBase := *data.PlatformEnv if source.MacOS != nil && targetBase.MacOS != nil { target := *targetBase.MacOS - for k, v := range *source.MacOS { - target[k] = v - } + maps.Copy(target, *source.MacOS) } if source.Linux != nil && targetBase.Linux != nil { target := *targetBase.Linux - for k, v := range *source.Linux { - target[k] = v - } + maps.Copy(target, *source.Linux) } if source.Windows != nil && targetBase.Windows != nil { target := *targetBase.Windows - for k, v := range *source.Windows { - target[k] = v - } + maps.Copy(target, *source.Windows) } } if override.EnvShell != nil { diff --git a/platform/platform.go b/platform/platform.go index 091bf73..e86272f 100644 --- a/platform/platform.go +++ b/platform/platform.go @@ -132,8 +132,17 @@ var DockerOSMap = PlatformMap[string]{ Windows: strPtr("windows"), } -// NewPlatformMap creates a new PlatformMap from a map of platform strings to values. -func NewPlatformMap[T any](values map[string]T) *PlatformMap[T] { +// ParsePlatformSingleValue creates a new PlatformMap with the value for all platforms +func ParsePlatformSingleValue[T any](value T) *PlatformMap[T] { + p := &PlatformMap[T]{} + p.MacOS = &value + p.Linux = &value + p.Windows = &value + return p +} + +// ParselatformMap creates a PlatformMap from a map of platform strings to values. +func ParselatformMap[T any](values map[string]T) *PlatformMap[T] { p := &PlatformMap[T]{} for k, v := range values { val := v // capture value for pointer @@ -150,3 +159,30 @@ func NewPlatformMap[T any](values map[string]T) *PlatformMap[T] { } return p } + +// NewPlatformMap creates a new PlatformMap from either a single value or a map. +func NewPlatformMap[T any](input any) *PlatformMap[T] { + switch v := input.(type) { + case T: + return ParsePlatformSingleValue(v) + case *T: + if v != nil { + return ParsePlatformSingleValue(*v) + } + return nil + case map[string]T: + return ParselatformMap(v) + case map[string]*T: + flat := make(map[string]T) + for k, ptr := range v { + if ptr != nil { + flat[k] = *ptr + } + } + return ParselatformMap(flat) + case nil: + return nil + default: + panic(fmt.Sprintf("NewPlatformMap: unsupported input type %T", input)) + } +}