Parcourir la source

3.2 C#: Upgrade GodotTools to nuget Microsoft.Build

This upgrade is needed in order to support
reading and editing project files that use Sdks
as well as other new features. A common example
in 3.2 is having to specify a PackageReference
version with a child element rather than the
attribute. This is no longer the case now.

Partial cherry-pick of f3bcd5f8dd36c4ce384f00a03650f71dce5c4de6
Most of the other changes from that commit were already partially
cherry-picked in 3928fe200f1fda49655b429bd64f7bb55457c30d.
Ignacio Etcheverry il y a 5 ans
Parent
commit
4d7b7d9b73

+ 14 - 2
modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs

@@ -2,7 +2,6 @@ using System;
 using System.IO;
 using System.IO;
 using System.Security;
 using System.Security;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Framework;
-using GodotTools.Core;
 
 
 namespace GodotTools.BuildLogger
 namespace GodotTools.BuildLogger
 {
 {
@@ -18,7 +17,7 @@ namespace GodotTools.BuildLogger
             if (null == Parameters)
             if (null == Parameters)
                 throw new LoggerException("Log directory was not set.");
                 throw new LoggerException("Log directory was not set.");
 
 
-            var parameters = Parameters.Split(new[] { ';' });
+            var parameters = Parameters.Split(new[] {';'});
 
 
             string logDir = parameters[0];
             string logDir = parameters[0];
 
 
@@ -183,4 +182,17 @@ namespace GodotTools.BuildLogger
         private StreamWriter issuesStreamWriter;
         private StreamWriter issuesStreamWriter;
         private int indent;
         private int indent;
     }
     }
+
+    internal static class StringExtensions
+    {
+        public static string CsvEscape(this string value, char delimiter = ',')
+        {
+            bool hasSpecialChar = value.IndexOfAny(new[] {'\"', '\n', '\r', delimiter}) != -1;
+
+            if (hasSpecialChar)
+                return "\"" + value.Replace("\"", "\"\"") + "\"";
+
+            return value;
+        }
+    }
 }
 }

+ 3 - 5
modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj

@@ -1,13 +1,11 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <ProjectGuid>{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}</ProjectGuid>
     <ProjectGuid>{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <TargetFramework>net472</TargetFramework>
-    <LangVersion>7</LangVersion>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>7.2</LangVersion>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.Build.Framework" />
-    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
+    <PackageReference Include="Microsoft.Build.Framework" Version="16.5.0" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />

+ 2 - 6
modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj

@@ -1,11 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid>
     <ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <TargetFramework>net472</TargetFramework>
-    <LangVersion>7</LangVersion>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>7.2</LangVersion>
   </PropertyGroup>
   </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
-  </ItemGroup>
 </Project>
 </Project>

+ 2 - 12
modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs

@@ -34,23 +34,13 @@ namespace GodotTools.Core
             return rooted ? Path.DirectorySeparatorChar + path : path;
             return rooted ? Path.DirectorySeparatorChar + path : path;
         }
         }
 
 
-        private static readonly string driveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
+        private static readonly string DriveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
 
 
         public static bool IsAbsolutePath(this string path)
         public static bool IsAbsolutePath(this string path)
         {
         {
             return path.StartsWith("/", StringComparison.Ordinal) ||
             return path.StartsWith("/", StringComparison.Ordinal) ||
                    path.StartsWith("\\", StringComparison.Ordinal) ||
                    path.StartsWith("\\", StringComparison.Ordinal) ||
-                   path.StartsWith(driveRoot, StringComparison.Ordinal);
-        }
-
-        public static string CsvEscape(this string value, char delimiter = ',')
-        {
-            bool hasSpecialChar = value.IndexOfAny(new char[] { '\"', '\n', '\r', delimiter }) != -1;
-
-            if (hasSpecialChar)
-                return "\"" + value.Replace("\"", "\"\"") + "\"";
-
-            return value;
+                   path.StartsWith(DriveRoot, StringComparison.Ordinal);
         }
         }
 
 
         public static string ToSafeDirName(this string dirName, bool allowDirSeparator)
         public static string ToSafeDirName(this string dirName, bool allowDirSeparator)

+ 11 - 3
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj

@@ -1,16 +1,24 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid>
     <ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid>
-    <OutputType>Library</OutputType>
     <TargetFramework>net472</TargetFramework>
     <TargetFramework>net472</TargetFramework>
-    <LangVersion>7</LangVersion>
+    <LangVersion>7.2</LangVersion>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
     <Reference Include="Microsoft.Build" />
     <Reference Include="Microsoft.Build" />
-    <PackageReference Include="DotNet.Glob" Version="2.1.1" />
+    <PackageReference Include="Microsoft.Build" Version="16.5.0" />
     <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
     <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <!--
+    The Microsoft.Build.Runtime package is too problematic so we create a MSBuild.exe stub. The workaround described
+    here doesn't work with Microsoft.NETFramework.ReferenceAssemblies: https://github.com/microsoft/msbuild/issues/3486
+    We need a MSBuild.exe file as there's an issue in Microsoft.Build where it executes platform dependent code when
+    searching for MSBuild.exe before the fallback to not using it. A stub is fine as it should never be executed.
+    -->
+    <None Include="MSBuild.exe" CopyToOutputDirectory="Always" />
+  </ItemGroup>
 </Project>
 </Project>

+ 0 - 0
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/MSBuild.exe


+ 3 - 7
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs

@@ -2,8 +2,8 @@ using GodotTools.Core;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
-using DotNet.Globbing;
 using Microsoft.Build.Construction;
 using Microsoft.Build.Construction;
+using Microsoft.Build.Globbing;
 
 
 namespace GodotTools.ProjectEditor
 namespace GodotTools.ProjectEditor
 {
 {
@@ -11,8 +11,6 @@ namespace GodotTools.ProjectEditor
     {
     {
         public static ProjectItemElement FindItemOrNull(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
         public static ProjectItemElement FindItemOrNull(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
         {
         {
-            GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
-
             string normalizedInclude = include.NormalizePath();
             string normalizedInclude = include.NormalizePath();
 
 
             foreach (var itemGroup in root.ItemGroups)
             foreach (var itemGroup in root.ItemGroups)
@@ -25,7 +23,7 @@ namespace GodotTools.ProjectEditor
                     if (item.ItemType != itemType)
                     if (item.ItemType != itemType)
                         continue;
                         continue;
 
 
-                    var glob = Glob.Parse(item.Include.NormalizePath(), globOptions);
+                    var glob = MSBuildGlob.Parse(item.Include.NormalizePath());
 
 
                     if (glob.IsMatch(normalizedInclude))
                     if (glob.IsMatch(normalizedInclude))
                         return item;
                         return item;
@@ -36,8 +34,6 @@ namespace GodotTools.ProjectEditor
         }
         }
         public static ProjectItemElement FindItemOrNullAbs(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
         public static ProjectItemElement FindItemOrNullAbs(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
         {
         {
-            GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
-
             string normalizedInclude = Path.GetFullPath(include).NormalizePath();
             string normalizedInclude = Path.GetFullPath(include).NormalizePath();
 
 
             foreach (var itemGroup in root.ItemGroups)
             foreach (var itemGroup in root.ItemGroups)
@@ -50,7 +46,7 @@ namespace GodotTools.ProjectEditor
                     if (item.ItemType != itemType)
                     if (item.ItemType != itemType)
                         continue;
                         continue;
 
 
-                    var glob = Glob.Parse(Path.GetFullPath(item.Include).NormalizePath(), globOptions);
+                    var glob = MSBuildGlob.Parse(Path.GetFullPath(item.Include).NormalizePath());
 
 
                     if (glob.IsMatch(normalizedInclude))
                     if (glob.IsMatch(normalizedInclude))
                         return item;
                         return item;

+ 2 - 5
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs

@@ -4,8 +4,8 @@ using System.Diagnostics;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
-using DotNet.Globbing;
 using Microsoft.Build.Construction;
 using Microsoft.Build.Construction;
+using Microsoft.Build.Globbing;
 
 
 namespace GodotTools.ProjectEditor
 namespace GodotTools.ProjectEditor
 {
 {
@@ -133,9 +133,6 @@ namespace GodotTools.ProjectEditor
             var result = new List<string>();
             var result = new List<string>();
             var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
             var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
 
 
-            var globOptions = new GlobOptions();
-            globOptions.Evaluation.CaseInsensitive = false;
-
             var root = ProjectRootElement.Open(projectPath);
             var root = ProjectRootElement.Open(projectPath);
             Debug.Assert(root != null);
             Debug.Assert(root != null);
 
 
@@ -151,7 +148,7 @@ namespace GodotTools.ProjectEditor
 
 
                     string normalizedInclude = item.Include.NormalizePath();
                     string normalizedInclude = item.Include.NormalizePath();
 
 
-                    var glob = Glob.Parse(normalizedInclude, globOptions);
+                    var glob = MSBuildGlob.Parse(normalizedInclude);
 
 
                     // TODO Check somehow if path has no blob to avoid the following loop...
                     // TODO Check somehow if path has no blob to avoid the following loop...
 
 

+ 7 - 10
modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs

@@ -36,15 +36,13 @@ namespace GodotTools.Build
                     }
                     }
                     case BuildTool.MsBuildVs:
                     case BuildTool.MsBuildVs:
                     {
                     {
-                        if (_msbuildToolsPath.Empty() || !File.Exists(_msbuildToolsPath))
+                        if (string.IsNullOrEmpty(_msbuildToolsPath) || !File.Exists(_msbuildToolsPath))
                         {
                         {
                             // Try to search it again if it wasn't found last time or if it was removed from its location
                             // Try to search it again if it wasn't found last time or if it was removed from its location
                             _msbuildToolsPath = FindMsBuildToolsPathOnWindows();
                             _msbuildToolsPath = FindMsBuildToolsPathOnWindows();
 
 
-                            if (_msbuildToolsPath.Empty())
-                            {
+                            if (string.IsNullOrEmpty(_msbuildToolsPath))
                                 throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildVs}'.");
                                 throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildVs}'.");
-                            }
                         }
                         }
 
 
                         if (!_msbuildToolsPath.EndsWith("\\"))
                         if (!_msbuildToolsPath.EndsWith("\\"))
@@ -57,15 +55,14 @@ namespace GodotTools.Build
                         string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat");
                         string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat");
 
 
                         if (!File.Exists(msbuildPath))
                         if (!File.Exists(msbuildPath))
-                        {
                             throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildMono}'. Tried with path: {msbuildPath}");
                             throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildMono}'. Tried with path: {msbuildPath}");
-                        }
 
 
                         return (msbuildPath, BuildTool.MsBuildMono);
                         return (msbuildPath, BuildTool.MsBuildMono);
                     }
                     }
                     case BuildTool.JetBrainsMsBuild:
                     case BuildTool.JetBrainsMsBuild:
                     {
                     {
                         var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
                         var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
+
                         if (!File.Exists(editorPath))
                         if (!File.Exists(editorPath))
                             throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
                             throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
 
 
@@ -83,7 +80,7 @@ namespace GodotTools.Build
                 }
                 }
             }
             }
 
 
-            if (OS.IsUnixLike())
+            if (OS.IsUnixLike)
             {
             {
                 switch (buildTool)
                 switch (buildTool)
                 {
                 {
@@ -138,12 +135,12 @@ namespace GodotTools.Build
         {
         {
             string ret = OS.PathWhich(name);
             string ret = OS.PathWhich(name);
 
 
-            if (!ret.Empty())
+            if (!string.IsNullOrEmpty(ret))
                 return ret;
                 return ret;
 
 
             string retFallback = OS.PathWhich($"{name}.exe");
             string retFallback = OS.PathWhich($"{name}.exe");
 
 
-            if (!retFallback.Empty())
+            if (!string.IsNullOrEmpty(retFallback))
                 return retFallback;
                 return retFallback;
 
 
             foreach (string hintDir in MsBuildHintDirs)
             foreach (string hintDir in MsBuildHintDirs)
@@ -195,7 +192,7 @@ namespace GodotTools.Build
 
 
                 string value = line.Substring(sepIdx + 1).StripEdges();
                 string value = line.Substring(sepIdx + 1).StripEdges();
 
 
-                if (value.Empty())
+                if (string.IsNullOrEmpty(value))
                     throw new FormatException("installationPath value is empty");
                     throw new FormatException("installationPath value is empty");
 
 
                 if (!value.EndsWith("\\"))
                 if (!value.EndsWith("\\"))

+ 6 - 6
modules/mono/editor/GodotTools/GodotTools/BuildTab.cs

@@ -72,7 +72,7 @@ namespace GodotTools
                     {
                     {
                         string[] csvColumns = file.GetCsvLine();
                         string[] csvColumns = file.GetCsvLine();
 
 
-                        if (csvColumns.Length == 1 && csvColumns[0].Empty())
+                        if (csvColumns.Length == 1 && string.IsNullOrEmpty(csvColumns[0]))
                             return;
                             return;
 
 
                         if (csvColumns.Length != 7)
                         if (csvColumns.Length != 7)
@@ -115,12 +115,12 @@ namespace GodotTools
             // Get correct issue idx from issue list
             // Get correct issue idx from issue list
             int issueIndex = (int)issuesList.GetItemMetadata(idx);
             int issueIndex = (int)issuesList.GetItemMetadata(idx);
 
 
-            if (idx < 0 || idx >= issues.Count)
+            if (issueIndex < 0 || issueIndex >= issues.Count)
                 throw new IndexOutOfRangeException("Issue index out of range");
                 throw new IndexOutOfRangeException("Issue index out of range");
 
 
             BuildIssue issue = issues[issueIndex];
             BuildIssue issue = issues[issueIndex];
 
 
-            if (issue.ProjectFile.Empty() && issue.File.Empty())
+            if (string.IsNullOrEmpty(issue.ProjectFile) && string.IsNullOrEmpty(issue.File))
                 return;
                 return;
 
 
             string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : BuildInfo.Solution.GetBaseDir();
             string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : BuildInfo.Solution.GetBaseDir();
@@ -158,14 +158,14 @@ namespace GodotTools
                     string tooltip = string.Empty;
                     string tooltip = string.Empty;
                     tooltip += $"Message: {issue.Message}";
                     tooltip += $"Message: {issue.Message}";
 
 
-                    if (!issue.Code.Empty())
+                    if (!string.IsNullOrEmpty(issue.Code))
                         tooltip += $"\nCode: {issue.Code}";
                         tooltip += $"\nCode: {issue.Code}";
 
 
                     tooltip += $"\nType: {(issue.Warning ? "warning" : "error")}";
                     tooltip += $"\nType: {(issue.Warning ? "warning" : "error")}";
 
 
                     string text = string.Empty;
                     string text = string.Empty;
 
 
-                    if (!issue.File.Empty())
+                    if (!string.IsNullOrEmpty(issue.File))
                     {
                     {
                         text += $"{issue.File}({issue.Line},{issue.Column}): ";
                         text += $"{issue.File}({issue.Line},{issue.Column}): ";
 
 
@@ -174,7 +174,7 @@ namespace GodotTools
                         tooltip += $"\nColumn: {issue.Column}";
                         tooltip += $"\nColumn: {issue.Column}";
                     }
                     }
 
 
-                    if (!issue.ProjectFile.Empty())
+                    if (!string.IsNullOrEmpty(issue.ProjectFile))
                         tooltip += $"\nProject: {issue.ProjectFile}";
                         tooltip += $"\nProject: {issue.ProjectFile}";
 
 
                     text += issue.Message;
                     text += issue.Message;

+ 4 - 4
modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs

@@ -302,7 +302,7 @@ namespace GodotTools
 
 
                 case ExternalEditorId.VsCode:
                 case ExternalEditorId.VsCode:
                 {
                 {
-                    if (_vsCodePath.Empty() || !File.Exists(_vsCodePath))
+                    if (string.IsNullOrEmpty(_vsCodePath) || !File.Exists(_vsCodePath))
                     {
                     {
                         // Try to search it again if it wasn't found last time or if it was removed from its location
                         // Try to search it again if it wasn't found last time or if it was removed from its location
                         _vsCodePath = VsCodeNames.SelectFirstNotNull(OS.PathWhich, orElse: string.Empty);
                         _vsCodePath = VsCodeNames.SelectFirstNotNull(OS.PathWhich, orElse: string.Empty);
@@ -354,7 +354,7 @@ namespace GodotTools
 
 
                     if (OS.IsOSX)
                     if (OS.IsOSX)
                     {
                     {
-                        if (!osxAppBundleInstalled && _vsCodePath.Empty())
+                        if (!osxAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath))
                         {
                         {
                             GD.PushError("Cannot find code editor: VSCode");
                             GD.PushError("Cannot find code editor: VSCode");
                             return Error.FileNotFound;
                             return Error.FileNotFound;
@@ -364,7 +364,7 @@ namespace GodotTools
                     }
                     }
                     else
                     else
                     {
                     {
-                        if (_vsCodePath.Empty())
+                        if (string.IsNullOrEmpty(_vsCodePath))
                         {
                         {
                             GD.PushError("Cannot find code editor: VSCode");
                             GD.PushError("Cannot find code editor: VSCode");
                             return Error.FileNotFound;
                             return Error.FileNotFound;
@@ -551,7 +551,7 @@ namespace GodotTools
                                    $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                    $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                    $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
                                    $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
             }
             }
-            else if (OS.IsUnixLike())
+            else if (OS.IsUnixLike)
             {
             {
                 settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
                 settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
                                    $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                    $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +

+ 1 - 5
modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj

@@ -1,12 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid>
     <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid>
-    <OutputType>Library</OutputType>
     <TargetFramework>net472</TargetFramework>
     <TargetFramework>net472</TargetFramework>
-    <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
-    <DataDirToolsOutputPath>$(GodotSourceRootPath)/bin/GodotSharp/Tools</DataDirToolsOutputPath>
-    <GodotApiConfiguration>Debug</GodotApiConfiguration>
-    <LangVersion>7</LangVersion>
+    <LangVersion>7.2</LangVersion>
     <GodotApiConfiguration>Debug</GodotApiConfiguration> <!-- The Godot editor uses the Debug Godot API assemblies -->
     <GodotApiConfiguration>Debug</GodotApiConfiguration> <!-- The Godot editor uses the Debug Godot API assemblies -->
     <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
     <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
     <GodotOutputDataDir>$(GodotSourceRootPath)/bin/GodotSharp</GodotOutputDataDir>
     <GodotOutputDataDir>$(GodotSourceRootPath)/bin/GodotSharp</GodotOutputDataDir>

+ 1 - 1
modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs

@@ -128,7 +128,7 @@ namespace GodotTools.Ides.MonoDevelop
                     {EditorId.MonoDevelop, "MonoDevelop.exe"}
                     {EditorId.MonoDevelop, "MonoDevelop.exe"}
                 };
                 };
             }
             }
-            else if (OS.IsUnixLike())
+            else if (OS.IsUnixLike)
             {
             {
                 ExecutableNames = new Dictionary<EditorId, string>
                 ExecutableNames = new Dictionary<EditorId, string>
                 {
                 {

+ 3 - 3
modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs

@@ -36,7 +36,7 @@ namespace GodotTools.Ides.Rider
                 {
                 {
                     return CollectRiderInfosMac();
                     return CollectRiderInfosMac();
                 }
                 }
-                if (OS.IsUnixLike())
+                if (OS.IsUnixLike)
                 {
                 {
                     return CollectAllRiderPathsLinux();
                     return CollectAllRiderPathsLinux();
                 }
                 }
@@ -147,7 +147,7 @@ namespace GodotTools.Ides.Rider
                 return GetToolboxRiderRootPath(localAppData);
                 return GetToolboxRiderRootPath(localAppData);
             }
             }
 
 
-            if (OS.IsUnixLike())
+            if (OS.IsUnixLike)
             {
             {
                 var home = Environment.GetEnvironmentVariable("HOME");
                 var home = Environment.GetEnvironmentVariable("HOME");
                 if (string.IsNullOrEmpty(home))
                 if (string.IsNullOrEmpty(home))
@@ -209,7 +209,7 @@ namespace GodotTools.Ides.Rider
 
 
         private static string GetRelativePathToBuildTxt()
         private static string GetRelativePathToBuildTxt()
         {
         {
-            if (OS.IsWindows || OS.IsUnixLike())
+            if (OS.IsWindows || OS.IsUnixLike)
                 return "../../build.txt";
                 return "../../build.txt";
             if (OS.IsOSX)
             if (OS.IsOSX)
                 return "Contents/Resources/build.txt";
                 return "Contents/Resources/build.txt";

+ 12 - 15
modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs

@@ -62,6 +62,11 @@ namespace GodotTools.Utils
             return name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
             return name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
         }
         }
 
 
+        private static bool IsAnyOS(IEnumerable<string> names)
+        {
+            return names.Any(p => p.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase));
+        }
+
         private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows));
         private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows));
         private static readonly Lazy<bool> _isOSX = new Lazy<bool>(() => IsOS(Names.OSX));
         private static readonly Lazy<bool> _isOSX = new Lazy<bool>(() => IsOS(Names.OSX));
         private static readonly Lazy<bool> _isX11 = new Lazy<bool>(() => IsOS(Names.X11));
         private static readonly Lazy<bool> _isX11 = new Lazy<bool>(() => IsOS(Names.X11));
@@ -71,6 +76,7 @@ namespace GodotTools.Utils
         private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android));
         private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android));
         private static readonly Lazy<bool> _isiOS = new Lazy<bool>(() => IsOS(Names.iOS));
         private static readonly Lazy<bool> _isiOS = new Lazy<bool>(() => IsOS(Names.iOS));
         private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5));
         private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5));
+        private static readonly Lazy<bool> _isUnixLike = new Lazy<bool>(() => IsAnyOS(UnixLikePlatforms));
 
 
         public static bool IsWindows => _isWindows.Value || IsUWP;
         public static bool IsWindows => _isWindows.Value || IsUWP;
         public static bool IsOSX => _isOSX.Value;
         public static bool IsOSX => _isOSX.Value;
@@ -82,18 +88,9 @@ namespace GodotTools.Utils
         public static bool IsiOS => _isiOS.Value;
         public static bool IsiOS => _isiOS.Value;
         public static bool IsHTML5 => _isHTML5.Value;
         public static bool IsHTML5 => _isHTML5.Value;
 
 
-        private static bool? _isUnixCache;
-        private static readonly string[] UnixLikePlatforms = { Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android, Names.iOS };
+        private static readonly string[] UnixLikePlatforms = {Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android, Names.iOS};
 
 
-        public static bool IsUnixLike()
-        {
-            if (_isUnixCache.HasValue)
-                return _isUnixCache.Value;
-
-            string osName = GetPlatformName();
-            _isUnixCache = UnixLikePlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase));
-            return _isUnixCache.Value;
-        }
+        public static bool IsUnixLike => _isUnixLike.Value;
 
 
         public static char PathSep => IsWindows ? ';' : ':';
         public static char PathSep => IsWindows ? ';' : ':';
 
 
@@ -121,10 +118,10 @@ namespace GodotTools.Utils
                 return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists);
                 return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists);
 
 
             return (from dir in searchDirs
             return (from dir in searchDirs
-                    select Path.Combine(dir, name)
+                select Path.Combine(dir, name)
                 into path
                 into path
-                    from ext in windowsExts
-                    select path + ext).FirstOrDefault(File.Exists);
+                from ext in windowsExts
+                select path + ext).FirstOrDefault(File.Exists);
         }
         }
 
 
         private static string PathWhichUnix([NotNull] string name)
         private static string PathWhichUnix([NotNull] string name)
@@ -189,7 +186,7 @@ namespace GodotTools.Utils
 
 
             startInfo.UseShellExecute = false;
             startInfo.UseShellExecute = false;
 
 
-            using (var process = new Process { StartInfo = startInfo })
+            using (var process = new Process {StartInfo = startInfo})
             {
             {
                 process.Start();
                 process.Start();
                 process.WaitForExit();
                 process.WaitForExit();