From 2d2b93926539bb732753ecccd39259a1504d815e Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Sat, 20 Dec 2025 11:04:31 -0500 Subject: [PATCH] feat(rename): rename project file and parent directory - Add RenameProjectFile method to rename .csproj on disk - Add RenameParentDirectoryIfMatches method to rename folder if it matches project name - Uses full paths via Path and DirectoryInfo classes - Directory rename only occurs if folder name matches old project name (case-insensitive) - Both methods return new path for subsequent operations Closes #20 Closes #21 --- .../Commands/RenamifyProjectCommand.cs | 8 +++ .../Services/ProjectFileService.cs | 52 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs index e0ed85e..b827d63 100644 --- a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs +++ b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs @@ -86,8 +86,16 @@ private void RenameProject(Project project, DTE2 dte) // Update namespace declarations in source files SourceFileService.UpdateNamespacesInProject(projectFilePath, currentName, newName); + // Rename parent directory if it matches project name + projectFilePath = ProjectFileService.RenameParentDirectoryIfMatches(projectFilePath, currentName, newName); + + // Rename the project file on disk + projectFilePath = ProjectFileService.RenameProjectFile(projectFilePath, newName); + // TODO: Implement remaining rename operations // See open issues for requirements: + // - #22: Remove and re-add project to solution + // - #23: Update project references // - #9: Update using statements across solution // - #11: Solution folder support // - #12: Progress indication diff --git a/src/CodingWithCalvin.ProjectRenamifier/Services/ProjectFileService.cs b/src/CodingWithCalvin.ProjectRenamifier/Services/ProjectFileService.cs index 0d909c3..f430fdf 100644 --- a/src/CodingWithCalvin.ProjectRenamifier/Services/ProjectFileService.cs +++ b/src/CodingWithCalvin.ProjectRenamifier/Services/ProjectFileService.cs @@ -1,3 +1,4 @@ +using System.IO; using System.Xml; namespace CodingWithCalvin.ProjectRenamifier.Services @@ -7,6 +8,57 @@ namespace CodingWithCalvin.ProjectRenamifier.Services /// internal static class ProjectFileService { + /// + /// Renames the project file on disk. + /// + /// Full path to the current .csproj file. + /// The new project name (without extension). + /// The new full path to the renamed project file. + 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; + } + + /// + /// Renames the parent directory if its name matches the old project name. + /// + /// Full path to the .csproj file. + /// The old project name to match against. + /// The new project name. + /// The new full path to the project file after directory rename, or the original path if no rename occurred. + 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); + } + /// /// Updates the RootNamespace and AssemblyName elements in a project file /// if they match the old project name.