Roslyn Sample: Rename items in a solution

Sometimes you make mistakes. No really, you do. Sometimes you use an incorrect term or word in a project, and then you need to replace it everywhere.

While it is quite easy to do this within source files (with a simple search/replace or building a tool to do it in bulk), it’s not so easy to rename the source files. Worst even if they are checked-in to source control.

After getting to know the Microsoft “Roslyn” CTP, it seemed like the right tool to help with this task. I needed to rename a lot of files in a solution to match the new class names. I had already built a small sample that went through a solution/projects/documents and created a text report.

It was only a matter of adapting this sample with a few tweaks. As always, the effort put into automating something should be worth it. So I followed the ASAP principle, which in this case means As Simple As Possible.

Instead of fiddling with the TFS API, the idea was to keep the “project iterator” and output a command-line instruction into a file whenever a document name matches the search criteria. After generating the file, its contents can be checked against the expected result, and if everything is OK, running it will rename all the files.

Enjoy!

Source:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Roslyn.Services;
using Roslyn.Scripting.CSharp;

namespace RoslynSample
{
  class Program
  {
    static void Main(string[] args)
    {
      RefactorSolution(@"C:\Src\MyApp.Full.sln", "ExternalClient", "ExternalCustomer");

      Console.ReadKey();
    }

    private static void RefactorSolution(string solutionPath, string fileNameFilter, string replacement)
    {
      var builder = new StringBuilder();
      var workspace = Workspace.LoadSolution(solutionPath);

      var solution = workspace.CurrentSolution;

      if (solution != null)
      {
        foreach (var project in solution.Projects)
        {
          var documentsToProcess = project.Documents.Where(d => d.DisplayName.Contains(fileNameFilter));

          foreach (var document in documentsToProcess)
          {
            var targetItemSpec = Path.Combine(
            Path.GetDirectoryName(document.Id.FileName),
            document.DisplayName.Replace(fileNameFilter, replacement));

            builder.AppendFormat(@"tf.exe rename ""{0}"" ""{1}""{2}", document.Id.FileName, targetItemSpec, Environment.NewLine);
          }
        }
      }

      File.WriteAllText("rename.cmd", builder.ToString());
    }
  }
}

1 thought on “Roslyn Sample: Rename items in a solution

Leave a comment