From 1b634785b50a8be5ff6f06feeb13726750115615 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Sat, 14 Mar 2020 19:01:29 +0100 Subject: [PATCH] C#: Replace uses of old Configuration and update old csprojs --- .../DotNetSolution.cs | 21 +++- .../ProjectGenerator.cs | 60 ++++----- .../GodotTools.ProjectEditor/ProjectUtils.cs | 119 ++++++++++++++++-- .../GodotTools/GodotTools/BottomPanel.cs | 2 +- .../GodotTools/GodotTools/BuildManager.cs | 6 +- .../GodotTools/Export/ExportPlugin.cs | 2 +- .../GodotTools/GodotTools/GodotSharpEditor.cs | 11 +- modules/mono/glue/GodotSharp/GodotSharp.sln | 2 - 8 files changed, 171 insertions(+), 52 deletions(-) diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index be57683c1f0..9afd9adeb13 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -121,15 +121,30 @@ EndProject"; @" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU {{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU"; - public static void FixConfigurations(string slnPath) + public static void MigrateFromOldConfigNames(string slnPath) { if (!File.Exists(slnPath)) return; - + var input = File.ReadAllText(slnPath); + + if (!Regex.IsMatch(input, Regex.Escape("Tools|Any CPU"))) + return; + + // This method renames old configurations in solutions to the new ones. + // + // This is the order configs appear in the solution and what we want to rename them to: + // Debug|Any CPU = Debug|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU + // Tools|Any CPU = Tools|Any CPU -> Debug|Any CPU = Debug|Any CPU + // + // But we want to move Tools (now Debug) to the top, so it's easier to rename like this: + // Debug|Any CPU = Debug|Any CPU -> Debug|Any CPU = Debug|Any CPU + // Release|Any CPU = Release|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU + // Tools|Any CPU = Tools|Any CPU -> ExportRelease|Any CPU = ExportRelease|Any CPU + var dict = new Dictionary { - {"Debug|Any CPU", "Tools|Any CPU"}, + {"Debug|Any CPU", "Debug|Any CPU"}, {"Release|Any CPU", "ExportDebug|Any CPU"}, {"Tools|Any CPU", "ExportRelease|Any CPU"} }; diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs index 28b7832f902..cbe3afaeddd 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs @@ -17,30 +17,30 @@ namespace GodotTools.ProjectEditor string path = Path.Combine(dir, name + ".csproj"); ProjectPropertyGroupElement mainGroup; - var root = CreateLibraryProject(name, "Tools", out mainGroup); + var root = CreateLibraryProject(name, "Debug", out mainGroup); mainGroup.SetProperty("OutputPath", Path.Combine(".mono", "temp", "bin", "$(Configuration)")); mainGroup.SetProperty("BaseIntermediateOutputPath", Path.Combine(".mono", "temp", "obj")); mainGroup.SetProperty("IntermediateOutputPath", Path.Combine("$(BaseIntermediateOutputPath)", "$(Configuration)")); - mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'Release' "; - mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'Release' "; + mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'ExportRelease' "; + mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'ExportRelease' "; - var toolsGroup = root.AddPropertyGroup(); - toolsGroup.Condition = " '$(Configuration)|$(Platform)' == 'Tools|AnyCPU' "; - toolsGroup.AddProperty("DebugSymbols", "true"); - toolsGroup.AddProperty("DebugType", "portable"); - toolsGroup.AddProperty("Optimize", "false"); - toolsGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;"); - toolsGroup.AddProperty("ErrorReport", "prompt"); - toolsGroup.AddProperty("WarningLevel", "4"); - toolsGroup.AddProperty("ConsolePause", "false"); + var debugGroup = root.AddPropertyGroup(); + debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "; + debugGroup.AddProperty("DebugSymbols", "true"); + debugGroup.AddProperty("DebugType", "portable"); + debugGroup.AddProperty("Optimize", "false"); + debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;"); + debugGroup.AddProperty("ErrorReport", "prompt"); + debugGroup.AddProperty("WarningLevel", "4"); + debugGroup.AddProperty("ConsolePause", "false"); var coreApiRef = root.AddItem("Reference", CoreApiProjectName); coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll")); coreApiRef.AddMetadata("Private", "False"); var editorApiRef = root.AddItem("Reference", EditorApiProjectName); - editorApiRef.Condition = " '$(Configuration)' == 'Tools' "; + editorApiRef.Condition = " '$(Configuration)' == 'Debug' "; editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll")); editorApiRef.AddMetadata("Private", "False"); @@ -103,24 +103,24 @@ namespace GodotTools.ProjectEditor mainGroup.AddProperty("TargetFrameworkVersion", "v4.7"); mainGroup.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - var debugGroup = root.AddPropertyGroup(); - debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "; - debugGroup.AddProperty("DebugSymbols", "true"); - debugGroup.AddProperty("DebugType", "portable"); - debugGroup.AddProperty("Optimize", "false"); - debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;"); - debugGroup.AddProperty("ErrorReport", "prompt"); - debugGroup.AddProperty("WarningLevel", "4"); - debugGroup.AddProperty("ConsolePause", "false"); + var exportDebugGroup = root.AddPropertyGroup(); + exportDebugGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportDebug|AnyCPU' "; + exportDebugGroup.AddProperty("DebugSymbols", "true"); + exportDebugGroup.AddProperty("DebugType", "portable"); + exportDebugGroup.AddProperty("Optimize", "false"); + exportDebugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;"); + exportDebugGroup.AddProperty("ErrorReport", "prompt"); + exportDebugGroup.AddProperty("WarningLevel", "4"); + exportDebugGroup.AddProperty("ConsolePause", "false"); - var releaseGroup = root.AddPropertyGroup(); - releaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "; - releaseGroup.AddProperty("DebugType", "portable"); - releaseGroup.AddProperty("Optimize", "true"); - releaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;"); - releaseGroup.AddProperty("ErrorReport", "prompt"); - releaseGroup.AddProperty("WarningLevel", "4"); - releaseGroup.AddProperty("ConsolePause", "false"); + var exportReleaseGroup = root.AddPropertyGroup(); + exportReleaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportRelease|AnyCPU' "; + exportReleaseGroup.AddProperty("DebugType", "portable"); + exportReleaseGroup.AddProperty("Optimize", "true"); + exportReleaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;"); + exportReleaseGroup.AddProperty("ErrorReport", "prompt"); + exportReleaseGroup.AddProperty("WarningLevel", "4"); + exportReleaseGroup.AddProperty("ConsolePause", "false"); // References var referenceGroup = root.AddItemGroup(); diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs index 233aab45b3f..af36f125f51 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using DotNet.Globbing; using Microsoft.Build.Construction; @@ -44,6 +45,7 @@ namespace GodotTools.ProjectEditor globOptions.Evaluation.CaseInsensitive = false; var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); foreach (var itemGroup in root.ItemGroups) { @@ -85,35 +87,35 @@ namespace GodotTools.ProjectEditor void AddPropertyIfNotPresent(string name, string condition, string value) { if (root.PropertyGroups - .Any(g => (g.Condition == string.Empty || g.Condition == condition) && + .Any(g => (g.Condition == string.Empty || g.Condition.Trim() == condition) && g.Properties .Any(p => p.Name == name && p.Value == value && - (p.Condition == condition || g.Condition == condition)))) + (p.Condition.Trim() == condition || g.Condition.Trim() == condition)))) { return; } - root.AddProperty(name, value).Condition = condition; + root.AddProperty(name, value).Condition = " " + condition + " "; dirty = true; } AddPropertyIfNotPresent(name: "ApiConfiguration", - condition: " '$(Configuration)' != 'Release' ", + condition: "'$(Configuration)' != 'ExportRelease'", value: "Debug"); AddPropertyIfNotPresent(name: "ApiConfiguration", - condition: " '$(Configuration)' == 'Release' ", + condition: "'$(Configuration)' == 'ExportRelease'", value: "Release"); void SetReferenceHintPath(string referenceName, string condition, string hintPath) { foreach (var itemGroup in root.ItemGroups.Where(g => - g.Condition == string.Empty || g.Condition == condition)) + g.Condition.Trim() == string.Empty || g.Condition.Trim() == condition)) { var references = itemGroup.Items.Where(item => item.ItemType == "Reference" && item.Include == referenceName && - (item.Condition == condition || itemGroup.Condition == condition)); + (item.Condition.Trim() == condition || itemGroup.Condition.Trim() == condition)); var referencesWithHintPath = references.Where(reference => reference.Metadata.Any(m => m.Name == "HintPath")); @@ -152,7 +154,7 @@ namespace GodotTools.ProjectEditor } // Found no Reference item at all. Add it. - root.AddItem("Reference", referenceName).Condition = condition; + root.AddItem("Reference", referenceName).Condition = " " + condition + " "; dirty = true; } @@ -160,7 +162,7 @@ namespace GodotTools.ProjectEditor const string editorProjectName = "GodotSharpEditor"; const string coreCondition = ""; - const string editorCondition = " '$(Configuration)' == 'Tools' "; + const string editorCondition = "'$(Configuration)' == 'Debug'"; var coreHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll"; var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll"; @@ -168,6 +170,105 @@ namespace GodotTools.ProjectEditor SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath); SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath); + if (dirty) + root.Save(); + } + + public static void MigrateFromOldConfigNames(string projectPath) + { + var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + + bool dirty = false; + + bool hasGodotProjectGeneratorVersion = false; + bool foundOldConfiguration = false; + + foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition == string.Empty)) + { + if (!hasGodotProjectGeneratorVersion && propertyGroup.Properties.Any(p => p.Name == "GodotProjectGeneratorVersion")) + hasGodotProjectGeneratorVersion = true; + + foreach (var configItem in propertyGroup.Properties + .Where(p => p.Condition.Trim() == "'$(Configuration)' == ''" && p.Value == "Tools")) + { + configItem.Value = "Debug"; + foundOldConfiguration = true; + dirty = true; + } + } + + if (!hasGodotProjectGeneratorVersion) + { + root.PropertyGroups.First(g => g.Condition == string.Empty)? + .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); + dirty = true; + } + + if (!foundOldConfiguration) + { + var toolsConditions = new[] + { + "'$(Configuration)|$(Platform)' == 'Tools|AnyCPU'", + "'$(Configuration)|$(Platform)' != 'Tools|AnyCPU'", + "'$(Configuration)' == 'Tools'", + "'$(Configuration)' != 'Tools'" + }; + + foundOldConfiguration = root.PropertyGroups + .Any(g => toolsConditions.Any(c => c == g.Condition.Trim())); + } + + if (foundOldConfiguration) + { + void MigrateConfigurationConditions(string oldConfiguration, string newConfiguration) + { + void MigrateConditions(string oldCondition, string newCondition) + { + foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition)) + { + propertyGroup.Condition = " " + newCondition + " "; + dirty = true; + } + + foreach (var propertyGroup in root.PropertyGroups) + { + foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition)) + { + prop.Condition = " " + newCondition + " "; + dirty = true; + } + } + + foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition)) + { + itemGroup.Condition = " " + newCondition + " "; + dirty = true; + } + + foreach (var itemGroup in root.ItemGroups) + { + foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition)) + { + item.Condition = " " + newCondition + " "; + dirty = true; + } + } + } + + foreach (var op in new[] {"==", "!="}) + { + MigrateConditions($"'$(Configuration)|$(Platform)' {op} '{oldConfiguration}|AnyCPU'", $"'$(Configuration)|$(Platform)' {op} '{newConfiguration}|AnyCPU'"); + MigrateConditions($"'$(Configuration)' {op} '{oldConfiguration}'", $"'$(Configuration)' {op} '{newConfiguration}'"); + } + } + + MigrateConfigurationConditions("Debug", "ExportDebug"); + MigrateConfigurationConditions("Release", "ExportRelease"); + MigrateConfigurationConditions("Tools", "Debug"); // Must be last + } + + if (dirty) root.Save(); } diff --git a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs index bd7eb599130..2971236482e 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs @@ -166,7 +166,7 @@ namespace GodotTools Internal.GodotIs32Bits() ? "32" : "64" }; - bool buildSuccess = BuildManager.BuildProjectBlocking("Tools", godotDefines); + bool buildSuccess = BuildManager.BuildProjectBlocking("Debug", godotDefines); if (!buildSuccess) return; diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs index 69a8c9cf4a1..94214cbb8fd 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs @@ -166,7 +166,7 @@ namespace GodotTools // Make sure the API assemblies are up to date before building the project. // We may not have had the chance to update the release API assemblies, and the debug ones // may have been deleted by the user at some point after they were loaded by the Godot editor. - string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "Release" ? "Release" : "Debug"); + string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "ExportRelease" ? "Release" : "Debug"); if (!string.IsNullOrEmpty(apiAssembliesUpdateError)) { @@ -242,7 +242,7 @@ namespace GodotTools Internal.GodotIs32Bits() ? "32" : "64" }; - return BuildProjectBlocking("Tools", godotDefines); + return BuildProjectBlocking("Debug", godotDefines); } public static void Initialize() @@ -256,7 +256,7 @@ namespace GodotTools : BuildTool.MsBuildVs; EditorDef("mono/builds/build_tool", msbuild); - + editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary { ["type"] = Godot.Variant.Type.Int, diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 3e2a8c22a98..05f84f547b8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -150,7 +150,7 @@ namespace GodotTools.Export string outputDir = new FileInfo(path).Directory?.FullName ?? throw new FileNotFoundException("Base directory not found"); - string buildConfig = isDebug ? "Debug" : "Release"; + string buildConfig = isDebug ? "ExportDebug" : "ExportRelease"; string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}"); CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 36caab8c299..796522b2f22 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -61,7 +61,7 @@ namespace GodotTools { Guid = guid, PathRelativeToSolution = name + ".csproj", - Configs = new List { "Tools", "ExportDebug", "ExportRelease" } + Configs = new List { "Debug", "ExportDebug", "ExportRelease" } }; solution.AddNewProject(name, projectInfo); @@ -403,10 +403,15 @@ namespace GodotTools { try { + // Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease + DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath); + // Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease + ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath); + + // Apply the other fixes after configurations are migrated + // Make sure the existing project has Api assembly references configured correctly ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); - // Make sure SolutionConfigurations are Tool, ExportDebug and ExportRelease - DotNetSolution.FixConfigurations(GodotSharpDirs.ProjectSlnPath); } catch (Exception e) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp.sln b/modules/mono/glue/GodotSharp/GodotSharp.sln index a496e36da36..4896d0a07de 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp.sln +++ b/modules/mono/glue/GodotSharp/GodotSharp.sln @@ -8,8 +8,6 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU