Skip to content

Commit

Permalink
Adding default test project to the SolutionGenerator tool
Browse files Browse the repository at this point in the history
  • Loading branch information
thepirat000 committed Jan 20, 2025
1 parent c7b63da commit 722412f
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 12 deletions.
97 changes: 86 additions & 11 deletions tools/SolutionGenerator/SolutionGenerator/Program.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
// MvsSln Doc: https://github.com/3F/MvsSln

using System.Reflection;
using System.Text;

using Microsoft.Build.Evaluation;

using net.r_eg.MvsSln;
using net.r_eg.MvsSln.Core;
using net.r_eg.MvsSln.Core.ObjHandlers;
using net.r_eg.MvsSln.Core.SlnHandlers;

using ProjectItem = net.r_eg.MvsSln.Core.ProjectItem;

namespace SolutionGenerator
{
public static class Program
{
// Args:
// 0: Input sln path
// 1: Filters (comma separated)
// 1: Filters (comma separated, e.g.: "entityframework,!core")
// 2: Output sln path
static void Main(string[] args)
{
Expand All @@ -22,17 +27,21 @@ static void Main(string[] args)
return;
}

var currentDirectory = new DirectoryInfo(Environment.CurrentDirectory);
var inputSlnPath = args[0];
var filters = args[1].Split(",").Where(f => f.Length > 0).ToList();
var outputSlnPath = args.Length > 2 && args[2].Length > 0 ? args[2] : $"{new DirectoryInfo(Environment.CurrentDirectory).Name}.sln";

var outputSlnPath = args.Length > 2 && args[2].Length > 0 ? args[2] : $"{currentDirectory.Name}.sln";
var outputDir = Path.GetDirectoryName(outputSlnPath)!;

if (!outputSlnPath.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
{
outputSlnPath += ".sln";
}

var sln = new Sln(inputSlnPath, SlnItems.AllNoLoad);
using var sln = new Sln(inputSlnPath, SlnItems.AllNoLoad);

// Apply filters
var projects = sln.Result.ProjectItems
.Where(p => IncludeProject(p, filters))
.ToList();
Expand All @@ -48,23 +57,45 @@ static void Main(string[] args)
for (int i = 0; i < projects.Count; i++)
{
Console.WriteLine($"Adding {projects[i].name}");

// Replace relative path with full path
projects[i] = projects[i] with { path = projects[i].fullPath };
}
Console.WriteLine();

// New project
var testProjectName = Path.GetFileNameWithoutExtension(outputSlnPath) + ".csproj";
var testProject = new ProjectItem(ProjectType.CsSdk, testProjectName, slnDir: outputDir);

projects.Add(testProject);
sln.Result.ProjectDependencies.GuidList.Add(testProject.pGuid);
sln.Result.ProjectDependencies.Projects.Add(testProject.pGuid, testProject);

var projectConfPlat = sln.Result.ProjectConfigurationPlatforms.Values.First()
.Where(pc => projects.Exists(prj => prj.pGuid == pc.PGuid))
.ToList();

var solutionFolders = sln.Result.SolutionFolders;

// Write modified sln
Console.WriteLine($"Writing modified sln to {outputSlnPath}");
var handlers = new Dictionary<Type, HandlerValue>()
{
[typeof(LProject)] = new(new WProject(projects, sln.Result.ProjectDependencies)),
[typeof(LNestedProjects)] = new(new WNestedProjects(sln.Result.SolutionFolders, projects))
[typeof(LNestedProjects)] = new(new WNestedProjects(sln.Result.SolutionFolders, projects)),
[typeof(LProjectConfigurationPlatforms)] = new(new WProjectConfigurationPlatforms(projectConfPlat)),
[typeof(LSolutionConfigurationPlatforms)] = new(new WSolutionConfigurationPlatforms(projectConfPlat)),
[typeof(LProjectSolutionItems)] = new(new WProjectSolutionItems(solutionFolders)),
};

using var w = new SlnWriter(outputSlnPath, handlers);
using (var w = new SlnWriter(outputSlnPath, handlers))
{
w.Options = SlnWriterOptions.CreateProjectsIfNotExist;
w.Write(sln.Result.Map);
}

w.Write(sln.Result.Map);
// Create the new project
CreateTestProject(projects, testProject, outputDir);
}

static bool IncludeProject(ProjectItem project, List<string> filters)
Expand All @@ -84,9 +115,53 @@ static bool IncludeProject(ProjectItem project, List<string> filters)
return true;
}

var found = filters.Exists(filter => project.name.Contains(filter, StringComparison.OrdinalIgnoreCase));

return found;
var positiveFilters = filters.FindAll(f => !f.StartsWith("!"));
var negativeFilters = filters.FindAll(f => f.StartsWith("!")).ConvertAll(f => f.TrimStart('!'));

var included = positiveFilters.Exists(filter => project.name.Contains(filter, StringComparison.OrdinalIgnoreCase));
var excluded = negativeFilters.Exists(filter => project.name.Contains(filter, StringComparison.OrdinalIgnoreCase));

return included && !excluded;
}

static void CreateTestProject(List<ProjectItem> projects, ProjectItem testProject, string outputDir)
{
var proj = new Project(NewProjectFileOptions.None);
proj.Xml.Sdk = "Microsoft.NET.Sdk";
var xp = new XProject(proj);

xp.SetProperties(new Dictionary<string, string>()
{
{ "OutputType", "Exe" },
{ "TargetFramework", "net9.0" },
{ "LangVersion", "latest" },
});

foreach (var project in projects.Where(p => p.pGuid != testProject.pGuid))
{
xp.AddProjectReference(project.fullPath, project.pGuid, project.name, false);
}

var program = """
using Audit.Core;
using System;
namespace Test2
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
""";
File.WriteAllText(Path.Combine(outputDir, "Program.cs"), program);

// Write the new project
xp.Save(testProject.fullPath, Encoding.UTF8);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"SolutionGenerator": {
"commandName": "Project",
"commandLineArgs": "\"D:\\MIOS\\Proyectos .NET\\Audit.NET\\Audit.NET.sln\" \"polly\" \"Audit.NET.modified.sln\""
"commandLineArgs": "\"D:\\MIOS\\Proyectos .NET\\Audit.NET\\Audit.NET.sln\" \"entityframework,!core\" \"C:\\Temp\\test1\\Test2.sln\""
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<ItemGroup>
<PackageReference Include="MvsSln" Version="2.7.0" />
<PackageReference Include="Microsoft.Build" Version="17.12.6" />
</ItemGroup>

</Project>

0 comments on commit 722412f

Please sign in to comment.