From 53beb3daac64cbfef5d9720dac35ea2d5a258f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enner=20P=C3=A9rez?= Date: Sat, 27 Apr 2024 02:12:03 -0500 Subject: [PATCH] JetBrains Toolbox IDE detection --- src/Models/ExternalTool.cs | 89 +++++++++++++++++++++++++++++++++++++- src/Native/Linux.cs | 1 + src/Native/MacOS.cs | 1 + src/Native/Windows.cs | 1 + 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index 5793fcbd..4108aa84 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; - +using System.Linq; +using System.Text.Json; using Avalonia.Media.Imaging; using Avalonia.Platform; +using SourceGit.Native; namespace SourceGit.Models { @@ -60,6 +62,29 @@ namespace SourceGit.Models } } + public class JetBrainsTool + { + public string Name { get; set; } + public string Instance { get; set; } + public string Path { get; set; } + public string Version { get; set; } + public string BuildNumber { get; set; } + public string ProductCode { get; set; } + public string DataDirectoryName { get; set; } + public string SvgIconPath { get; set; } + public string PngIconPath => System.IO.Path.ChangeExtension(SvgIconPath, "png"); + public string IcoIconPath => System.IO.Path.ChangeExtension(SvgIconPath, "ico"); + public string ProductVendor { get; set; } + public string Executable { get; set; } + public string Icon { get; set; } + public string FallbackIcon { get; set; } + + public override string ToString() + { + return $"{ProductVendor} {Name} {Version}"; + } + } + public class ExternalToolsFinder { public List Founded @@ -103,5 +128,67 @@ namespace SourceGit.Models Name = name, Icon = icon, OpenCmdArgs = args, Executable = path, FallbackIcon = fallbackIcon }); } + + public void FindJetBrainsFromToolbox(Func platform_finder) + { + var exclude = new[] { "fleet", "dotmemory", "dottrace", "resharper-u", "androidstudio" }; + var state = Path.Combine(platform_finder.Invoke(), "state.json"); + var models = Array.Empty(); + if (File.Exists(state)) + { + var stateData = JsonSerializer.Deserialize(File.ReadAllText(state), new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }); + + var tools = stateData.Tools + .Where(p => !exclude.Contains(p.ToolId.ToLowerInvariant())) + .ToArray(); + + models = tools.Select(s => + { + return new JetBrainsTool() + { + Name = s.DisplayName, + Executable = s.LaunchCommand, + Icon =$"JetBrains/{s.ProductCode}", + FallbackIcon = $"JetBrains/JB", + Path = s.InstallLocation, + Version = s.DisplayVersion, + BuildNumber = s.BuildNumber, + ProductCode = s.ProductCode, + ProductVendor = "JetBrains", + }; + }).ToArray(); + } + + foreach (var model in models) + { + var item = new Func(() => + { + return Path.Combine(model.Path, model.Executable); + }); + var name = model.ProductVendor + "_" + model.ProductCode + (model.Instance != null ? $"_{model.Instance}" : string.Empty); + TryAdd($"{model}", model.Icon, "\"{0}\"", $"{name.ToUpperInvariant()}_PATH", item, model.FallbackIcon); + } + } + + + internal class JetBrainsState + { + public int Version { get; set; } + public string AppVersion { get; set; } + public List Tools { get; set; } + } + + internal class Tool + { + public string ChannelId { get; set; } + public string ToolId { get; set; } + public string ProductCode { get; set; } + public string Tag { get; set; } + public string DisplayName { get; set; } + public string DisplayVersion { get; set; } + public string BuildNumber { get; set; } + public string InstallLocation { get; set; } + public string LaunchCommand { get; set; } + } } } diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs index 176941cc..f2ff11e2 100644 --- a/src/Native/Linux.cs +++ b/src/Native/Linux.cs @@ -58,6 +58,7 @@ namespace SourceGit.Native finder.VSCode(() => FindExecutable("code")); finder.VSCodeInsiders(() => FindExecutable("code-insiders")); finder.Fleet(FindJetBrainFleet); + finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps"); finder.SublimeText(() => FindExecutable("subl")); return finder.Founded; } diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index f4ddc2ea..450b87ba 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -33,6 +33,7 @@ namespace SourceGit.Native finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"); finder.VSCodeInsiders(() => "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"); finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet"); + finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Library/Application Support/JetBrains/Toolbox"); finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"); return finder.Founded; } diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 2d22ac42..8c4ab022 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -111,6 +111,7 @@ namespace SourceGit.Native finder.VSCode(FindVSCode); finder.VSCodeInsiders(FindVSCodeInsiders); finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe"); + finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox"); finder.SublimeText(FindSublimeText); return finder.Founded; }