Browse Source

C#: Don't overwrite newer Godot.NET.Sdk patch version in csproj

Allow game projects to use a Godot.NET.Sdk with a newer patch version.
The major and minor version are still required to be the same.

For example: Allow a Godot 3.2.4 C# project to use a hypothetical
3.2.5 version of Godot.NET.Sdk.
Ignacio Etcheverry 4 years ago
parent
commit
9b24d5f2d0

+ 1 - 0
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj

@@ -7,6 +7,7 @@
   <ItemGroup>
     <Reference Include="Microsoft.Build" />
     <PackageReference Include="Microsoft.Build" Version="16.5.0" />
+    <PackageReference Include="semver" Version="2.0.6" />
     <PackageReference Include="JetBrains.Annotations" Version="2019.1.3.0" ExcludeAssets="runtime" PrivateAssets="all" />
     <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
   </ItemGroup>

+ 2 - 3
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs

@@ -9,8 +9,7 @@ namespace GodotTools.ProjectEditor
     public static class ProjectGenerator
     {
         public const string GodotSdkVersionToUse = "3.2.3";
-
-        public static string GodotSdkAttrValue => $"Godot.NET.Sdk/{GodotSdkVersionToUse}";
+        public const string GodotSdkNameToUse = "Godot.NET.Sdk";
 
         public static ProjectRootElement GenGameProject(string name)
         {
@@ -19,7 +18,7 @@ namespace GodotTools.ProjectEditor
 
             var root = ProjectRootElement.Create(NewProjectFileOptions.None);
 
-            root.Sdk = GodotSdkAttrValue;
+            root.Sdk = $"{GodotSdkNameToUse}/{GodotSdkVersionToUse}";
 
             var mainGroup = root.AddPropertyGroup();
             mainGroup.AddProperty("TargetFramework", "net472");

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

@@ -4,11 +4,13 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
+using System.Text.RegularExpressions;
 using System.Xml;
 using System.Xml.Linq;
 using JetBrains.Annotations;
 using Microsoft.Build.Construction;
 using Microsoft.Build.Globbing;
+using Semver;
 
 namespace GodotTools.ProjectEditor
 {
@@ -189,7 +191,7 @@ namespace GodotTools.ProjectEditor
                         continue;
 
 
-                    string normalizedRemove= item.Remove.NormalizePath();
+                    string normalizedRemove = item.Remove.NormalizePath();
 
                     var glob = MSBuildGlob.Parse(normalizedRemove);
 
@@ -233,7 +235,7 @@ namespace GodotTools.ProjectEditor
             if (!string.IsNullOrEmpty(root.Sdk))
                 return;
 
-            root.Sdk = ProjectGenerator.GodotSdkAttrValue;
+            root.Sdk = $"{ProjectGenerator.GodotSdkNameToUse}/{ProjectGenerator.GodotSdkVersionToUse}";
 
             root.ToolsVersion = null;
             root.DefaultTargets = null;
@@ -408,11 +410,32 @@ namespace GodotTools.ProjectEditor
 
         public static void EnsureGodotSdkIsUpToDate(MSBuildProject project)
         {
+            string godotSdkAttrValue = $"{ProjectGenerator.GodotSdkNameToUse}/{ProjectGenerator.GodotSdkVersionToUse}";
+
             var root = project.Root;
-            string godotSdkAttrValue = ProjectGenerator.GodotSdkAttrValue;
+            string rootSdk = root.Sdk?.Trim();
 
-            if (!string.IsNullOrEmpty(root.Sdk) && root.Sdk.Trim().Equals(godotSdkAttrValue, StringComparison.OrdinalIgnoreCase))
-                return;
+            if (!string.IsNullOrEmpty(rootSdk))
+            {
+                // Check if the version is already the same.
+                if (rootSdk.Equals(godotSdkAttrValue, StringComparison.OrdinalIgnoreCase))
+                    return;
+
+                // We also allow higher versions as long as the major and minor are the same.
+                var semVerToUse = SemVersion.Parse(ProjectGenerator.GodotSdkVersionToUse);
+                var godotSdkAttrLaxValueRegex = new Regex($@"^{ProjectGenerator.GodotSdkNameToUse}/(?<ver>.*)$");
+
+                var match = godotSdkAttrLaxValueRegex.Match(rootSdk);
+
+                if (match.Success &&
+                    SemVersion.TryParse(match.Groups["ver"].Value, out var semVerDetected) &&
+                    semVerDetected.Major == semVerToUse.Major &&
+                    semVerDetected.Minor == semVerToUse.Minor &&
+                    semVerDetected > semVerToUse)
+                {
+                    return;
+                }
+            }
 
             root.Sdk = godotSdkAttrValue;
             project.HasUnsavedChanges = true;