diff --git a/README.md b/README.md index 3a60082..6d00f2f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A terminal command to open Unity projects quickly from the command line. - macOS - Windows -- Linux +- Linux (TBD) ## Commands diff --git a/src/ucll.tests/PlatformSupportTests.cs b/src/ucll.tests/PlatformSupportTests.cs index 2b72b00..6c6bb78 100644 --- a/src/ucll.tests/PlatformSupportTests.cs +++ b/src/ucll.tests/PlatformSupportTests.cs @@ -1,25 +1,16 @@ -using System.Runtime.InteropServices; - public class PlatformSupportTests { - [Fact_PlatformOSX] - public void FindInstallationRootReturnsValidRoot() + [Theory] + [InlineData(typeof(MacSupport), + "/Applications/Unity/Hub/Editor/2022.3.10f1/Unity.app/Contents/MacOS/Unity", + "/Applications/Unity/Hub/Editor/2022.3.10f1")] + [InlineData(typeof(WindowsSupport), + @"C:\Program Files\Unity\Hub\Editor\6000.0.59f2\Editor\Unity.exe", + @"C:\Program Files\Unity\Hub\Editor\6000.0.59f2")] + public void FindInstallationRootReturnsValidRoot(Type platformSupportType, string editorPath, string expectedRoot) { - PlatformSupport platformSupport = PlatformSupport.Create(); - const string editorPath = "/Applications/Unity/Hub/Editor/2022.3.10f1/Unity.app/Contents/MacOS/Unity"; + PlatformSupport platformSupport = (Activator.CreateInstance(platformSupportType) as PlatformSupport)!; string root = platformSupport.FindInstallationRoot(editorPath); - Assert.Equal("/Applications/Unity/Hub/Editor/2022.3.10f1", root); - } - - // ReSharper disable once InconsistentNaming - private sealed class Fact_PlatformOSX : FactAttribute - { - public Fact_PlatformOSX() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - Skip = "Test only runs on macOS"; - } - } + Assert.Equal(expectedRoot, root); } } \ No newline at end of file diff --git a/src/ucll/Shared/Platform/LinuxSupport.cs b/src/ucll/Shared/Platform/LinuxSupport.cs index bb57d38..f182a6b 100644 --- a/src/ucll/Shared/Platform/LinuxSupport.cs +++ b/src/ucll/Shared/Platform/LinuxSupport.cs @@ -1,5 +1,10 @@ internal sealed class LinuxSupport : PlatformSupport { + public override string FindInstallationRoot(string editorPath) + { + throw new NotImplementedException(); + } + public override string FormatHubArgs(string args) => args; // Linux doesn't need the "--" prefix @@ -11,8 +16,6 @@ public override ProcessStartInfo OpenFileWithApp(string filePath, string applica return new ProcessStartInfo(applicationPath, filePath); } - public override string RelativeEditorPathToExecutable => "Editor/Unity"; - public override string UnityHubConfigDirectory => Path.Combine(UserHome, ".config/UnityHub"); public override ProcessStartInfo GetUnityProjectSearchProcess() diff --git a/src/ucll/Shared/Platform/MacSupport.cs b/src/ucll/Shared/Platform/MacSupport.cs index 83dcdb2..05064a9 100644 --- a/src/ucll/Shared/Platform/MacSupport.cs +++ b/src/ucll/Shared/Platform/MacSupport.cs @@ -8,7 +8,15 @@ public override ProcessStartInfo OpenFileWithApp(string filePath, string applica return new ProcessStartInfo("open", $"-a \"{applicationPath}\" \"{filePath}\""); } - public override string RelativeEditorPathToExecutable => "Contents/MacOS/Unity"; + public override string FindInstallationRoot(string editorPath) + { + return editorPath.Replace("/Unity.app/Contents/MacOS/Unity", string.Empty); + } + + public override string GetUnityExecutablePath(string path) + { + return Path.Combine(path, "Contents/MacOS/Unity"); + } public override string UnityHubConfigDirectory => Path.Combine(UserHome, "Library/Application Support/UnityHub"); diff --git a/src/ucll/Shared/Platform/PlatformSupport.cs b/src/ucll/Shared/Platform/PlatformSupport.cs index 003ec47..bcd9d2f 100644 --- a/src/ucll/Shared/Platform/PlatformSupport.cs +++ b/src/ucll/Shared/Platform/PlatformSupport.cs @@ -34,8 +34,7 @@ public static PlatformSupport Create() /// /// Given the path to an editor executable, returns the root directory path of the installation. /// - public string FindInstallationRoot(string editorPath) - => new DirectoryInfo(editorPath.Replace(RelativeEditorPathToExecutable, string.Empty)).Parent!.FullName; + public abstract string FindInstallationRoot(string editorPath); /// /// Path to the Unity Hub executable or null if it doesn't exist (or couldn't be found). @@ -69,9 +68,9 @@ public string FindInstallationRoot(string editorPath) public abstract ProcessStartInfo OpenFileWithApp(string filePath, string applicationPath); /// - /// The path from the installation bundle (macOS) or root (Windows) to the executable. + /// Converts an installation bundle path (macOS) to a path to the binary, if needed. /// - public abstract string RelativeEditorPathToExecutable { get; } + public virtual string GetUnityExecutablePath(string path) => path; /// /// The path to the directory that contains Unity Hub config files. diff --git a/src/ucll/Shared/Platform/WindowsSupport.cs b/src/ucll/Shared/Platform/WindowsSupport.cs index a185988..cd55990 100644 --- a/src/ucll/Shared/Platform/WindowsSupport.cs +++ b/src/ucll/Shared/Platform/WindowsSupport.cs @@ -12,7 +12,10 @@ public override ProcessStartInfo OpenFileWithApp(string filePath, string applica return new ProcessStartInfo(applicationPath, $"\"{filePath}\""); } - public override string RelativeEditorPathToExecutable => @"Editor\Unity.exe"; + public override string FindInstallationRoot(string editorPath) + { + return editorPath.Replace(@"Editor\Unity.exe", string.Empty).TrimEnd('\\'); + } public override string UnityHubConfigDirectory => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "UnityHub"); diff --git a/src/ucll/Shared/UnityHub.cs b/src/ucll/Shared/UnityHub.cs index 5441a19..deede6f 100644 --- a/src/ucll/Shared/UnityHub.cs +++ b/src/ucll/Shared/UnityHub.cs @@ -23,18 +23,19 @@ internal class UnityHub(PlatformSupport platformSupport) public string GetEditorPath(string version) { // Fast: try the default install location first. - string? executablePath = platformSupport.FindDefaultEditorPath(version); - if (executablePath != null) - return executablePath; + string? editorPathDefault = platformSupport.FindDefaultEditorPath(version); + if (editorPathDefault != null) + return editorPathDefault; // Fallback: query Unity Hub for custom installation locations. var editors = ListInstalledEditors(); - string? appBundlePath = editors.FirstOrDefault(p => p.Version == version).Path; + string? editorPathHub = editors.FirstOrDefault(p => p.Version == version).Path; - if (appBundlePath == null) + if (editorPathHub == null) throw new UserException($"Unity version {version} is not installed."); - return Path.Combine(appBundlePath, platformSupport.RelativeEditorPathToExecutable); + // On macOS, the Unity Hub returns a path to the app bundle (Unity.app), but we need the binary within. + return platformSupport.GetUnityExecutablePath(editorPathHub); } public IEnumerable GetRecentProjects(bool favoriteOnly = false)