Merge pull request #92 from ennerperez/feature/issues-77

code_review:

* use JsonSerializerContext to avoid AOT warnnings
* since we call TryAdd by interating the installed tools, so detecting by environment variable becomes meaningless (it can not detect tools not installed by Toolbox). Just add it into founded directly
* remove unnecessary type defines
* determine the Icon used by tool while adding it to the founded list.

# Conflicts:
#	src/Native/Linux.cs
#	src/Native/MacOS.cs
#	src/Native/Windows.cs
This commit is contained in:
leo 2024-04-27 20:54:26 +08:00
commit 9a68418f51
24 changed files with 87 additions and 33 deletions

View file

@ -4,6 +4,7 @@ namespace SourceGit
{ {
[JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)] [JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)]
[JsonSerializable(typeof(Models.Version))] [JsonSerializable(typeof(Models.Version))]
[JsonSerializable(typeof(Models.JetBrainsState))]
[JsonSerializable(typeof(ViewModels.Preference))] [JsonSerializable(typeof(ViewModels.Preference))]
internal partial class JsonCodeGen : JsonSerializerContext { } internal partial class JsonCodeGen : JsonSerializerContext { }
} }

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Text.Json;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
@ -19,8 +20,20 @@ namespace SourceGit.Models
{ {
get get
{ {
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{Icon}.png", UriKind.RelativeOrAbsolute)); if (string.IsNullOrWhiteSpace(Icon))
return new Bitmap(icon); {
return null;
}
try
{
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{Icon}.png", UriKind.RelativeOrAbsolute));
return new Bitmap(icon);
}
catch (Exception)
{
return null;
}
} }
} }
@ -36,6 +49,26 @@ namespace SourceGit.Models
} }
} }
public class JetBrainsState
{
public int Version { get; set; }
public string AppVersion { get; set; }
public List<JetBrainsTool> Tools { get; set; }
}
public class JetBrainsTool
{
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; }
}
public class ExternalToolsFinder public class ExternalToolsFinder
{ {
public List<ExternalTool> Founded public List<ExternalTool> Founded
@ -44,31 +77,6 @@ namespace SourceGit.Models
private set; private set;
} = new List<ExternalTool>(); } = new List<ExternalTool>();
public void VSCode(Func<string> platform_finder)
{
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platform_finder);
}
public void VSCodeInsiders(Func<string> platform_finder)
{
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platform_finder);
}
public void Fleet(Func<string> platform_finder)
{
TryAdd("JetBrains Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platform_finder);
}
public void Rider(Func<string> platform_finder)
{
TryAdd("JetBrains Rider", "rider", "\"{0}\"", "RIDER_PATH", platform_finder);
}
public void SublimeText(Func<string> platform_finder)
{
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platform_finder);
}
public void TryAdd(string name, string icon, string args, string env, Func<string> finder) public void TryAdd(string name, string icon, string args, string env, Func<string> finder)
{ {
var path = Environment.GetEnvironmentVariable(env); var path = Environment.GetEnvironmentVariable(env);
@ -84,8 +92,52 @@ namespace SourceGit.Models
Name = name, Name = name,
Icon = icon, Icon = icon,
OpenCmdArgs = args, OpenCmdArgs = args,
Executable = path, Executable = path
}); });
} }
public void VSCode(Func<string> platform_finder)
{
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platform_finder);
}
public void VSCodeInsiders(Func<string> platform_finder)
{
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platform_finder);
}
public void Fleet(Func<string> platform_finder)
{
TryAdd("JetBrains Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platform_finder);
}
public void SublimeText(Func<string> platform_finder)
{
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platform_finder);
}
public void FindJetBrainsFromToolbox(Func<string> platform_finder)
{
var exclude = new List<string> { "fleet", "dotmemory", "dottrace", "resharper-u", "androidstudio" };
var supported_icons = new List<string> { "CL", "DB", "DL", "DS", "GO", "IC", "IU", "JB", "PC", "PS", "PY", "QA", "QD", "RD", "RM", "RR", "WRS", "WS" };
var state = Path.Combine(platform_finder(), "state.json");
if (File.Exists(state))
{
var stateData = JsonSerializer.Deserialize(File.ReadAllText(state), JsonCodeGen.Default.JetBrainsState);
foreach (var tool in stateData.Tools)
{
if (exclude.Contains(tool.ToolId.ToLowerInvariant()))
continue;
Founded.Add(new ExternalTool
{
Name = $"JetBrains {tool.DisplayName} {tool.DisplayVersion}",
Icon = supported_icons.Contains(tool.ProductCode) ? $"JetBrains/{tool.ProductCode}" : $"JetBrains/JB",
OpenCmdArgs = "\"{0}\"",
Executable = Path.Combine(tool.InstallLocation, tool.LaunchCommand),
});
}
}
}
} }
} }

View file

@ -57,8 +57,8 @@ namespace SourceGit.Native
var finder = new Models.ExternalToolsFinder(); var finder = new Models.ExternalToolsFinder();
finder.VSCode(() => FindExecutable("code")); finder.VSCode(() => FindExecutable("code"));
finder.VSCodeInsiders(() => FindExecutable("code-insiders")); finder.VSCodeInsiders(() => FindExecutable("code-insiders"));
finder.Fleet(FindJetBrainFleet); finder.Fleet(FindJetBrainsFleet);
finder.Rider(() => string.Empty); finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox");
finder.SublimeText(() => FindExecutable("subl")); finder.SublimeText(() => FindExecutable("subl"));
return finder.Founded; return finder.Founded;
} }
@ -175,7 +175,7 @@ namespace SourceGit.Native
return null; return null;
} }
private string FindJetBrainFleet() private string FindJetBrainsFleet()
{ {
var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet"; var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet";
return File.Exists(path) ? path : FindExecutable("fleet"); return File.Exists(path) ? path : FindExecutable("fleet");

View file

@ -33,7 +33,7 @@ namespace SourceGit.Native
finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"); 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.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.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet");
finder.Rider(() => string.Empty); finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Library/Application Support/JetBrains/Toolbox");
finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"); finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl");
return finder.Founded; return finder.Founded;
} }

View file

@ -111,7 +111,7 @@ namespace SourceGit.Native
finder.VSCode(FindVSCode); finder.VSCode(FindVSCode);
finder.VSCodeInsiders(FindVSCodeInsiders); finder.VSCodeInsiders(FindVSCodeInsiders);
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe"); finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe");
finder.Rider(FindRider); finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox");
finder.SublimeText(FindSublimeText); finder.SublimeText(FindSublimeText);
return finder.Founded; return finder.Founded;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -23,6 +23,7 @@
<ItemGroup> <ItemGroup>
<AvaloniaResource Include="App.ico" /> <AvaloniaResource Include="App.ico" />
<AvaloniaResource Include="Resources/ExternalToolIcons/*" /> <AvaloniaResource Include="Resources/ExternalToolIcons/*" />
<AvaloniaResource Include="Resources/ExternalToolIcons/JetBrains/*" />
<AvaloniaResource Include="Resources/Fonts/*" /> <AvaloniaResource Include="Resources/Fonts/*" />
<AvaloniaResource Include="Resources/ShellIcons/*" /> <AvaloniaResource Include="Resources/ShellIcons/*" />
</ItemGroup> </ItemGroup>