Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Directory.Build.targets parsing and getting Target nodes #35

Merged
merged 3 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions Sources/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="codeessentials.Extensions.Logging.Demystifier" Version="1.1.66" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
<PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.88" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.91" />
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
<PackageVersion Include="Kysect.CommonLib" Version="0.1.18" />
<PackageVersion Include="Kysect.CommonLib.DependencyInjection" Version="0.1.18" />
<PackageVersion Include="Kysect.CommonLib" Version="0.1.21" />
<PackageVersion Include="Kysect.CommonLib.DependencyInjection" Version="0.1.21" />
<PackageVersion Include="Kysect.CommonLib.Testing" Version="0.1.21" />
<PackageVersion Include="Kysect.DotnetSlnGenerator" Version="0.1.6" />
<PackageVersion Include="Kysect.Editorconfig" Version="1.1.8" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
Expand All @@ -28,15 +29,15 @@
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="Markdig" Version="0.33.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="NUnit" Version="4.0.1" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageVersion Include="NUnit.Analyzers" Version="3.10.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="System.IO.Abstractions" Version="20.0.4" />
<PackageVersion Include="TestableIO.System.IO.Abstractions" Version="20.0.4" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="20.0.15" />
<PackageVersion Include="xunit" Version="2.6.6" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="21.0.2" />
<PackageVersion Include="xunit" Version="2.8.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
</PackageReference>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Kysect.CommonLib.DependencyInjection" />
<PackageReference Include="Kysect.CommonLib.Testing" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Kysect.DotnetProjectSystem.Projects;
using Microsoft.Language.Xml;

namespace Kysect.DotnetProjectSystem.Tests.Projects;

public class DirectoryBuildTargetFileTests
{
[Fact]
public void Create_FileWithTarget_ReturnFileWithTarget()
{
var content = """
<Project>
<Target Name="SomeTargetName" BeforeTargets="BeforeBuild">
<PropertyGroup Condition="'$(SomeProperty)' == 'true'">
<SomeProperty>false</SomeProperty>
</PropertyGroup>
</Target>
</Project>
""";

var dotnetBuildTargetFile = DirectoryBuildTargetFile.Create(content);

IReadOnlyCollection<IXmlElementSyntax> targets = dotnetBuildTargetFile.GetTargets();

targets.Should().HaveCount(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,48 @@ public void Create_ForSolutionWithoutDirectoryFiles_DirectoryFileMustBeCreatedOn
.ToXmlString(_syntaxFormatter)
.Should().Be(directoryPackagesPropsContent);
}

[Fact]
public void Create_SolutionWithDirectoryBuildTargets_ReturnTargetFileContent()
{
string directoryBuildTargetContent = """
<Project>
<Target Name="SomeTargetName" BeforeTargets="BeforeBuild">
<PropertyGroup Condition="'$(SomeProperty)' == 'true'">
<SomeProperty>false</SomeProperty>
</PropertyGroup>
</Target>
</Project>
""";

_solutionFileStructureBuilderFactory.Create("Solution")
.AddDirectoryBuildTargets(directoryBuildTargetContent)
.Save(_currentPath);

DotnetSolutionModifier solutionModifier = _solutionModifierFactory.Create("Solution.sln");

solutionModifier
.GetOrCreateDirectoryBuildTargetFile()
.ToXmlString(_syntaxFormatter)
.Should().Be(directoryBuildTargetContent);
}

[Fact]
public void Create_SolutionWithoutDirectoryBuildTargets_ReturnEmptyTargetFileContent()
{
string directoryBuildTargetContent = """
<Project>
</Project>
""";

_solutionFileStructureBuilderFactory.Create("Solution")
.Save(_currentPath);

DotnetSolutionModifier solutionModifier = _solutionModifierFactory.Create("Solution.sln");

solutionModifier
.GetOrCreateDirectoryBuildTargetFile()
.ToXmlString(_syntaxFormatter)
.Should().Be(directoryBuildTargetContent);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Kysect.DotnetProjectSystem.FileStructureBuilding;
using Kysect.DotnetProjectSystem.Parsing;
using Kysect.DotnetProjectSystem.Projects;
using Kysect.DotnetProjectSystem.SolutionModification;
using Kysect.DotnetProjectSystem.Tests.Asserts;
using Kysect.DotnetProjectSystem.Tools;
using Kysect.DotnetProjectSystem.Xml;
using Microsoft.Language.Xml;
using System.IO.Abstractions.TestingHelpers;

namespace Kysect.DotnetProjectSystem.Tests.SolutionModification;
Expand Down Expand Up @@ -83,4 +85,31 @@ public void Save_AfterAddingValueToDirectoryBuildProps_FileSaved()
.ShouldExists()
.ShouldHaveContent(expectedContent);
}

[Fact]
public void Save_AfterModifyDirectoryBuildTargets_FileSaved()
{
var expectedContent = """
<Project>
<NewNode></NewNode>
</Project>
""";

_solutionFileStructureBuilderFactory.Create("Solution")
.AddDirectoryBuildTargets(DirectoryBuildTargetFile.CreateEmpty())
.Save(_currentPath);

DotnetSolutionModifier solutionModifier = _solutionModifierFactory.Create("Solution.sln");
solutionModifier
.GetOrCreateDirectoryBuildTargetFile()
.UpdateDocument(d => d.ReplaceNode(
d.Root.AsSyntaxElement.AsNode,
d.Root.AsSyntaxElement.AddChild(ExtendedSyntaxFactory.XmlElement("NewNode")).AsNode));
solutionModifier.Save();

_fileSystemAsserts
.File(SolutionItemNameConstants.DirectoryBuildTargets)
.ShouldExists()
.ShouldHaveContent(expectedContent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class SolutionFileStructureBuilder
private readonly List<SolutionStructureElement> _files;
private DirectoryBuildPropsFile? _directoryBuildPropsFile;
private DirectoryPackagesPropsFile? _directoryPackagesPropsFile;
private DirectoryBuildTargetFile? _directoryBuildTargetFile;

public SolutionFileStructureBuilder(IFileSystem fileSystem, XmlDocumentSyntaxFormatter syntaxFormatter, string solutionName)
{
Expand Down Expand Up @@ -66,11 +67,22 @@ public SolutionFileStructureBuilder AddDirectoryPackagesProps(DirectoryPackagesP
return this;
}

public SolutionFileStructureBuilder AddDirectoryBuildTargets(string content)
{
return AddDirectoryBuildTargets(DirectoryBuildTargetFile.Create(content));
}

public SolutionFileStructureBuilder AddDirectoryBuildTargets(DirectoryBuildTargetFile directoryBuildTargetFile)
{
_directoryBuildTargetFile = directoryBuildTargetFile;
return this;
}

public void Save(string solutionDirectory)
{
string solutionFileContent = CreateSolutionFile(_fileSystem);

DirectoryExtensions.EnsureDirectoryExists(_fileSystem, solutionDirectory);
_fileSystem.EnsureDirectoryExists(solutionDirectory);
_fileSystem.File.WriteAllText(_fileSystem.Path.Combine(solutionDirectory, $"{_solutionName}.sln"), solutionFileContent);

if (_directoryBuildPropsFile is not null)
Expand All @@ -79,6 +91,9 @@ public void Save(string solutionDirectory)
if (_directoryPackagesPropsFile is not null)
AddFile([SolutionItemNameConstants.DirectoryPackagesProps], _directoryPackagesPropsFile.File.ToXmlString(_syntaxFormatter));

if (_directoryBuildTargetFile is not null)
AddFile([SolutionItemNameConstants.DirectoryBuildTargets], _directoryBuildTargetFile.ToXmlString(_syntaxFormatter));

foreach (SolutionStructureElement? solutionFileInfo in _files)
{
string partialFilePath = _fileSystem.Path.Combine(solutionFileInfo.Path.ToArray());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Kysect.CommonLib.BaseTypes.Extensions;
using Kysect.DotnetProjectSystem.Xml;
using Microsoft.Language.Xml;

namespace Kysect.DotnetProjectSystem.Projects;

public class DirectoryBuildTargetFile
{
private XmlDocumentSyntax _content;

public static DirectoryBuildTargetFile CreateEmpty()
{
string contentTemplate =
"""
<Project>
</Project>
""";

return Create(contentTemplate);
}

public static DirectoryBuildTargetFile Create(string content)
{
XmlDocumentSyntax xmlDocumentSyntax = Parser.ParseText(content);
if (xmlDocumentSyntax.RootSyntax is null)
return CreateEmpty();

return new DirectoryBuildTargetFile(xmlDocumentSyntax);
}

public DirectoryBuildTargetFile(XmlDocumentSyntax content)
{
_content = content;
}

public IReadOnlyCollection<IXmlElementSyntax> GetTargets()
{
return GetNodesByName("Target");
}

public IReadOnlyCollection<IXmlElementSyntax> GetNodesByName(string name)
{
return _content.GetNodesByName(name);
}

public void UpdateDocument(Func<XmlDocumentSyntax, XmlDocumentSyntax> morphism)
{
morphism.ThrowIfNull();
_content = morphism(_content);
}

public string ToXmlString(XmlDocumentSyntaxFormatter formatter)
{
formatter.ThrowIfNull();

return formatter.Format(_content).ToFullString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class DotnetSolutionModifier
private readonly IFileSystem _fileSystem;
private DirectoryBuildPropsFile? _directoryBuildPropsModifier;
private DirectoryPackagesPropsFile? _directoryPackagePropsModifier;
private DirectoryBuildTargetFile? _directoryBuildTargetFile;
private readonly Dictionary<string, DotnetCsprojFile> _projects;

public IReadOnlyCollection<KeyValuePair<string, DotnetCsprojFile>> Projects => _projects;
Expand All @@ -29,17 +30,25 @@ public DirectoryPackagesPropsFile GetOrCreateDirectoryPackagePropsModifier()
return _directoryPackagePropsModifier;
}

public DirectoryBuildTargetFile GetOrCreateDirectoryBuildTargetFile()
{
_directoryBuildTargetFile ??= DirectoryBuildTargetFile.CreateEmpty();
return _directoryBuildTargetFile;
}

public DotnetSolutionModifier(
Dictionary<string, DotnetCsprojFile> projects,
DirectoryBuildPropsFile? directoryBuildPropsModifier,
DirectoryPackagesPropsFile? directoryPackagePropsModifier,
DirectoryBuildTargetFile? directoryBuildTargetsFile,
IFileSystem fileSystem,
IFileInfo solutionPath,
XmlDocumentSyntaxFormatter syntaxFormatter)
{
_projects = projects;
_directoryBuildPropsModifier = directoryBuildPropsModifier;
_directoryPackagePropsModifier = directoryPackagePropsModifier;
_directoryBuildTargetFile = directoryBuildTargetsFile;
_fileSystem = fileSystem;
_solutionPath = solutionPath;
_syntaxFormatter = syntaxFormatter;
Expand All @@ -61,6 +70,12 @@ public void Save()
_fileSystem.File.WriteAllText(directoryPackagesPropsPath, _directoryPackagePropsModifier.File.ToXmlString(_syntaxFormatter));
}

if (_directoryBuildTargetFile is not null)
{
string directoryPackagesPropsPath = _fileSystem.Path.Combine(_solutionPath.Directory.FullName, SolutionItemNameConstants.DirectoryBuildTargets);
_fileSystem.File.WriteAllText(directoryPackagesPropsPath, _directoryBuildTargetFile.ToXmlString(_syntaxFormatter));
}

foreach (KeyValuePair<string, DotnetCsprojFile> projectModifier in _projects)
{
_fileSystem.File.WriteAllText(projectModifier.Key, projectModifier.Value.File.ToXmlString(_syntaxFormatter));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ public DotnetSolutionModifier Create(string solutionPath)

DirectoryBuildPropsFile? directoryBuildPropsModifier = TryCreateDirectoryBuildPropsFile(solutionFileInfo);
DirectoryPackagesPropsFile? directoryPackagesPropsFile = TryCreateDirectoryPackagesPropsFile(solutionFileInfo);
DirectoryBuildTargetFile? directoryBuildTargetsFile = TryCreateDirectoryBuildTargetsFile(solutionFileInfo);
Dictionary<string, DotnetCsprojFile> projects = CreateProjectModifiers(solutionFileInfo);

return new DotnetSolutionModifier(
projects,
directoryBuildPropsModifier,
directoryPackagesPropsFile,
directoryBuildTargetsFile,
_fileSystem,
solutionFileInfo,
_syntaxFormatter);
Expand Down Expand Up @@ -63,6 +65,22 @@ public DotnetSolutionModifier Create(string solutionPath)
return new DirectoryPackagesPropsFile(dotnetProjectFile);
}

private DirectoryBuildTargetFile? TryCreateDirectoryBuildTargetsFile(IFileInfo solutionFileInfo)
{
solutionFileInfo.Directory.ThrowIfNull();

string path = _fileSystem.Path.Combine(solutionFileInfo.Directory.FullName, SolutionItemNameConstants.DirectoryBuildTargets);
if (!_fileSystem.File.Exists(path))
return null;

string fileContent =
_fileSystem.File.Exists(path)
? _fileSystem.File.ReadAllText(path)
: string.Empty;

return DirectoryBuildTargetFile.Create(fileContent);
}

private Dictionary<string, DotnetCsprojFile> CreateProjectModifiers(IFileInfo solutionFileInfo)
{
solutionFileInfo.Directory.ThrowIfNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public static class SolutionItemNameConstants
{
public const string DirectoryBuildProps = "Directory.Build.props";
public const string DirectoryPackagesProps = "Directory.Packages.props";
public const string DirectoryBuildTargets = "Directory.Build.targets";
}

This file was deleted.

Loading