-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjectFileService.cs
More file actions
130 lines (110 loc) · 4.94 KB
/
ProjectFileService.cs
File metadata and controls
130 lines (110 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System.IO;
using System.Xml;
namespace CodingWithCalvin.ProjectRenamifier.Services
{
/// <summary>
/// Service for updating project file (.csproj) elements.
/// </summary>
internal static class ProjectFileService
{
/// <summary>
/// Renames the project file on disk.
/// </summary>
/// <param name="projectFilePath">Full path to the current .csproj file.</param>
/// <param name="newName">The new project name (without extension).</param>
/// <returns>The new full path to the renamed project file.</returns>
public static string RenameProjectFile(string projectFilePath, string newName)
{
var directory = Path.GetDirectoryName(projectFilePath);
var extension = Path.GetExtension(projectFilePath);
var newFileName = newName + extension;
var newFilePath = Path.Combine(directory, newFileName);
File.Move(projectFilePath, newFilePath);
return newFilePath;
}
/// <summary>
/// Renames the parent directory if its name matches the old project name.
/// </summary>
/// <param name="projectFilePath">Full path to the .csproj file.</param>
/// <param name="oldName">The old project name to match against.</param>
/// <param name="newName">The new project name.</param>
/// <returns>The new full path to the project file after directory rename, or the original path if no rename occurred.</returns>
public static string RenameParentDirectoryIfMatches(string projectFilePath, string oldName, string newName)
{
var projectDirectory = Path.GetDirectoryName(projectFilePath);
var parentDirectory = Directory.GetParent(projectDirectory);
if (parentDirectory == null)
{
return projectFilePath;
}
var directoryName = new DirectoryInfo(projectDirectory).Name;
// Only rename if directory name matches the old project name
if (!directoryName.Equals(oldName, StringComparison.OrdinalIgnoreCase))
{
return projectFilePath;
}
var newDirectoryPath = Path.Combine(parentDirectory.FullName, newName);
Directory.Move(projectDirectory, newDirectoryPath);
// Return the new project file path
var fileName = Path.GetFileName(projectFilePath);
return Path.Combine(newDirectoryPath, fileName);
}
/// <summary>
/// Updates the RootNamespace and AssemblyName elements in a project file
/// if they match the old project name.
/// </summary>
/// <param name="projectFilePath">Full path to the .csproj file.</param>
/// <param name="oldName">The old project name to match against.</param>
/// <param name="newName">The new project name to set.</param>
/// <returns>True if any changes were made, false otherwise.</returns>
public static bool UpdateProjectFile(string projectFilePath, string oldName, string newName)
{
var doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(projectFilePath);
var modified = false;
modified |= UpdateElement(doc, "RootNamespace", oldName, newName);
modified |= UpdateElement(doc, "AssemblyName", oldName, newName);
if (modified)
{
doc.Save(projectFilePath);
}
return modified;
}
/// <summary>
/// Updates a specific element in the project file if its value matches the old name.
/// </summary>
private static bool UpdateElement(XmlDocument doc, string elementName, string oldName, string newName)
{
// Handle both SDK-style (no namespace) and legacy (with namespace) project files
var namespaceManager = new XmlNamespaceManager(doc.NameTable);
var msbuildNs = "http://schemas.microsoft.com/developer/msbuild/2003";
// Check if document uses the MSBuild namespace
var hasNamespace = doc.DocumentElement?.NamespaceURI == msbuildNs;
XmlNodeList nodes;
if (hasNamespace)
{
namespaceManager.AddNamespace("ms", msbuildNs);
nodes = doc.SelectNodes($"//ms:{elementName}", namespaceManager);
}
else
{
nodes = doc.SelectNodes($"//{elementName}");
}
if (nodes == null || nodes.Count == 0)
{
return false;
}
var modified = false;
foreach (XmlNode node in nodes)
{
if (node.InnerText.Equals(oldName, StringComparison.OrdinalIgnoreCase))
{
node.InnerText = newName;
modified = true;
}
}
return modified;
}
}
}