Skip to content

Commit

Permalink
Initial infrastructure for code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
credfeto committed Apr 27, 2024
1 parent 851531e commit 2071006
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/Credfeto.DotNet.Repo.Tools.CleanUp/CleanUpSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class CleanUpSetup
{
public static IServiceCollection AddCleanUp(this IServiceCollection services)
{
return services.AddSingleton<IBulkCodeCleanUp, BulkCodeCleanUp>();
return services.AddSingleton<IBulkCodeCleanUp, BulkCodeCleanUp>()
.AddSingleton<IProjectXmlRewriter, ProjectXmlRewriter>();
}
}
10 changes: 10 additions & 0 deletions src/Credfeto.DotNet.Repo.Tools.CleanUp/IProjectXmlRewriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Xml;

namespace Credfeto.DotNet.Repo.Tools.CleanUp;

public interface IProjectXmlRewriter
{
void ReOrderPropertyGroups(XmlDocument project, string filename);

void ReOrderIncludes(XmlDocument project);
}
15 changes: 13 additions & 2 deletions src/Credfeto.DotNet.Repo.Tools.CleanUp/Services/BulkCodeCleanUp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public sealed class BulkCodeCleanUp : IBulkCodeCleanUp
private readonly IGitRepositoryFactory _gitRepositoryFactory;
private readonly IGlobalJson _globalJson;
private readonly ILogger<BulkCodeCleanUp> _logger;
private readonly IProjectXmlRewriter _projectXmlRewriter;
private readonly IReleaseConfigLoader _releaseConfigLoader;
private readonly ITrackingCache _trackingCache;

Expand All @@ -35,13 +36,15 @@ public sealed class BulkCodeCleanUp : IBulkCodeCleanUp
IGlobalJson globalJson,
IDotNetVersion dotNetVersion,
IReleaseConfigLoader releaseConfigLoader,
IProjectXmlRewriter projectXmlRewriter,
ILogger<BulkCodeCleanUp> logger)
{
this._trackingCache = trackingCache;
this._gitRepositoryFactory = gitRepositoryFactory;
this._globalJson = globalJson;
this._dotNetVersion = dotNetVersion;
this._releaseConfigLoader = releaseConfigLoader;
this._projectXmlRewriter = projectXmlRewriter;
this._logger = logger;
}

Expand Down Expand Up @@ -206,15 +209,20 @@ private async ValueTask UpdateDotNetAsync(CleanupUpdateContext updateContext, Re
{
XmlDocument doc = await LoadProjectAsync(path: project, cancellationToken: cancellationToken);

// TODO:
// Project_cleanup (ordering)
this.ProjectCleanup(project: doc, projectFile: project);

await SaveProjectAsync(project: project, doc: doc, cancellationToken: cancellationToken);
}

throw new NotSupportedException("Not yet available");
}

private void ProjectCleanup(XmlDocument project, string projectFile)
{
this._projectXmlRewriter.ReOrderPropertyGroups(project: project, filename: projectFile);
this._projectXmlRewriter.ReOrderIncludes(project: project);
}

private static async ValueTask SaveProjectAsync(string project, XmlDocument doc, CancellationToken cancellationToken)
{
XmlWriterSettings settings = new() { Indent = true, IndentChars = " ", NewLineOnAttributes = false, OmitXmlDeclaration = true };
Expand All @@ -223,6 +231,9 @@ await using (XmlWriter xmlWriter = XmlWriter.Create(outputFileName: project, set
{
doc.Save(xmlWriter);
}

// TODO: Fix this.
await Task.Delay(millisecondsDelay: 1, cancellationToken: cancellationToken);
}

private static async ValueTask<XmlDocument> LoadProjectAsync(string path, CancellationToken cancellationToken)
Expand Down
180 changes: 180 additions & 0 deletions src/Credfeto.DotNet.Repo.Tools.CleanUp/Services/ProjectXmlRewriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Xml;

namespace Credfeto.DotNet.Repo.Tools.CleanUp.Services;

public sealed class ProjectXmlRewriter : IProjectXmlRewriter
{
[SuppressMessage(category: "Meziantou.Analyzer", checkId: "MA0051: Method is too long", Justification = "TODO just comments")]
public void ReOrderPropertyGroups(XmlDocument project, string filename)
{
/*
$toRemove = @()
$propertyGroups = $project.SelectNodes("PropertyGroup")
foreach($propertyGroup in $propertyGroups) {
$children = $propertyGroup.SelectNodes("*")
$attributes = [ordered]@{}
foreach($attribute in $propertyGroup.Attributes) {
$attValue = $propertyGroup.GetAttribute($attribute.Name)
$attributes[$attribute.Name] = $attValue
}
$orderedChildren = @{}
[bool]$replace = $true
foreach($child in $children) {
[string]$name = ($child.Name).ToString().ToUpper()
if($name -eq "#COMMENT") {
$replace = $false;
Log -message "$filename SKIPPING GROUP AS Found Comment"
Break
}
if($orderedChildren.Contains($name)) {
$replace = $false;
if($name -eq "DEFINECONSTANTS") {
# Skip DefineConstants as they can be added many times
Break
}
Log -message "$filename SKIPPING GROUP AS Found Duplicate item $name"
Break
}
$orderedChildren.Add($name, $child)
}
if($replace) {
if($orderedChildren) {
$propertyGroup.RemoveAll()
foreach($entryKey in $orderedChildren.Keys | Sort-Object -CaseSensitive) {
$item = $orderedChildren[$entryKey]
$propertyGroup.AppendChild($item)
}
foreach($attribute in $attributes.Keys) {
$propertyGroup.SetAttribute($attribute, $attributes[$attribute])
}
}
else {
$toRemove.Add($propertyGroup)
}
}
}
# remove any empty groups
foreach($item in $toRemove) {
[void]$project.RemoveChild($item)
}
*/

throw new NotSupportedException("Needs to be written");
}

[SuppressMessage(category: "Meziantou.Analyzer", checkId: "MA0051: Method is too long", Justification = "TODO just comments")]
public void ReOrderIncludes(XmlDocument project)
{
/*
$itemGroups = $project.SelectNodes("ItemGroup")
$normalItems = @{}
$privateItems = @{}
$projectItems = @{}
foreach($itemGroup in $itemGroups) {
if($itemGroup.HasAttributes) {
# Skip groups that have attributes
Continue
}
$toRemove = @()
# Extract Package References
$includes = $itemGroup.SelectNodes("PackageReference")
if($includes.Count -ne 0) {
foreach($include in $includes) {
[string]$packageId = $include.GetAttribute("Include")
[string]$private = $include.GetAttribute("PrivateAssets")
$toRemove += $include
if([string]::IsNullOrEmpty($private)) {
if(!$normalItems.Contains($packageId.ToUpper())) {
$normalItems.Add($packageId.ToUpper(), $include)
}
}
else {
if(!$privateItems.Contains($packageId.ToUpper())) {
$privateItems.Add($packageId.ToUpper(), $include)
}
}
}
}
# Extract Project References
$includes = $itemGroup.SelectNodes("ProjectReference")
if($includes.Count -ne 0) {
foreach($include in $includes) {
[string]$projectPath = $include.GetAttribute("Include")
$toRemove += $include
if(!$projectItems.Contains($projectPath.ToUpper())) {
$projectItems.Add($projectPath.ToUpper(), $include)
}
}
}
# Folder Includes
$includes = $itemGroup.SelectNodes("Folder")
if($includes.Count -ne 0) {
foreach($include in $includes) {
Log -message "* Found Folder to remove $( $include.Include )"
$toRemove += $include
}
}
# Remove items marked for deletion
foreach($include in $toRemove) {
[void]$itemGroup.RemoveChild($include)
}
# Remove Empty item Groups
if($itemGroup.ChildNodes.Count -eq 0) {
[void]$project.RemoveChild($itemGroup)
}
}
# Write References to projects
if($projectItems.Count -ne 0) {
$itemGroup = $data.CreateElement("ItemGroup")
foreach($includeKey in $projectItems.Keys | Sort-Object -CaseSensitive ) {
$include = $projectItems[$includeKey]
$itemGroup.AppendChild($include)
}
$project.AppendChild($itemGroup)
}
# Write References that are not dev only dependencies
if($normalItems.Count -ne 0) {
$itemGroup = $data.CreateElement("ItemGroup")
foreach($includeKey in $normalItems.Keys | Sort-Object -CaseSensitive ) {
$include = $normalItems[$includeKey]
$itemGroup.AppendChild($include)
}
$project.AppendChild($itemGroup)
}
# Write References that are dev only dependencies
if($privateItems.Count -ne 0) {
$itemGroup = $data.CreateElement("ItemGroup")
foreach($includeKey in $privateItems.Keys | Sort-Object -CaseSensitive ) {
$include = $privateItems[$includeKey]
$itemGroup.AppendChild($include)
}
$project.AppendChild($itemGroup)
}
*/
throw new NotSupportedException("Needs to be written");
}
}

0 comments on commit 2071006

Please sign in to comment.