package platform import ( "os/exec" "runtime" "strings" "sync" "gitgud.io/mike/mpv-manager/pkg/log" ) type OSType string const ( Windows OSType = "windows" Darwin OSType = "darwin" Linux OSType = "linux" ) type Platform struct { OSType OSType Arch string Distro string DistroFamily string Version string CPUInfo CPUInfo GPUInfo *GPUInfo } type CPUInfo struct { Vendor string VendorDisplay string ArchitectureLevel string Model string Features []string SupportsAVX2 bool SupportsAVX512 bool SupportsNEON bool } func Detect() *Platform { p := &Platform{ OSType: getOSType(), Arch: runtime.GOARCH, } if p.OSType == Linux { p.Distro, p.DistroFamily = detectLinuxDistro() } // Run CPU and GPU detection concurrently var cpuInfo CPUInfo var gpuInfo *GPUInfo var wg sync.WaitGroup wg.Add(2) // Detect CPU in goroutine go func() { defer wg.Done() cpuInfo = detectCPU() }() // Detect GPU in goroutine go func() { defer wg.Done() gpuInfo = detectGPU() }() // Wait for both detections to complete wg.Wait() p.CPUInfo = cpuInfo p.GPUInfo = gpuInfo if p.OSType == Darwin { p.Version = detectMacOSVersion() } return p } func getOSType() OSType { switch runtime.GOOS { case "windows": return Windows case "darwin": return Darwin default: return Linux } } func (p *Platform) getOSTypeDisplay() string { switch p.OSType { case Darwin: return "macOS" default: return string(p.OSType) } } func (p *Platform) IsWindows() bool { return p.OSType == Windows } func (p *Platform) IsDarwin() bool { return p.OSType == Darwin } func (p *Platform) IsLinux() bool { return p.OSType == Linux } // GetCPULevel returns the CPU architecture level for binary selection // Returns "x86-64-v3" for AVX2 support, "x86-64" for baseline, or "arm64" for ARM func (p *Platform) GetCPULevel() string { return p.CPUInfo.ArchitectureLevel } // GetDetectedCPULevel returns the detected CPU architecture level // This creates a new Platform detection to get the CPU level func GetDetectedCPULevel() string { p := Detect() return p.CPUInfo.ArchitectureLevel } // Cached platform for GetCPULevel function var detectedPlatform *Platform var detectOnce sync.Once // GetCPULevel returns the CPU architecture level (cached) func GetCPULevel() string { detectOnce.Do(func() { detectedPlatform = Detect() }) return detectedPlatform.CPUInfo.ArchitectureLevel } func (p *Platform) IsImmutableDistro() bool { if p.OSType != Linux { return false } immutableDistros := []string{ "fedora-atomic", "fedora-silverblue", "fedora-kinoite", "endless", "vanilla", "bluefin", "bazzite", "universal-blue", "aurora", "cosmic", } for _, distro := range immutableDistros { if strings.Contains(strings.ToLower(p.Distro), distro) { return true } } return false } func detectMacOSVersion() string { if runtime.GOOS != "darwin" { return "" } output, err := exec.Command("sw_vers", "-productVersion").Output() if err != nil { log.Debug("Failed to get macOS version: " + err.Error()) return "" } return strings.TrimSpace(string(output)) } func getMacOSVersionName(version string) string { macosNames := map[string]string{ "10.0": "Cheetah", "10.1": "Puma", "10.2": "Jaguar", "10.3": "Panther", "10.4": "Tiger", "10.5": "Leopard", "10.6": "Snow Leopard", "10.7": "Lion", "10.8": "Mountain Lion", "10.9": "Mavericks", "10.10": "Yosemite", "10.11": "El Capitan", "10.12": "Sierra", "10.13": "High Sierra", "10.14": "Mojave", "10.15": "Catalina", "11": "Big Sur", "12": "Monterey", "13": "Ventura", "14": "Sonoma", "15": "Sequoia", "26": "Tahoe", } if name, ok := macosNames[version]; ok { return name } return version } func (p *Platform) String() string { var sb strings.Builder sb.WriteString(p.getOSTypeDisplay()) if p.OSType == Darwin { sb.WriteString(" ") sb.WriteString(p.Version) if versionName := getMacOSVersionName(p.Version); versionName != "" && versionName != p.Version { sb.WriteString(" - ") sb.WriteString(versionName) } if p.CPUInfo.Model != "" { sb.WriteString(" (") sb.WriteString(p.CPUInfo.Model) sb.WriteString(")") } } else { sb.WriteString(" ") sb.WriteString(p.Arch) } if p.OSType == Linux && p.Distro != "" { sb.WriteString(" (") sb.WriteString(p.Distro) if p.DistroFamily != "" { sb.WriteString("/") sb.WriteString(p.DistroFamily) } sb.WriteString(")") } return sb.String() }