feat(doctor): split iOS checks into simulator and physical-device paths

This commit is contained in:
pj committed 2026-06-06 23:45:13 +05:30
1 parent 30c84288f5
commit 02bbeb8190
2 files changed
+42 -9

No files matched your search

+21 -8
View File
@@ -33,6 +33,8 @@ func doctorChecksFor(platform string) []doctorCheck {
return androidChecks() return androidChecks()
case "ios": case "ios":
return iosChecks() return iosChecks()
case "ios-device":
return append(iosChecks(), iosDeviceChecks()...)
case "all": case "all":
return allChecks() return allChecks()
default: default:
@@ -55,19 +57,30 @@ func androidChecks() []doctorCheck {
} }
} }
// iosChecks covers the simulator path, which the native companion drives with
// no JVM. A simulator host with no Java still passes. Physical-device runs
// additionally need java and the sidecar JAR, covered by iosDeviceChecks and
// surfaced through the "all" union.
func iosChecks() []doctorCheck { func iosChecks() []doctorCheck {
return []doctorCheck{ return []doctorCheck{
{Name: "xcrun on PATH", Run: checkExecutableOnPath("xcrun")}, {Name: "xcrun on PATH (ios simulator)", Run: checkExecutableOnPath("xcrun")},
{Name: "simctl on PATH", Run: checkExecutableOnPath("simctl")}, {Name: "simctl on PATH (ios simulator)", Run: checkExecutableOnPath("simctl")},
{Name: "java 17+ on PATH", Run: checkJavaVersion}, }
{Name: "sidecar JAR is real (not placeholder)", Run: checkSidecarJAR}, }
// iosDeviceChecks covers the extra prerequisites a physical iOS device needs:
// the JVM and a real sidecar JAR for the sidecar driver path.
func iosDeviceChecks() []doctorCheck {
return []doctorCheck{
{Name: "java 17+ on PATH (ios physical device)", Run: checkJavaVersion},
{Name: "sidecar JAR is real (ios physical device)", Run: checkSidecarJAR},
} }
} }
func allChecks() []doctorCheck { func allChecks() []doctorCheck {
seen := map[string]bool{} seen := map[string]bool{}
var combined []doctorCheck var combined []doctorCheck
for _, group := range [][]doctorCheck{webChecks(), androidChecks(), iosChecks()} { for _, group := range [][]doctorCheck{webChecks(), androidChecks(), iosChecks(), iosDeviceChecks()} {
for _, c := range group { for _, c := range group {
if seen[c.Name] { if seen[c.Name] {
continue continue
@@ -116,15 +129,15 @@ func parseDoctorArgs(args []string, stderr io.Writer) (doctorOptions, error) {
flagSet := flag.NewFlagSet("doctor", flag.ContinueOnError) flagSet := flag.NewFlagSet("doctor", flag.ContinueOnError)
flagSet.SetOutput(stderr) flagSet.SetOutput(stderr)
var options doctorOptions var options doctorOptions
flagSet.StringVar(&options.platform, "platform", "all", "target platform: web, android, ios, all") flagSet.StringVar(&options.platform, "platform", "all", "target platform: web, android, ios, ios-device, all")
if err := flagSet.Parse(args); err != nil { if err := flagSet.Parse(args); err != nil {
return doctorOptions{}, err return doctorOptions{}, err
} }
switch options.platform { switch options.platform {
case "web", "android", "ios", "all": case "web", "android", "ios", "ios-device", "all":
return options, nil return options, nil
default: default:
return doctorOptions{}, fmt.Errorf("unsupported platform: %q (web, android, ios, all)", options.platform) return doctorOptions{}, fmt.Errorf("unsupported platform: %q (web, android, ios, ios-device, all)", options.platform)
} }
} }
+21 -1
View File
@@ -127,13 +127,33 @@ func TestDoctorChecksFor_All_IsUnion(t *testing.T) {
for _, c := range all { for _, c := range all {
names[c.Name]++ names[c.Name]++
} }
for _, name := range []string{"adb on PATH", "xcrun on PATH", "headless chromium can launch"} { for _, name := range []string{"adb on PATH", "xcrun on PATH (ios simulator)", "headless chromium can launch"} {
if names[name] != 1 { if names[name] != 1 {
t.Errorf("expected %q in 'all' exactly once, got %d", name, names[name]) t.Errorf("expected %q in 'all' exactly once, got %d", name, names[name])
} }
} }
} }
func TestDoctorChecksFor_iOSSimulator_OmitsJava(t *testing.T) {
for _, c := range doctorChecksFor("ios") {
if strings.Contains(c.Name, "java") || strings.Contains(c.Name, "sidecar") {
t.Errorf("ios simulator checks must omit %q; simulator runs need no JVM", c.Name)
}
}
}
func TestDoctorChecksFor_iOSDevice_IncludesJava(t *testing.T) {
found := false
for _, c := range doctorChecksFor("ios-device") {
if strings.Contains(c.Name, "java") {
found = true
}
}
if !found {
t.Error("ios-device checks must include java for the sidecar path")
}
}
func TestDoctorChecksFor_UnknownPlatform(t *testing.T) { func TestDoctorChecksFor_UnknownPlatform(t *testing.T) {
if got := doctorChecksFor("fuchsia"); got != nil { if got := doctorChecksFor("fuchsia"); got != nil {
t.Errorf("expected nil for unknown platform, got %+v", got) t.Errorf("expected nil for unknown platform, got %+v", got)