Here is a Linqpad file. You specify the root directory name and it will generate a directory structure with a solution file in the root directory. Under the root directory are 2 project directories, one a c# library project and the other is an NUnit test project for testing the library. The root directory is created in the Temp directory.
async void Main()
{
IFileSystem fileSystem = new FileSystem();
string linqPadFile = "";
string projectName = "YYY";
var testDirPath = Path.Combine(Path.GetTempPath(), projectName);
var rootDir = fileSystem.Directory.CreateDirectory(testDirPath);
Debug.Assert(rootDir.Exists, $"Directory {rootDir.FullName} not found.");
var projFileCreator = new CSharpProjectFileCreator(fileSystem);
var response = projFileCreator.Create(new CreateProjectRequest(rootDir.CreateSubdirectory($"{projectName}"), $"{projectName}.csproj",
["Microsoft.Extensions.Logging", "System.IO.Abstractions", "Microsoft.Extensions.DependencyInjection"], $"{projectName}.cs", internalsVisibleTo: $"{projectName}.NUnit"));
var response2 = projFileCreator.Create(new CreateProjectRequest(rootDir.CreateSubdirectory($"{projectName}.NUnit"), $"{projectName}.NUnit.csproj",
["NUnit", "NUnit3TestAdapter", "Microsoft.NET.Test.Sdk", "System.IO.Abstractions", "System.IO.Abstractions.TestingHelpers", "coverlet.collector"],
$"{projectName}.NUnit.cs", NUnitSamples.NUnitSampleTest));
projFileCreator.CreateSolutionFile(testDirPath, projectName);
// Output
//Console.WriteLine($"Project File Name: {projectFileName}");
//Console.WriteLine("");
//Console.WriteLine("--- Project Contents ---");
//Console.WriteLine(projectFileContents);
}
public record CreateProjectRequest(IDirectoryInfo TargetDir, string ProjectFileName, string[] NugetReferences, string ContentFileName = "", string Content = "", string internalsVisibleTo = "");
public record CreateProjectResponse(bool Successful, string msg = "");
public class CSharpProjectFileCreator
{
private readonly IFileSystem _fileSystem;
public CSharpProjectFileCreator(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
public CreateProjectResponse Create(CreateProjectRequest request)
{
bool fullySuccessful = false;
if (!request.TargetDir.Exists)
{
return new CreateProjectResponse(false, $"Directory {request.TargetDir.FullName} not found.");
}
var projectFilePath = Path.Combine(request.TargetDir.FullName, request.ProjectFileName);
var projectFi = _fileSystem.FileInfo.New(projectFilePath);
var successful = GenerateProjectFile(projectFi.FullName, request.NugetReferences, request.internalsVisibleTo);
if (!successful)
{
return new CreateProjectResponse(false, $"Project file {projectFi.FullName} not created.");
}
var contentFilePath = Path.Combine(request.TargetDir.FullName, request.ContentFileName);
var contentFi = _fileSystem.FileInfo.New(contentFilePath);
successful = CreateFile(contentFi.FullName, request.Content);
if (!successful)
{
return new CreateProjectResponse(false, $"Project file {projectFi.FullName} created, but not the content file {contentFi.FullName} .");
}
return new CreateProjectResponse(fullySuccessful, $"Project file {projectFi.FullName} and Content file {contentFi.FullName} were created");
}
private bool GenerateProjectFile(string projectFullName, string[] nugetReferences, string internalsVisibleTo = "")
{
string packageReferences = "";
if (nugetReferences.Any())
{
packageReferences = string.Join(Environment.NewLine,
nugetReferences.Select(x => $" <PackageReference Include=\"{x}\" Version=\"*\" />"));
}
var projectContent = projectTemplate.Replace("{packageReferences}", packageReferences);
string internalsVisibleToSection = "";
if (internalsVisibleTo.Length > 0)
{
internalsVisibleToSection = internalsVisibleTemplate.Replace("{internalsVisibleTo}", internalsVisibleTo);
}
projectContent = projectContent.Replace("{internalsVisibleToSection}", internalsVisibleToSection);
//_fileSystem.File.WriteAllText(projectFullName, projContent);
return CreateFile(projectFullName, projectContent); //_fileSystem.File.Exists(projectFullName);
}
private bool CreateFile(string fileFullName, string content)
{
_fileSystem.File.WriteAllText(fileFullName, content);
return _fileSystem.File.Exists(fileFullName);
}
public bool CreateSolutionFile(string rootDirectoryPath, string projectName)
{
var solnFilePath = Path.Combine(rootDirectoryPath, projectName + ".slnx");
bool successful = CreateFile(solnFilePath, projectSolutionTemplate.Replace("{projectName}", projectName));
return successful;
}
private static string projectTemplate =
"""
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Project references go here-->
<ItemGroup>
{packageReferences}
</ItemGroup>
{internalsVisibleToSection}
</Project>
""";
private static string projectSolutionTemplate =
"""
<Solution>
<Configurations>
<Platform Name="Any CPU" />
</Configurations>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
</Folder>
<Project Path="{projectName}/{projectName}.csproj" />
<Project Path="{projectName}.NUnit/{projectName}.NUnit.csproj" />
</Solution>
""";
private static string internalsVisibleTemplate =
"""
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>{internalsVisibleTo}</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
""";
}
public class NUnitSamples
{
public static readonly string NUnitSampleTest = // See https://rbovill.blogspot.com/2006/01/using-nunit.html
"""
// See https://rbovill.blogspot.com/2006/01/using-nunit.html
using NUnit.Framework;
[TestFixture]
public class SomeTester
{
// Format of a Test method, Try to put all the setup for the test in the test.
// If necessary add private Setup/Initialise/Teardown methods to assist this
// rather than using the one listed above
[Test]
public void SomeTest1()
{
}
// You can add test parameters to a test and use it to test multiple cases
[Test]
[TestCase(5.0d, 0.0d, 3.0d)]
[TestCase(5.0d, 1.0d, 3.0d)]
[TestCase(5.0d, 0.0d, 5.0d)]
public void SomeTest2(double fullLengthSecs, double startTimeSecs, int expectedValue)
{
}
}
""";
}
No comments:
Post a Comment