ProjectUtils.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using GodotTools.Core;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using Microsoft.Build.Construction;
  8. using Microsoft.Build.Globbing;
  9. namespace GodotTools.ProjectEditor
  10. {
  11. public sealed class MSBuildProject
  12. {
  13. internal ProjectRootElement Root { get; set; }
  14. public bool HasUnsavedChanges { get; set; }
  15. public void Save() => Root.Save();
  16. public MSBuildProject(ProjectRootElement root)
  17. {
  18. Root = root;
  19. }
  20. }
  21. public static class ProjectUtils
  22. {
  23. public static MSBuildProject Open(string path)
  24. {
  25. var root = ProjectRootElement.Open(path);
  26. return root != null ? new MSBuildProject(root) : null;
  27. }
  28. private static List<string> GetAllFilesRecursive(string rootDirectory, string mask)
  29. {
  30. string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
  31. // We want relative paths
  32. for (int i = 0; i < files.Length; i++)
  33. {
  34. files[i] = files[i].RelativeToPath(rootDirectory);
  35. }
  36. return new List<string>(files);
  37. }
  38. // NOTE: Assumes auto-including items. Only used by the scripts metadata generator, which will be replaced with source generators in the future.
  39. public static IEnumerable<string> GetIncludeFiles(string projectPath, string itemType)
  40. {
  41. var excluded = new List<string>();
  42. var includedFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
  43. var root = ProjectRootElement.Open(projectPath);
  44. Debug.Assert(root != null);
  45. foreach (var item in root.Items)
  46. {
  47. if (string.IsNullOrEmpty(item.Condition))
  48. continue;
  49. if (item.ItemType != itemType)
  50. continue;
  51. string normalizedExclude = item.Exclude.NormalizePath();
  52. var glob = MSBuildGlob.Parse(normalizedExclude);
  53. excluded.AddRange(includedFiles.Where(includedFile => glob.IsMatch(includedFile)));
  54. }
  55. includedFiles.RemoveAll(f => excluded.Contains(f));
  56. return includedFiles;
  57. }
  58. public static void MigrateToProjectSdksStyle(MSBuildProject project, string projectName)
  59. {
  60. var origRoot = project.Root;
  61. if (!string.IsNullOrEmpty(origRoot.Sdk))
  62. return;
  63. project.Root = ProjectGenerator.GenGameProject(projectName);
  64. project.Root.FullPath = origRoot.FullPath;
  65. project.HasUnsavedChanges = true;
  66. }
  67. public static void EnsureGodotSdkIsUpToDate(MSBuildProject project)
  68. {
  69. var root = project.Root;
  70. string godotSdkAttrValue = ProjectGenerator.GodotSdkAttrValue;
  71. if (!string.IsNullOrEmpty(root.Sdk) && root.Sdk.Trim().Equals(godotSdkAttrValue, StringComparison.OrdinalIgnoreCase))
  72. return;
  73. root.Sdk = godotSdkAttrValue;
  74. project.HasUnsavedChanges = true;
  75. }
  76. }
  77. }