fix(browser): support macOS core bundle paths

This commit is contained in:
voidvon
2026-04-03 18:33:41 +08:00
parent 3d264eb83d
commit 2b17605460
2 changed files with 142 additions and 0 deletions
+63
View File
@@ -31,6 +31,12 @@ func FindCoreExecutable(baseDir string) (string, string, bool) {
if baseDir == "" {
return "", "", false
}
if directPath, directCandidate, ok := findDirectCoreExecutable(baseDir); ok {
return directPath, directCandidate, true
}
if bundlePath, bundleCandidate, ok := findAppBundleExecutable(baseDir); ok {
return bundlePath, bundleCandidate, true
}
for _, candidate := range CoreExecutableCandidates() {
p := filepath.Join(baseDir, filepath.FromSlash(candidate))
if _, err := os.Stat(p); err == nil {
@@ -39,3 +45,60 @@ func FindCoreExecutable(baseDir string) (string, string, bool) {
}
return "", "", false
}
func findDirectCoreExecutable(path string) (string, string, bool) {
info, err := os.Stat(path)
if err != nil || info.IsDir() {
return "", "", false
}
normalized := filepath.ToSlash(filepath.Clean(path))
for _, candidate := range CoreExecutableCandidates() {
candidatePath := filepath.ToSlash(candidate)
if strings.HasSuffix(normalized, candidatePath) || filepath.Base(normalized) == filepath.Base(candidatePath) {
return path, candidate, true
}
}
return "", "", false
}
func findAppBundleExecutable(path string) (string, string, bool) {
if goruntime.GOOS != "darwin" {
return "", "", false
}
info, err := os.Stat(path)
if err != nil || !info.IsDir() {
return "", "", false
}
normalized := filepath.ToSlash(filepath.Clean(path))
if !strings.HasSuffix(strings.ToLower(normalized), ".app") {
return "", "", false
}
for _, candidate := range CoreExecutableCandidates() {
candidatePath := filepath.ToSlash(candidate)
appMarker := ".app/"
index := strings.Index(strings.ToLower(candidatePath), appMarker)
if index < 0 {
continue
}
if !strings.EqualFold(filepath.Base(normalized), filepath.Base(candidatePath[:index+len(".app")])) {
continue
}
relativeExecutable := candidatePath[index+len(appMarker):]
if relativeExecutable == "" {
continue
}
p := filepath.Join(path, filepath.FromSlash(relativeExecutable))
if _, err := os.Stat(p); err == nil {
return p, candidate, true
}
}
return "", "", false
}
+79
View File
@@ -4,6 +4,7 @@ import (
"ant-chrome/backend/internal/config"
"os"
"path/filepath"
"runtime"
"testing"
)
@@ -103,6 +104,84 @@ func TestResolveChromeBinaryNormalizesWindowsStyleRelativeCorePath(t *testing.T)
}
}
func TestResolveChromeBinaryAcceptsDirectExecutablePath(t *testing.T) {
t.Parallel()
root := t.TempDir()
coreDir := filepath.Join(root, "chrome-direct")
if err := os.MkdirAll(coreDir, 0o755); err != nil {
t.Fatalf("创建内核目录失败: %v", err)
}
exePath := filepath.Join(coreDir, filepath.FromSlash(CoreExecutableCandidates()[0]))
if err := os.MkdirAll(filepath.Dir(exePath), 0o755); err != nil {
t.Fatalf("创建可执行文件目录失败: %v", err)
}
if err := os.WriteFile(exePath, []byte("stub"), 0o755); err != nil {
t.Fatalf("写入可执行文件失败: %v", err)
}
cfg := config.DefaultConfig()
mgr := NewManager(cfg, root)
mgr.CoreDAO = &coreDAOStub{
list: []Core{
{
CoreId: "core-direct",
CoreName: "Chrome Direct",
CorePath: exePath,
IsDefault: true,
},
},
}
got, err := mgr.ResolveChromeBinary(&Profile{})
if err != nil {
t.Fatalf("ResolveChromeBinary 返回错误: %v", err)
}
if got != exePath {
t.Fatalf("ResolveChromeBinary 路径错误: got=%q want=%q", got, exePath)
}
}
func TestResolveChromeBinaryAcceptsDarwinAppBundlePath(t *testing.T) {
t.Parallel()
if runtime.GOOS != "darwin" {
t.Skip("仅验证 darwin .app 路径解析")
}
root := t.TempDir()
appDir := filepath.Join(root, "Chromium.app")
exePath := filepath.Join(appDir, "Contents", "MacOS", "Chromium")
if err := os.MkdirAll(filepath.Dir(exePath), 0o755); err != nil {
t.Fatalf("创建可执行文件目录失败: %v", err)
}
if err := os.WriteFile(exePath, []byte("stub"), 0o755); err != nil {
t.Fatalf("写入可执行文件失败: %v", err)
}
cfg := config.DefaultConfig()
mgr := NewManager(cfg, root)
mgr.CoreDAO = &coreDAOStub{
list: []Core{
{
CoreId: "core-app",
CoreName: "Chromium App",
CorePath: appDir,
IsDefault: true,
},
},
}
got, err := mgr.ResolveChromeBinary(&Profile{})
if err != nil {
t.Fatalf("ResolveChromeBinary 返回错误: %v", err)
}
if got != exePath {
t.Fatalf("ResolveChromeBinary 路径错误: got=%q want=%q", got, exePath)
}
}
func TestCountInstancesByCoreTreatsLegacyDefaultReferenceAsDefault(t *testing.T) {
t.Parallel()