Update Darwin system information implementation (#104361)

Instead of just showing "macOS", now show the name as declared by the
OS itself, the version, and the kernel/build version.

Reviewed-on: https://projects.blender.org/studio/flamenco/pulls/104361
Reviewed-by: Sybren A. Stüvel <sybren@blender.org>
This commit is contained in:
Srivathsav-Kyatham 2025-03-25 10:45:57 +01:00 committed by Sybren A. Stüvel
parent 97109a6c92
commit 4be5c1ca5b
2 changed files with 187 additions and 4 deletions

View File

@ -2,13 +2,75 @@ package sysinfo
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// canSymlink always returns true, as symlinking on non-Windows platforms is not import (
// hard. "encoding/xml"
"fmt"
"os"
"strings"
"github.com/rs/zerolog/log"
)
type PlistData struct {
XMLName xml.Name `xml:"plist"`
Dict Dict `xml:"dict"`
}
type Dict struct {
Keys []string `xml:"key"`
Strings []string `xml:"string"`
}
// canSymlink always returns true, as symlinking on non-Windows platforms is not hard.
func canSymlink() (bool, error) { func canSymlink() (bool, error) {
return true, nil return true, nil
} }
func description() (string, error) { func description() (string, error) {
// TODO: figure out how to get more info on macOS. plistFile := "/System/Library/CoreServices/SystemVersion.plist"
return "macOS", nil info, err := getSystemInfo(plistFile)
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve system information")
return "macOS", nil
}
return info, nil
}
func getSystemInfo(plistFile string) (string, error) {
data, err := os.ReadFile(plistFile)
if err != nil {
return "", fmt.Errorf("could not read system info file %s: %w", plistFile, err)
}
var plist PlistData
if err := xml.Unmarshal(data, &plist); err != nil {
return "", fmt.Errorf("failed to read system info from %s: %w", plistFile, err)
}
productName := "macOS"
var productVersion, buildVersion string
for i, key := range plist.Dict.Keys {
if i >= len(plist.Dict.Strings) {
break
}
switch key {
case "ProductName":
productName = plist.Dict.Strings[i]
case "ProductVersion":
productVersion = plist.Dict.Strings[i]
case "ProductBuildVersion":
buildVersion = plist.Dict.Strings[i]
}
}
parts := []string{productName}
if productVersion != "" {
parts = append(parts, productVersion)
}
if buildVersion != "" {
parts = append(parts, fmt.Sprintf("(Build %s)", buildVersion))
}
return strings.Join(parts, " "), nil
} }

View File

@ -0,0 +1,121 @@
package sysinfo
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetSystemInfo_ValidPlist(t *testing.T) {
plistContent := `<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>ProductName</key>
<string>macOS</string>
<key>ProductVersion</key>
<string>15.3.1</string>
<key>ProductBuildVersion</key>
<string>24D70</string>
</dict>
</plist>`
tempFile, cleanup := createTempPlist(t, plistContent)
defer cleanup()
expected := "macOS 15.3.1 (Build 24D70)"
result, err := getSystemInfo(tempFile)
assert.NoError(t, err)
assert.Equal(t, expected, result)
}
func TestGetSystemInfo_NoProductName(t *testing.T) {
plistContent := `<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>ProductVersion</key>
<string>15.3.1</string>
<key>ProductBuildVersion</key>
<string>24D70</string>
</dict>
</plist>`
tempFile, cleanup := createTempPlist(t, plistContent)
defer cleanup()
expected := "macOS 15.3.1 (Build 24D70)"
result, err := getSystemInfo(tempFile)
assert.NoError(t, err)
assert.Equal(t, expected, result)
}
func TestGetSystemInfo_OnlyProductName(t *testing.T) {
plistContent := `<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>ProductName</key>
<string>macOS Custom</string>
</dict>
</plist>`
tempFile, cleanup := createTempPlist(t, plistContent)
defer cleanup()
expected := "macOS Custom"
result, err := getSystemInfo(tempFile)
assert.NoError(t, err)
assert.Equal(t, expected, result)
}
func TestGetSystemInfo_EmptyDict(t *testing.T) {
plistContent := `<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict></dict>
</plist>`
tempFile, cleanup := createTempPlist(t, plistContent)
defer cleanup()
expected := "macOS"
result, err := getSystemInfo(tempFile)
assert.NoError(t, err)
assert.Equal(t, expected, result)
}
func TestGetSystemInfo_InvalidXML(t *testing.T) {
plistContent := `INVALID_XML_DATA`
tempFile, cleanup := createTempPlist(t, plistContent)
defer cleanup()
_, err := getSystemInfo(tempFile)
assert.Error(t, err)
}
func TestGetSystemInfo_FileNotFound(t *testing.T) {
_, err := getSystemInfo("/path/to/nonexistent.plist")
assert.Error(t, err)
}
func createTempPlist(t *testing.T, content string) (string, func()) {
tempFile, err := os.CreateTemp("", "test_plist_*.plist")
assert.NoError(t, err)
_, err = tempFile.WriteString(content)
assert.NoError(t, err)
err = tempFile.Close()
assert.NoError(t, err)
cleanup := func() {
os.Remove(tempFile.Name())
}
return tempFile.Name(), cleanup
}