|
@@ -1,4 +1,4 @@
|
|
|
-using System;
|
|
|
+using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
@@ -14,403 +14,403 @@ using OS = GodotTools.Utils.OS;
|
|
|
|
|
|
namespace GodotTools.Ides.Rider
|
|
|
{
|
|
|
- /// <summary>
|
|
|
- /// This code is a modified version of the JetBrains resharper-unity plugin listed under Apache License 2.0 license:
|
|
|
- /// https://github.com/JetBrains/resharper-unity/blob/master/unity/JetBrains.Rider.Unity.Editor/EditorPlugin/RiderPathLocator.cs
|
|
|
- /// </summary>
|
|
|
- public static class RiderPathLocator
|
|
|
- {
|
|
|
- public static RiderInfo[] GetAllRiderPaths()
|
|
|
+ /// <summary>
|
|
|
+ /// This code is a modified version of the JetBrains resharper-unity plugin listed under Apache License 2.0 license:
|
|
|
+ /// https://github.com/JetBrains/resharper-unity/blob/master/unity/JetBrains.Rider.Unity.Editor/EditorPlugin/RiderPathLocator.cs
|
|
|
+ /// </summary>
|
|
|
+ public static class RiderPathLocator
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- if (OS.IsWindows)
|
|
|
+ public static RiderInfo[] GetAllRiderPaths()
|
|
|
{
|
|
|
- return CollectRiderInfosWindows();
|
|
|
- }
|
|
|
- if (OS.IsOSX)
|
|
|
- {
|
|
|
- return CollectRiderInfosMac();
|
|
|
- }
|
|
|
- if (OS.IsUnixLike())
|
|
|
- {
|
|
|
- return CollectAllRiderPathsLinux();
|
|
|
- }
|
|
|
- throw new Exception("Unexpected OS.");
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- GD.PushWarning(e.Message);
|
|
|
- }
|
|
|
-
|
|
|
- return new RiderInfo[0];
|
|
|
- }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (OS.IsWindows)
|
|
|
+ {
|
|
|
+ return CollectRiderInfosWindows();
|
|
|
+ }
|
|
|
+ if (OS.IsOSX)
|
|
|
+ {
|
|
|
+ return CollectRiderInfosMac();
|
|
|
+ }
|
|
|
+ if (OS.IsUnixLike())
|
|
|
+ {
|
|
|
+ return CollectAllRiderPathsLinux();
|
|
|
+ }
|
|
|
+ throw new Exception("Unexpected OS.");
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ GD.PushWarning(e.Message);
|
|
|
+ }
|
|
|
|
|
|
- private static RiderInfo[] CollectAllRiderPathsLinux()
|
|
|
- {
|
|
|
- var installInfos = new List<RiderInfo>();
|
|
|
- var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
- if (!string.IsNullOrEmpty(home))
|
|
|
- {
|
|
|
- var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
- installInfos.AddRange(CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false)
|
|
|
- .Select(a => new RiderInfo(a, true)).ToList());
|
|
|
-
|
|
|
- //$Home/.local/share/applications/jetbrains-rider.desktop
|
|
|
- var shortcut = new FileInfo(Path.Combine(home, @".local/share/applications/jetbrains-rider.desktop"));
|
|
|
-
|
|
|
- if (shortcut.Exists)
|
|
|
- {
|
|
|
- var lines = File.ReadAllLines(shortcut.FullName);
|
|
|
- foreach (var line in lines)
|
|
|
- {
|
|
|
- if (!line.StartsWith("Exec=\""))
|
|
|
- continue;
|
|
|
- var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault();
|
|
|
- if (string.IsNullOrEmpty(path))
|
|
|
- continue;
|
|
|
-
|
|
|
- if (installInfos.Any(a => a.Path == path)) // avoid adding similar build as from toolbox
|
|
|
- continue;
|
|
|
- installInfos.Add(new RiderInfo(path, false));
|
|
|
- }
|
|
|
+ return new RiderInfo[0];
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- // snap install
|
|
|
- var snapInstallPath = "/snap/rider/current/bin/rider.sh";
|
|
|
- if (new FileInfo(snapInstallPath).Exists)
|
|
|
- installInfos.Add(new RiderInfo(snapInstallPath, false));
|
|
|
-
|
|
|
- return installInfos.ToArray();
|
|
|
- }
|
|
|
|
|
|
- private static RiderInfo[] CollectRiderInfosMac()
|
|
|
- {
|
|
|
- var installInfos = new List<RiderInfo>();
|
|
|
- // "/Applications/*Rider*.app"
|
|
|
- var folder = new DirectoryInfo("/Applications");
|
|
|
- if (folder.Exists)
|
|
|
- {
|
|
|
- installInfos.AddRange(folder.GetDirectories("*Rider*.app")
|
|
|
- .Select(a => new RiderInfo(a.FullName, false))
|
|
|
- .ToList());
|
|
|
- }
|
|
|
-
|
|
|
- // /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app
|
|
|
- var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
- var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true)
|
|
|
- .Select(a => new RiderInfo(a, true));
|
|
|
- installInfos.AddRange(paths);
|
|
|
-
|
|
|
- return installInfos.ToArray();
|
|
|
- }
|
|
|
+ private static RiderInfo[] CollectAllRiderPathsLinux()
|
|
|
+ {
|
|
|
+ var installInfos = new List<RiderInfo>();
|
|
|
+ var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
+ if (!string.IsNullOrEmpty(home))
|
|
|
+ {
|
|
|
+ var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
+ installInfos.AddRange(CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false)
|
|
|
+ .Select(a => new RiderInfo(a, true)).ToList());
|
|
|
+
|
|
|
+ //$Home/.local/share/applications/jetbrains-rider.desktop
|
|
|
+ var shortcut = new FileInfo(Path.Combine(home, @".local/share/applications/jetbrains-rider.desktop"));
|
|
|
+
|
|
|
+ if (shortcut.Exists)
|
|
|
+ {
|
|
|
+ var lines = File.ReadAllLines(shortcut.FullName);
|
|
|
+ foreach (var line in lines)
|
|
|
+ {
|
|
|
+ if (!line.StartsWith("Exec=\""))
|
|
|
+ continue;
|
|
|
+ var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault();
|
|
|
+ if (string.IsNullOrEmpty(path))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (installInfos.Any(a => a.Path == path)) // avoid adding similar build as from toolbox
|
|
|
+ continue;
|
|
|
+ installInfos.Add(new RiderInfo(path, false));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- private static RiderInfo[] CollectRiderInfosWindows()
|
|
|
- {
|
|
|
- var installInfos = new List<RiderInfo>();
|
|
|
- var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
- var installPathsToolbox = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider64.exe", false).ToList();
|
|
|
- installInfos.AddRange(installPathsToolbox.Select(a => new RiderInfo(a, true)).ToList());
|
|
|
-
|
|
|
- var installPaths = new List<string>();
|
|
|
- const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
|
|
|
- CollectPathsFromRegistry(registryKey, installPaths);
|
|
|
- const string wowRegistryKey = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
|
|
|
- CollectPathsFromRegistry(wowRegistryKey, installPaths);
|
|
|
-
|
|
|
- installInfos.AddRange(installPaths.Select(a => new RiderInfo(a, false)).ToList());
|
|
|
-
|
|
|
- return installInfos.ToArray();
|
|
|
- }
|
|
|
+ // snap install
|
|
|
+ var snapInstallPath = "/snap/rider/current/bin/rider.sh";
|
|
|
+ if (new FileInfo(snapInstallPath).Exists)
|
|
|
+ installInfos.Add(new RiderInfo(snapInstallPath, false));
|
|
|
|
|
|
- private static string GetToolboxBaseDir()
|
|
|
- {
|
|
|
- if (OS.IsWindows)
|
|
|
- {
|
|
|
- var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
|
|
- return Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider");
|
|
|
- }
|
|
|
-
|
|
|
- if (OS.IsOSX)
|
|
|
- {
|
|
|
- var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
- if (!string.IsNullOrEmpty(home))
|
|
|
- {
|
|
|
- return Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider");
|
|
|
+ return installInfos.ToArray();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (OS.IsUnixLike())
|
|
|
- {
|
|
|
- var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
- if (!string.IsNullOrEmpty(home))
|
|
|
+ private static RiderInfo[] CollectRiderInfosMac()
|
|
|
{
|
|
|
- return Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider");
|
|
|
+ var installInfos = new List<RiderInfo>();
|
|
|
+ // "/Applications/*Rider*.app"
|
|
|
+ var folder = new DirectoryInfo("/Applications");
|
|
|
+ if (folder.Exists)
|
|
|
+ {
|
|
|
+ installInfos.AddRange(folder.GetDirectories("*Rider*.app")
|
|
|
+ .Select(a => new RiderInfo(a.FullName, false))
|
|
|
+ .ToList());
|
|
|
+ }
|
|
|
+
|
|
|
+ // /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app
|
|
|
+ var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
+ var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true)
|
|
|
+ .Select(a => new RiderInfo(a, true));
|
|
|
+ installInfos.AddRange(paths);
|
|
|
+
|
|
|
+ return installInfos.ToArray();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- throw new Exception("Unexpected OS.");
|
|
|
- }
|
|
|
-
|
|
|
- internal static ProductInfo GetBuildVersion(string path)
|
|
|
- {
|
|
|
- var buildTxtFileInfo = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
|
|
|
- var dir = buildTxtFileInfo.DirectoryName;
|
|
|
- if (!Directory.Exists(dir))
|
|
|
- return null;
|
|
|
- var buildVersionFile = new FileInfo(Path.Combine(dir, "product-info.json"));
|
|
|
- if (!buildVersionFile.Exists)
|
|
|
- return null;
|
|
|
- var json = File.ReadAllText(buildVersionFile.FullName);
|
|
|
- return ProductInfo.GetProductInfo(json);
|
|
|
- }
|
|
|
-
|
|
|
- internal static Version GetBuildNumber(string path)
|
|
|
- {
|
|
|
- var file = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
|
|
|
- if (!file.Exists)
|
|
|
- return null;
|
|
|
- var text = File.ReadAllText(file.FullName);
|
|
|
- if (text.Length <= 3)
|
|
|
- return null;
|
|
|
-
|
|
|
- var versionText = text.Substring(3);
|
|
|
- return Version.TryParse(versionText, out var v) ? v : null;
|
|
|
- }
|
|
|
+ private static RiderInfo[] CollectRiderInfosWindows()
|
|
|
+ {
|
|
|
+ var installInfos = new List<RiderInfo>();
|
|
|
+ var toolboxRiderRootPath = GetToolboxBaseDir();
|
|
|
+ var installPathsToolbox = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider64.exe", false).ToList();
|
|
|
+ installInfos.AddRange(installPathsToolbox.Select(a => new RiderInfo(a, true)).ToList());
|
|
|
|
|
|
- internal static bool IsToolbox(string path)
|
|
|
- {
|
|
|
- return path.StartsWith(GetToolboxBaseDir());
|
|
|
- }
|
|
|
+ var installPaths = new List<string>();
|
|
|
+ const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
|
|
|
+ CollectPathsFromRegistry(registryKey, installPaths);
|
|
|
+ const string wowRegistryKey = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
|
|
|
+ CollectPathsFromRegistry(wowRegistryKey, installPaths);
|
|
|
|
|
|
- private static string GetRelativePathToBuildTxt()
|
|
|
- {
|
|
|
- if (OS.IsWindows || OS.IsUnixLike())
|
|
|
- return "../../build.txt";
|
|
|
- if (OS.IsOSX)
|
|
|
- return "Contents/Resources/build.txt";
|
|
|
- throw new Exception("Unknown OS.");
|
|
|
- }
|
|
|
+ installInfos.AddRange(installPaths.Select(a => new RiderInfo(a, false)).ToList());
|
|
|
|
|
|
- private static void CollectPathsFromRegistry(string registryKey, List<string> installPaths)
|
|
|
- {
|
|
|
- using (var key = Registry.LocalMachine.OpenSubKey(registryKey))
|
|
|
- {
|
|
|
- if (key == null) return;
|
|
|
- foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider")))
|
|
|
- {
|
|
|
- using (var subkey = key.OpenSubKey(subkeyName))
|
|
|
- {
|
|
|
- var folderObject = subkey?.GetValue("InstallLocation");
|
|
|
- if (folderObject == null) continue;
|
|
|
- var folder = folderObject.ToString();
|
|
|
- var possiblePath = Path.Combine(folder, @"bin\rider64.exe");
|
|
|
- if (File.Exists(possiblePath))
|
|
|
- installPaths.Add(possiblePath);
|
|
|
- }
|
|
|
+ return installInfos.ToArray();
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static string[] CollectPathsFromToolbox(string toolboxRiderRootPath, string dirName, string searchPattern,
|
|
|
- bool isMac)
|
|
|
- {
|
|
|
- if (!Directory.Exists(toolboxRiderRootPath))
|
|
|
- return new string[0];
|
|
|
|
|
|
- var channelDirs = Directory.GetDirectories(toolboxRiderRootPath);
|
|
|
- var paths = channelDirs.SelectMany(channelDir =>
|
|
|
+ private static string GetToolboxBaseDir()
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
|
|
|
- var historyFile = Path.Combine(channelDir, ".history.json");
|
|
|
- if (File.Exists(historyFile))
|
|
|
+ if (OS.IsWindows)
|
|
|
{
|
|
|
- var json = File.ReadAllText(historyFile);
|
|
|
- var build = ToolboxHistory.GetLatestBuildFromJson(json);
|
|
|
- if (build != null)
|
|
|
- {
|
|
|
- var buildDir = Path.Combine(channelDir, build);
|
|
|
- var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
|
|
|
- if (executablePaths.Any())
|
|
|
- return executablePaths;
|
|
|
- }
|
|
|
+ var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
|
|
+ return Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider");
|
|
|
}
|
|
|
|
|
|
- var channelFile = Path.Combine(channelDir, ".channel.settings.json");
|
|
|
- if (File.Exists(channelFile))
|
|
|
+ if (OS.IsOSX)
|
|
|
{
|
|
|
- var json = File.ReadAllText(channelFile).Replace("active-application", "active_application");
|
|
|
- var build = ToolboxInstallData.GetLatestBuildFromJson(json);
|
|
|
- if (build != null)
|
|
|
- {
|
|
|
- var buildDir = Path.Combine(channelDir, build);
|
|
|
- var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
|
|
|
- if (executablePaths.Any())
|
|
|
- return executablePaths;
|
|
|
- }
|
|
|
+ var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
+ if (!string.IsNullOrEmpty(home))
|
|
|
+ {
|
|
|
+ return Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // changes in toolbox json files format may brake the logic above, so return all found Rider installations
|
|
|
- return Directory.GetDirectories(channelDir)
|
|
|
- .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- // do not write to Debug.Log, just log it.
|
|
|
- Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
|
|
|
- }
|
|
|
-
|
|
|
- return new string[0];
|
|
|
- })
|
|
|
- .Where(c => !string.IsNullOrEmpty(c))
|
|
|
- .ToArray();
|
|
|
- return paths;
|
|
|
- }
|
|
|
-
|
|
|
- private static string[] GetExecutablePaths(string dirName, string searchPattern, bool isMac, string buildDir)
|
|
|
- {
|
|
|
- var folder = new DirectoryInfo(Path.Combine(buildDir, dirName));
|
|
|
- if (!folder.Exists)
|
|
|
- return new string[0];
|
|
|
-
|
|
|
- if (!isMac)
|
|
|
- return new[] {Path.Combine(folder.FullName, searchPattern)}.Where(File.Exists).ToArray();
|
|
|
- return folder.GetDirectories(searchPattern).Select(f => f.FullName)
|
|
|
- .Where(Directory.Exists).ToArray();
|
|
|
- }
|
|
|
-
|
|
|
- // Disable the "field is never assigned" compiler warning. We never assign it, but Unity does.
|
|
|
- // Note that Unity disable this warning in the generated C# projects
|
|
|
-#pragma warning disable 0649
|
|
|
+ if (OS.IsUnixLike())
|
|
|
+ {
|
|
|
+ var home = Environment.GetEnvironmentVariable("HOME");
|
|
|
+ if (!string.IsNullOrEmpty(home))
|
|
|
+ {
|
|
|
+ return Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- [Serializable]
|
|
|
- class ToolboxHistory
|
|
|
- {
|
|
|
- public List<ItemNode> history;
|
|
|
+ throw new Exception("Unexpected OS.");
|
|
|
+ }
|
|
|
|
|
|
- public static string GetLatestBuildFromJson(string json)
|
|
|
- {
|
|
|
- try
|
|
|
+ internal static ProductInfo GetBuildVersion(string path)
|
|
|
{
|
|
|
- return JsonConvert.DeserializeObject<ToolboxHistory>(json).history.LastOrDefault()?.item.build;
|
|
|
+ var buildTxtFileInfo = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
|
|
|
+ var dir = buildTxtFileInfo.DirectoryName;
|
|
|
+ if (!Directory.Exists(dir))
|
|
|
+ return null;
|
|
|
+ var buildVersionFile = new FileInfo(Path.Combine(dir, "product-info.json"));
|
|
|
+ if (!buildVersionFile.Exists)
|
|
|
+ return null;
|
|
|
+ var json = File.ReadAllText(buildVersionFile.FullName);
|
|
|
+ return ProductInfo.GetProductInfo(json);
|
|
|
}
|
|
|
- catch (Exception)
|
|
|
+
|
|
|
+ internal static Version GetBuildNumber(string path)
|
|
|
{
|
|
|
- Logger.Warn($"Failed to get latest build from json {json}");
|
|
|
+ var file = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
|
|
|
+ if (!file.Exists)
|
|
|
+ return null;
|
|
|
+ var text = File.ReadAllText(file.FullName);
|
|
|
+ if (text.Length <= 3)
|
|
|
+ return null;
|
|
|
+
|
|
|
+ var versionText = text.Substring(3);
|
|
|
+ return Version.TryParse(versionText, out var v) ? v : null;
|
|
|
}
|
|
|
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- [Serializable]
|
|
|
- class ItemNode
|
|
|
- {
|
|
|
- public BuildNode item;
|
|
|
- }
|
|
|
+ internal static bool IsToolbox(string path)
|
|
|
+ {
|
|
|
+ return path.StartsWith(GetToolboxBaseDir());
|
|
|
+ }
|
|
|
|
|
|
- [Serializable]
|
|
|
- class BuildNode
|
|
|
- {
|
|
|
- public string build;
|
|
|
- }
|
|
|
+ private static string GetRelativePathToBuildTxt()
|
|
|
+ {
|
|
|
+ if (OS.IsWindows || OS.IsUnixLike())
|
|
|
+ return "../../build.txt";
|
|
|
+ if (OS.IsOSX)
|
|
|
+ return "Contents/Resources/build.txt";
|
|
|
+ throw new Exception("Unknown OS.");
|
|
|
+ }
|
|
|
|
|
|
- [Serializable]
|
|
|
- public class ProductInfo
|
|
|
- {
|
|
|
- public string version;
|
|
|
- public string versionSuffix;
|
|
|
+ private static void CollectPathsFromRegistry(string registryKey, List<string> installPaths)
|
|
|
+ {
|
|
|
+ using (var key = Registry.LocalMachine.OpenSubKey(registryKey))
|
|
|
+ {
|
|
|
+ if (key == null) return;
|
|
|
+ foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider")))
|
|
|
+ {
|
|
|
+ using (var subkey = key.OpenSubKey(subkeyName))
|
|
|
+ {
|
|
|
+ var folderObject = subkey?.GetValue("InstallLocation");
|
|
|
+ if (folderObject == null) continue;
|
|
|
+ var folder = folderObject.ToString();
|
|
|
+ var possiblePath = Path.Combine(folder, @"bin\rider64.exe");
|
|
|
+ if (File.Exists(possiblePath))
|
|
|
+ installPaths.Add(possiblePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- [CanBeNull]
|
|
|
- internal static ProductInfo GetProductInfo(string json)
|
|
|
- {
|
|
|
- try
|
|
|
+ private static string[] CollectPathsFromToolbox(string toolboxRiderRootPath, string dirName, string searchPattern,
|
|
|
+ bool isMac)
|
|
|
{
|
|
|
- var productInfo = JsonConvert.DeserializeObject<ProductInfo>(json);
|
|
|
- return productInfo;
|
|
|
+ if (!Directory.Exists(toolboxRiderRootPath))
|
|
|
+ return new string[0];
|
|
|
+
|
|
|
+ var channelDirs = Directory.GetDirectories(toolboxRiderRootPath);
|
|
|
+ var paths = channelDirs.SelectMany(channelDir =>
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
|
|
|
+ var historyFile = Path.Combine(channelDir, ".history.json");
|
|
|
+ if (File.Exists(historyFile))
|
|
|
+ {
|
|
|
+ var json = File.ReadAllText(historyFile);
|
|
|
+ var build = ToolboxHistory.GetLatestBuildFromJson(json);
|
|
|
+ if (build != null)
|
|
|
+ {
|
|
|
+ var buildDir = Path.Combine(channelDir, build);
|
|
|
+ var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
|
|
|
+ if (executablePaths.Any())
|
|
|
+ return executablePaths;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var channelFile = Path.Combine(channelDir, ".channel.settings.json");
|
|
|
+ if (File.Exists(channelFile))
|
|
|
+ {
|
|
|
+ var json = File.ReadAllText(channelFile).Replace("active-application", "active_application");
|
|
|
+ var build = ToolboxInstallData.GetLatestBuildFromJson(json);
|
|
|
+ if (build != null)
|
|
|
+ {
|
|
|
+ var buildDir = Path.Combine(channelDir, build);
|
|
|
+ var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
|
|
|
+ if (executablePaths.Any())
|
|
|
+ return executablePaths;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // changes in toolbox json files format may brake the logic above, so return all found Rider installations
|
|
|
+ return Directory.GetDirectories(channelDir)
|
|
|
+ .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ // do not write to Debug.Log, just log it.
|
|
|
+ Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return new string[0];
|
|
|
+ })
|
|
|
+ .Where(c => !string.IsNullOrEmpty(c))
|
|
|
+ .ToArray();
|
|
|
+ return paths;
|
|
|
}
|
|
|
- catch (Exception)
|
|
|
+
|
|
|
+ private static string[] GetExecutablePaths(string dirName, string searchPattern, bool isMac, string buildDir)
|
|
|
{
|
|
|
- Logger.Warn($"Failed to get version from json {json}");
|
|
|
+ var folder = new DirectoryInfo(Path.Combine(buildDir, dirName));
|
|
|
+ if (!folder.Exists)
|
|
|
+ return new string[0];
|
|
|
+
|
|
|
+ if (!isMac)
|
|
|
+ return new[] { Path.Combine(folder.FullName, searchPattern) }.Where(File.Exists).ToArray();
|
|
|
+ return folder.GetDirectories(searchPattern).Select(f => f.FullName)
|
|
|
+ .Where(Directory.Exists).ToArray();
|
|
|
}
|
|
|
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
+ // Disable the "field is never assigned" compiler warning. We never assign it, but Unity does.
|
|
|
+ // Note that Unity disable this warning in the generated C# projects
|
|
|
+#pragma warning disable 0649
|
|
|
|
|
|
- // ReSharper disable once ClassNeverInstantiated.Global
|
|
|
- [Serializable]
|
|
|
- class ToolboxInstallData
|
|
|
- {
|
|
|
- // ReSharper disable once InconsistentNaming
|
|
|
- public ActiveApplication active_application;
|
|
|
+ [Serializable]
|
|
|
+ class ToolboxHistory
|
|
|
+ {
|
|
|
+ public List<ItemNode> history;
|
|
|
+
|
|
|
+ public static string GetLatestBuildFromJson(string json)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ return JsonConvert.DeserializeObject<ToolboxHistory>(json).history.LastOrDefault()?.item.build;
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
+ {
|
|
|
+ Logger.Warn($"Failed to get latest build from json {json}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- [CanBeNull]
|
|
|
- public static string GetLatestBuildFromJson(string json)
|
|
|
- {
|
|
|
- try
|
|
|
+ [Serializable]
|
|
|
+ class ItemNode
|
|
|
{
|
|
|
- var toolbox = JsonConvert.DeserializeObject<ToolboxInstallData>(json);
|
|
|
- var builds = toolbox.active_application.builds;
|
|
|
- if (builds != null && builds.Any())
|
|
|
- return builds.First();
|
|
|
+ public BuildNode item;
|
|
|
}
|
|
|
- catch (Exception)
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ class BuildNode
|
|
|
{
|
|
|
- Logger.Warn($"Failed to get latest build from json {json}");
|
|
|
+ public string build;
|
|
|
}
|
|
|
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
+ [Serializable]
|
|
|
+ public class ProductInfo
|
|
|
+ {
|
|
|
+ public string version;
|
|
|
+ public string versionSuffix;
|
|
|
|
|
|
- [Serializable]
|
|
|
- class ActiveApplication
|
|
|
- {
|
|
|
- // ReSharper disable once InconsistentNaming
|
|
|
- public List<string> builds;
|
|
|
- }
|
|
|
+ [CanBeNull]
|
|
|
+ internal static ProductInfo GetProductInfo(string json)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var productInfo = JsonConvert.DeserializeObject<ProductInfo>(json);
|
|
|
+ return productInfo;
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
+ {
|
|
|
+ Logger.Warn($"Failed to get version from json {json}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-#pragma warning restore 0649
|
|
|
+ // ReSharper disable once ClassNeverInstantiated.Global
|
|
|
+ [Serializable]
|
|
|
+ class ToolboxInstallData
|
|
|
+ {
|
|
|
+ // ReSharper disable once InconsistentNaming
|
|
|
+ public ActiveApplication active_application;
|
|
|
|
|
|
- public struct RiderInfo
|
|
|
- {
|
|
|
- public bool IsToolbox;
|
|
|
- public string Presentation;
|
|
|
- public Version BuildNumber;
|
|
|
- public ProductInfo ProductInfo;
|
|
|
- public string Path;
|
|
|
-
|
|
|
- public RiderInfo(string path, bool isToolbox)
|
|
|
- {
|
|
|
- BuildNumber = GetBuildNumber(path);
|
|
|
- ProductInfo = GetBuildVersion(path);
|
|
|
- Path = new FileInfo(path).FullName; // normalize separators
|
|
|
- var presentation = $"Rider {BuildNumber}";
|
|
|
-
|
|
|
- if (ProductInfo != null && !string.IsNullOrEmpty(ProductInfo.version))
|
|
|
+ [CanBeNull]
|
|
|
+ public static string GetLatestBuildFromJson(string json)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var toolbox = JsonConvert.DeserializeObject<ToolboxInstallData>(json);
|
|
|
+ var builds = toolbox.active_application.builds;
|
|
|
+ if (builds != null && builds.Any())
|
|
|
+ return builds.First();
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
+ {
|
|
|
+ Logger.Warn($"Failed to get latest build from json {json}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ class ActiveApplication
|
|
|
{
|
|
|
- var suffix = string.IsNullOrEmpty(ProductInfo.versionSuffix) ? "" : $" {ProductInfo.versionSuffix}";
|
|
|
- presentation = $"Rider {ProductInfo.version}{suffix}";
|
|
|
+ // ReSharper disable once InconsistentNaming
|
|
|
+ public List<string> builds;
|
|
|
}
|
|
|
|
|
|
- if (isToolbox)
|
|
|
- presentation += " (JetBrains Toolbox)";
|
|
|
+#pragma warning restore 0649
|
|
|
|
|
|
- Presentation = presentation;
|
|
|
- IsToolbox = isToolbox;
|
|
|
- }
|
|
|
- }
|
|
|
+ public struct RiderInfo
|
|
|
+ {
|
|
|
+ public bool IsToolbox;
|
|
|
+ public string Presentation;
|
|
|
+ public Version BuildNumber;
|
|
|
+ public ProductInfo ProductInfo;
|
|
|
+ public string Path;
|
|
|
|
|
|
- private static class Logger
|
|
|
- {
|
|
|
- internal static void Warn(string message, Exception e = null)
|
|
|
- {
|
|
|
- throw new Exception(message, e);
|
|
|
- }
|
|
|
+ public RiderInfo(string path, bool isToolbox)
|
|
|
+ {
|
|
|
+ BuildNumber = GetBuildNumber(path);
|
|
|
+ ProductInfo = GetBuildVersion(path);
|
|
|
+ Path = new FileInfo(path).FullName; // normalize separators
|
|
|
+ var presentation = $"Rider {BuildNumber}";
|
|
|
+
|
|
|
+ if (ProductInfo != null && !string.IsNullOrEmpty(ProductInfo.version))
|
|
|
+ {
|
|
|
+ var suffix = string.IsNullOrEmpty(ProductInfo.versionSuffix) ? "" : $" {ProductInfo.versionSuffix}";
|
|
|
+ presentation = $"Rider {ProductInfo.version}{suffix}";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isToolbox)
|
|
|
+ presentation += " (JetBrains Toolbox)";
|
|
|
+
|
|
|
+ Presentation = presentation;
|
|
|
+ IsToolbox = isToolbox;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class Logger
|
|
|
+ {
|
|
|
+ internal static void Warn(string message, Exception e = null)
|
|
|
+ {
|
|
|
+ throw new Exception(message, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
}
|