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:
parent
97109a6c92
commit
4be5c1ca5b
@ -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
|
||||||
}
|
}
|
||||||
|
121
pkg/sysinfo/sysinfo_darwin_test.go
Normal file
121
pkg/sysinfo/sysinfo_darwin_test.go
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user