Skip to content

Commit 2ab0b37

Browse files
committed
fix(build): avoid compile-time VisionOS enum references
1 parent a2a5edf commit 2ab0b37

4 files changed

Lines changed: 127 additions & 14 deletions

File tree

MCPForUnity/Editor/Tools/Build/BuildTargetMapping.cs

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
using System;
12
using UnityEditor;
23
using UnityEditor.Build;
34

45
namespace MCPForUnity.Editor.Tools.Build
56
{
67
public static class BuildTargetMapping
78
{
9+
private const string VisionOSName = "VisionOS";
10+
811
public static bool TryResolveBuildTarget(string name, out BuildTarget target)
912
{
1013
if (string.IsNullOrEmpty(name))
@@ -24,12 +27,8 @@ public static bool TryResolveBuildTarget(string name, out BuildTarget target)
2427
case "webgl": target = BuildTarget.WebGL; return true;
2528
case "uwp": target = BuildTarget.WSAPlayer; return true;
2629
case "tvos": target = BuildTarget.tvOS; return true;
27-
// BuildTarget.VisionOS exists only in Unity 2023.2+ and late 2022.3 patches
28-
#if UNITY_2023_2_OR_NEWER
29-
case "visionos": target = BuildTarget.VisionOS; return true;
30-
#endif
3130
default:
32-
if (System.Enum.TryParse(name, true, out target))
31+
if (Enum.TryParse(name, true, out target))
3332
return true;
3433
target = default;
3534
return false;
@@ -50,10 +49,14 @@ public static BuildTargetGroup GetTargetGroup(BuildTarget target)
5049
case BuildTarget.WebGL: return BuildTargetGroup.WebGL;
5150
case BuildTarget.WSAPlayer: return BuildTargetGroup.WSA;
5251
case BuildTarget.tvOS: return BuildTargetGroup.tvOS;
53-
#if UNITY_2023_2_OR_NEWER
54-
case BuildTarget.VisionOS: return BuildTargetGroup.VisionOS;
55-
#endif
56-
default: return BuildTargetGroup.Unknown;
52+
default:
53+
if (IsVisionOSTarget(target)
54+
&& Enum.TryParse(VisionOSName, true, out BuildTargetGroup visionOSGroup))
55+
{
56+
return visionOSGroup;
57+
}
58+
59+
return BuildTargetGroup.Unknown;
5760
}
5861
}
5962

@@ -67,12 +70,49 @@ public static string TryResolveNamedBuildTarget(string name, out NamedBuildTarge
6770
if (!TryResolveBuildTarget(name, out var buildTarget))
6871
{
6972
namedTarget = default;
70-
return $"Unknown build target: '{name}'. Valid targets: windows64, osx, linux64, android, ios, webgl, uwp, tvos, visionos";
73+
return GetUnknownBuildTargetMessage(name);
74+
}
75+
76+
var targetGroup = GetTargetGroup(buildTarget);
77+
if (targetGroup == BuildTargetGroup.Unknown)
78+
{
79+
namedTarget = default;
80+
return IsVisionOSTarget(buildTarget)
81+
? "VisionOS build target is available, but its BuildTargetGroup is not exposed by this Unity editor installation."
82+
: $"Build target group could not be resolved for target '{buildTarget}'.";
7183
}
72-
namedTarget = GetNamedBuildTarget(buildTarget);
84+
85+
namedTarget = NamedBuildTarget.FromBuildTargetGroup(targetGroup);
7386
return null;
7487
}
7588

89+
public static string GetUnknownBuildTargetMessage(string name)
90+
{
91+
if (string.Equals(name, "visionos", StringComparison.OrdinalIgnoreCase))
92+
{
93+
return "VisionOS build target is not available in this Unity editor installation. "
94+
+ "Install the visionOS build support module or use a Unity version/configuration that exposes BuildTarget.VisionOS.";
95+
}
96+
97+
return $"Unknown build target: '{name}'. Valid targets: {GetValidTargetsList()}.";
98+
}
99+
100+
private static string GetValidTargetsList()
101+
{
102+
string validTargets = "windows64, osx, linux64, android, ios, webgl, uwp, tvos";
103+
if (Enum.TryParse(VisionOSName, true, out BuildTarget _))
104+
{
105+
validTargets += ", visionos";
106+
}
107+
108+
return validTargets;
109+
}
110+
111+
private static bool IsVisionOSTarget(BuildTarget target)
112+
{
113+
return string.Equals(target.ToString(), VisionOSName, StringComparison.OrdinalIgnoreCase);
114+
}
115+
76116
public static string GetDefaultOutputPath(BuildTarget target, string productName)
77117
{
78118
string basePath = $"Builds/{target}";

MCPForUnity/Editor/Tools/ManageBuild.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private static object HandleBuild(ToolParams p)
6464

6565
string targetName = p.Get("target");
6666
if (!BuildTargetMapping.TryResolveBuildTarget(targetName, out var target))
67-
return new ErrorResponse($"Unknown target '{targetName}'.");
67+
return new ErrorResponse(BuildTargetMapping.GetUnknownBuildTargetMessage(targetName));
6868

6969
var group = BuildTargetMapping.GetTargetGroup(target);
7070
if (!BuildPipeline.IsBuildTargetSupported(group, target))
@@ -221,7 +221,7 @@ private static object HandlePlatform(ToolParams p)
221221

222222
// Switch platform
223223
if (!BuildTargetMapping.TryResolveBuildTarget(targetName, out var target))
224-
return new ErrorResponse($"Unknown target '{targetName}'.");
224+
return new ErrorResponse(BuildTargetMapping.GetUnknownBuildTargetMessage(targetName));
225225

226226
var group = BuildTargetMapping.GetTargetGroup(target);
227227
if (!BuildPipeline.IsBuildTargetSupported(group, target))
@@ -442,7 +442,7 @@ private static object HandleBatch(ToolParams p)
442442
foreach (var t in targets)
443443
{
444444
if (!BuildTargetMapping.TryResolveBuildTarget(t, out var bt))
445-
return new ErrorResponse($"Unknown target '{t}' in batch.");
445+
return new ErrorResponse(BuildTargetMapping.GetUnknownBuildTargetMessage(t));
446446
var btGroup = BuildTargetMapping.GetTargetGroup(bt);
447447
if (!BuildPipeline.IsBuildTargetSupported(btGroup, bt))
448448
return new ErrorResponse(
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using MCPForUnity.Editor.Tools.Build;
3+
using NUnit.Framework;
4+
using UnityEditor;
5+
6+
namespace MCPForUnity.Tests.EditMode.Tools
7+
{
8+
[TestFixture]
9+
public class BuildTargetMappingTests
10+
{
11+
[TestCase("windows64", BuildTarget.StandaloneWindows64)]
12+
[TestCase("macos", BuildTarget.StandaloneOSX)]
13+
[TestCase("linux", BuildTarget.StandaloneLinux64)]
14+
[TestCase("tvos", BuildTarget.tvOS)]
15+
public void TryResolveBuildTarget_KnownAliasesResolve(string name, BuildTarget expected)
16+
{
17+
Assert.IsTrue(BuildTargetMapping.TryResolveBuildTarget(name, out var target));
18+
Assert.AreEqual(expected, target);
19+
}
20+
21+
[Test]
22+
public void TryResolveNamedBuildTarget_UnknownTargetListsOnlyAvailableTargets()
23+
{
24+
string error = BuildTargetMapping.TryResolveNamedBuildTarget("not-a-target", out _);
25+
26+
Assert.IsNotNull(error);
27+
StringAssert.Contains("windows64", error);
28+
29+
bool visionOSAvailable = Enum.TryParse("VisionOS", true, out BuildTarget _);
30+
if (visionOSAvailable)
31+
{
32+
StringAssert.Contains("visionos", error);
33+
}
34+
else
35+
{
36+
Assert.IsFalse(error.Contains("visionos"));
37+
}
38+
}
39+
40+
[Test]
41+
public void TryResolveNamedBuildTarget_VisionOSUnavailableReturnsHelpfulError()
42+
{
43+
bool visionOSAvailable = Enum.TryParse("VisionOS", true, out BuildTarget _);
44+
string error = BuildTargetMapping.TryResolveNamedBuildTarget("visionos", out _);
45+
46+
if (visionOSAvailable)
47+
{
48+
Assert.IsTrue(BuildTargetMapping.TryResolveBuildTarget("visionos", out _));
49+
if (error != null)
50+
{
51+
StringAssert.Contains("VisionOS", error);
52+
}
53+
}
54+
else
55+
{
56+
Assert.IsFalse(BuildTargetMapping.TryResolveBuildTarget("visionos", out _));
57+
Assert.IsNotNull(error);
58+
StringAssert.Contains("VisionOS build target is not available", error);
59+
}
60+
}
61+
}
62+
}

TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/BuildTargetMappingTests.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)