Last active
June 25, 2023 06:59
-
-
Save GER-NaN/a1998db21bb2b8770fe9b765211eb16f to your computer and use it in GitHub Desktop.
This will combine multiple .cs files from a solution into a single source file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using Microsoft.Build.Evaluation; | |
using Microsoft.Build.Construction; | |
namespace SourceCombiner | |
{ | |
public sealed class SourceCombiner | |
{ | |
private static readonly List<string> SourceFilesToIgnore = new List<string> | |
{ | |
"AssemblyInfo.cs" | |
}; | |
static void Main(string[] args) | |
{ | |
if (args == null || args.Length < 2) | |
{ | |
Console.WriteLine("You must provide at least 2 arguments. The first is the solution file path and the second is the output file path."); | |
return; | |
} | |
string projectFilePath = args[0]; | |
string outputFilePath = args[1]; | |
bool openFile = false; | |
if (args.Length > 2) | |
{ | |
Boolean.TryParse(args[2],out openFile); | |
} | |
var filesToParse = GetSourceFileNames(projectFilePath); | |
var namespaces = GetUniqueNamespaces(filesToParse); | |
string outputSource = GenerateCombinedSource(namespaces,filesToParse); | |
File.WriteAllText(outputFilePath,outputSource); | |
if (openFile) | |
{ | |
Process.Start(outputFilePath); | |
} | |
} | |
private static string GenerateCombinedSource(List<string> namespaces,List<string> files) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
sb.AppendLine(@"/*"); | |
sb.AppendLine($" * File generated by SourceCombiner.exe using {files.Count} source files."); | |
sb.AppendLine($" * Created On: {DateTime.Now}"); | |
sb.AppendLine(@"*/"); | |
foreach (var ns in namespaces.OrderBy(s => s)) | |
{ | |
sb.AppendLine("using " + ns + ";"); | |
} | |
foreach (var file in files) | |
{ | |
IEnumerable<string> sourceLines = File.ReadAllLines(file); | |
sb.AppendLine(@"//*** SourceCombiner -> original file " + Path.GetFileName(file) + " ***"); | |
var openingTag = "using "; | |
foreach (var sourceLine in sourceLines) | |
{ | |
var trimmedLine = sourceLine.Trim().Replace(" ", " "); | |
var isUsingDir = trimmedLine.StartsWith(openingTag) && trimmedLine.EndsWith(";"); | |
if (!string.IsNullOrWhiteSpace(sourceLine) && !isUsingDir) | |
{ | |
sb.AppendLine(sourceLine); | |
} | |
} | |
} | |
return sb.ToString(); | |
} | |
private static List<string> GetSourceFileNames(string solutionFilePath) | |
{ | |
List<string> files = new List<string>(); | |
SolutionFile solutionFile = SolutionFile.Parse(solutionFilePath); | |
foreach (Project project in solutionFile.ProjectsInOrder.Select(p => new Project(p.AbsolutePath))) | |
{ | |
foreach (ProjectItem item in project.AllEvaluatedItems.Where(item => item.ItemType == "Compile")) | |
{ | |
if (!SourceFilesToIgnore.Contains(Path.GetFileName(item.EvaluatedInclude))) | |
{ | |
string projectFolder = Path.GetDirectoryName(project.FullPath); | |
string fullpath = Path.Combine(projectFolder, item.EvaluatedInclude); | |
files.Add(fullpath); | |
} | |
} | |
} | |
return files; | |
} | |
private static List<string> GetUniqueNamespaces(List<string> files) | |
{ | |
var names = new List<string>(); | |
const string openingTag = "using "; | |
const int namespaceStartIndex = 6; | |
foreach (var file in files) | |
{ | |
IEnumerable<string> sourceLines = File.ReadAllLines(file); | |
foreach (var sourceLine in sourceLines) | |
{ | |
var trimmedLine = sourceLine.Trim().Replace(" ", " "); | |
if (trimmedLine.StartsWith(openingTag) && trimmedLine.EndsWith(";")) | |
{ | |
var name = trimmedLine.Substring(namespaceStartIndex, trimmedLine.Length - namespaceStartIndex - 1); | |
if (!names.Contains(name)) | |
{ | |
names.Add(name); | |
} | |
} | |
} | |
} | |
return names; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment