create helper classes

This commit is contained in:
Matthew Parker [SSW]
2024-01-21 14:59:19 +10:00
parent 3f5905349d
commit 22af01dc48
16 changed files with 225 additions and 215 deletions

View File

@@ -1,5 +1,4 @@
using System; using Avalonia;
using Avalonia;
namespace DotNetSolutionTools.App; namespace DotNetSolutionTools.App;

View File

@@ -5,6 +5,7 @@ using CommunityToolkit.Mvvm.Input;
using DotNetSolutionTools.App.Models; using DotNetSolutionTools.App.Models;
using DotNetSolutionTools.App.Services; using DotNetSolutionTools.App.Services;
using DotNetSolutionTools.Core; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core.Common;
namespace DotNetSolutionTools.App.ViewModels; namespace DotNetSolutionTools.App.ViewModels;
@@ -35,13 +36,19 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
var results = SolutionProjectParity.CompareSolutionAndCSharpProjects(SolutionFolderPath, SolutionFilePath); {
foreach (var result in results) var results = SolutionProjectParity.CompareSolutionAndCSharpProjects(
OperationResults.Add(result); SolutionFolderPath,
ResultsLabel = $"{results.Count} Projects in folder missing from solution"; SolutionFilePath
}, token); );
foreach (var result in results)
OperationResults.Add(result);
ResultsLabel = $"{results.Count} Projects in folder missing from solution";
},
token
);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -59,10 +66,13 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
FormatCsproj.FormatCsprojFile(CsprojFilePath); {
}, token); FormatCsproj.FormatCsprojFile(CsprojFilePath);
},
token
);
ResultsLabel = "Successfully formatted csproj file"; ResultsLabel = "Successfully formatted csproj file";
} }
catch (Exception e) catch (Exception e)
@@ -71,7 +81,6 @@ public partial class MainWindowViewModel : ViewModelBase
OperationResults?.Add(e.Message); OperationResults?.Add(e.Message);
OperationResults?.Add(e.ToString()); OperationResults?.Add(e.ToString());
} }
} }
[RelayCommand] [RelayCommand]
@@ -82,15 +91,18 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(SolutionFilePath);
var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromSolution(solutionFile);
foreach (var csproj in csprojList)
{ {
FormatCsproj.FormatCsprojFile(csproj); var solutionFile = SlnHelper.ParseSolutionFileFromPath(SolutionFilePath);
} var csprojList = CsprojHelper.RetrieveAllCSharpProjectFullPathsFromSolution(solutionFile);
}, token); foreach (var csproj in csprojList)
{
FormatCsproj.FormatCsprojFile(csproj);
}
},
token
);
ResultsLabel = "Successfully formatted all csproj files in solution file"; ResultsLabel = "Successfully formatted all csproj files in solution file";
} }
catch (Exception e) catch (Exception e)
@@ -108,14 +120,17 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromFolder(SolutionFolderPath);
foreach (var csproj in csprojList)
{ {
FormatCsproj.FormatCsprojFile(csproj); var csprojList = CsprojHelper.RetrieveAllCSharpProjectFullPathsFromFolder(SolutionFolderPath);
} foreach (var csproj in csprojList)
}, token); {
FormatCsproj.FormatCsprojFile(csproj);
}
},
token
);
ResultsLabel = "Successfully formatted all csproj files in folder"; ResultsLabel = "Successfully formatted all csproj files in folder";
} }
catch (Exception e) catch (Exception e)
@@ -134,12 +149,15 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
var results = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(SolutionFilePath); {
results.ForEach(s => OperationResults.Add(s)); var results = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(SolutionFilePath);
ResultsLabel = $"{results.Count} Projects missing ImplicitUsings"; results.ForEach(s => OperationResults.Add(s));
}, token); ResultsLabel = $"{results.Count} Projects missing ImplicitUsings";
},
token
);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -157,12 +175,15 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
var results = WarningsAsErrors.FindCSharpProjectsMissingTreatWarningsAsErrors(SolutionFilePath); {
results.ForEach(s => OperationResults.Add(s)); var results = WarningsAsErrors.FindCSharpProjectsMissingTreatWarningsAsErrors(SolutionFilePath);
ResultsLabel = $"{results.Count} Projects missing TreatWarningsAsErrors"; results.ForEach(s => OperationResults.Add(s));
}, token); ResultsLabel = $"{results.Count} Projects missing TreatWarningsAsErrors";
},
token
);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -180,10 +201,13 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(() => await Task.Run(
{ () =>
CleanFolder.DeleteBinObjAndNodeModulesFoldersInFolder(SolutionFolderPath); {
}, token); CleanFolder.DeleteBinObjAndNodeModulesFoldersInFolder(SolutionFolderPath);
},
token
);
ResultsLabel = "Successfully deleted bin and obj folders"; ResultsLabel = "Successfully deleted bin and obj folders";
} }
catch (Exception e) catch (Exception e)
@@ -191,7 +215,6 @@ public partial class MainWindowViewModel : ViewModelBase
ResultsLabel = "Failed to delete bin and obj folders"; ResultsLabel = "Failed to delete bin and obj folders";
OperationResults?.Add(e.Message); OperationResults?.Add(e.Message);
OperationResults?.Add(e.ToString()); OperationResults?.Add(e.ToString());
} }
} }
@@ -203,10 +226,13 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(async () => await Task.Run(
{ async () =>
await DotNetUpgrade.UpdateProjectsInSolutionToNet80(SolutionFilePath); {
}, token); await DotNetUpgrade.UpdateProjectsInSolutionToNet80(SolutionFilePath);
},
token
);
ResultsLabel = "Successfully updated all projects in solution to .NET 8"; ResultsLabel = "Successfully updated all projects in solution to .NET 8";
} }
catch (Exception e) catch (Exception e)
@@ -225,10 +251,13 @@ public partial class MainWindowViewModel : ViewModelBase
try try
{ {
ResultsLabel = "Running..."; ResultsLabel = "Running...";
await Task.Run(async () => await Task.Run(
{ async () =>
await DotNetUpgrade.UpdateProjectAtPathToNet80(CsprojFilePath); {
}, token); await DotNetUpgrade.UpdateProjectAtPathToNet80(CsprojFilePath);
},
token
);
ResultsLabel = "Successfully updated project to .NET 8"; ResultsLabel = "Successfully updated project to .NET 8";
} }
catch (Exception e) catch (Exception e)

View File

@@ -1,5 +1,4 @@
using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
namespace DotNetSolutionTools.App.ViewModels; namespace DotNetSolutionTools.App.ViewModels;

View File

@@ -1,5 +1,4 @@
using System.ComponentModel; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands; namespace DotNetSolutionTools.CLI.Commands;

View File

@@ -1,5 +1,6 @@
using System.ComponentModel; using System.ComponentModel;
using DotNetSolutionTools.Core; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core.Common;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands; namespace DotNetSolutionTools.CLI.Commands;
@@ -15,9 +16,7 @@ public class CompareCommand : Command<CompareCommand.Settings>
public required string SolutionFilePath { get; set; } public required string SolutionFilePath { get; set; }
[CommandOption("-l|--logprojectfiles")] [CommandOption("-l|--logprojectfiles")]
[Description( [Description("true to enable log output of all project files found in folder. Default is false.")]
"true to enable log output of all project files found in folder. Default is false."
)]
[DefaultValue(false)] [DefaultValue(false)]
public bool LogAllProjectFileNames { get; set; } = false; public bool LogAllProjectFileNames { get; set; } = false;
} }
@@ -28,9 +27,7 @@ public class CompareCommand : Command<CompareCommand.Settings>
var pathToSolutionFile = settings.SolutionFilePath; var pathToSolutionFile = settings.SolutionFilePath;
Console.WriteLine($"Retrieving C# Projects from {folderDirectory}"); Console.WriteLine($"Retrieving C# Projects from {folderDirectory}");
var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectNamesFromFolder( var csprojList = CsprojHelper.RetrieveAllCSharpProjectFullPathsFromFolder(folderDirectory);
folderDirectory
);
if (settings.LogAllProjectFileNames) if (settings.LogAllProjectFileNames)
{ {
@@ -45,12 +42,10 @@ public class CompareCommand : Command<CompareCommand.Settings>
Console.WriteLine($"Parsing Solution File: {pathToSolutionFile}"); Console.WriteLine($"Parsing Solution File: {pathToSolutionFile}");
// Load the solution file // Load the solution file
var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(pathToSolutionFile); var solutionFile = SlnHelper.ParseSolutionFileFromPath(pathToSolutionFile);
if (solutionFile == null) if (solutionFile == null)
{ {
Console.WriteLine( Console.WriteLine("Failed to parse solution file. The file was either not found or malformed.");
"Failed to parse solution file. The file was either not found or malformed."
);
return 1; return 1;
} }
@@ -61,9 +56,7 @@ public class CompareCommand : Command<CompareCommand.Settings>
); );
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
Console.WriteLine( Console.WriteLine($"Missing {projectsMissingFromSolution.Count} C# Projects from Solution File");
$"Missing {projectsMissingFromSolution.Count} C# Projects from Solution File"
);
foreach (var project in projectsMissingFromSolution) foreach (var project in projectsMissingFromSolution)
{ {

View File

@@ -1,4 +1,5 @@
using DotNetSolutionTools.Core; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core.Common;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands; namespace DotNetSolutionTools.CLI.Commands;
@@ -29,17 +30,13 @@ public class FormatCsprojCommand : Command<FormatCsprojCommand.Settings>
} }
else if (!string.IsNullOrWhiteSpace(settings.SolutionFilePath)) else if (!string.IsNullOrWhiteSpace(settings.SolutionFilePath))
{ {
var test = SolutionProjectParity.ParseSolutionFileFromPath(settings.SolutionFilePath); var test = SlnHelper.ParseSolutionFileFromPath(settings.SolutionFilePath);
if (test == null) if (test == null)
{ {
Console.WriteLine( Console.WriteLine("Failed to parse solution file. The file was either not found or malformed.");
"Failed to parse solution file. The file was either not found or malformed."
);
return 1; return 1;
} }
var cSharpProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile( var cSharpProjects = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(test);
test
);
Console.WriteLine($"Found {cSharpProjects.Count} C# Projects"); Console.WriteLine($"Found {cSharpProjects.Count} C# Projects");
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
foreach (var project in cSharpProjects) foreach (var project in cSharpProjects)
@@ -54,9 +51,7 @@ public class FormatCsprojCommand : Command<FormatCsprojCommand.Settings>
var folderDirectory = settings.SolutionFolderPath; // Include the trailing slash var folderDirectory = settings.SolutionFolderPath; // Include the trailing slash
Console.WriteLine($"Retrieving C# Projects from {folderDirectory}"); Console.WriteLine($"Retrieving C# Projects from {folderDirectory}");
var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromFolder( var csprojList = CsprojHelper.RetrieveAllCSharpProjectFullPathsFromFolder(folderDirectory);
folderDirectory
);
Console.WriteLine($"Retrieved {csprojList.Length} C# Projects"); Console.WriteLine($"Retrieved {csprojList.Length} C# Projects");
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
@@ -70,9 +65,7 @@ public class FormatCsprojCommand : Command<FormatCsprojCommand.Settings>
} }
else else
{ {
Console.WriteLine( Console.WriteLine("No arguments were provided. Please provide a csproj, folder, or solution file.");
"No arguments were provided. Please provide a csproj, folder, or solution file."
);
return 1; return 1;
} }
} }

View File

@@ -1,5 +1,6 @@
using System.ComponentModel; using System.ComponentModel;
using DotNetSolutionTools.Core; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core.Common;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands; namespace DotNetSolutionTools.CLI.Commands;
@@ -17,9 +18,7 @@ public class ImplicitUsingsCommand : Command<ImplicitUsingsCommand.Settings>
public bool AddMissing { get; set; } = false; public bool AddMissing { get; set; } = false;
[CommandOption("-d|--enable-disabled")] [CommandOption("-d|--enable-disabled")]
[Description( [Description("Sets Implicit Usings to true for any projects with it disabled. Default is false.")]
"Sets Implicit Usings to true for any projects with it disabled. Default is false."
)]
[DefaultValue(false)] [DefaultValue(false)]
public bool EnableDisabled { get; set; } = false; public bool EnableDisabled { get; set; } = false;
@@ -34,24 +33,18 @@ public class ImplicitUsingsCommand : Command<ImplicitUsingsCommand.Settings>
var pathToSolutionFile = settings.SolutionFilePath; var pathToSolutionFile = settings.SolutionFilePath;
Console.WriteLine($"Retrieving Solution from {pathToSolutionFile}"); Console.WriteLine($"Retrieving Solution from {pathToSolutionFile}");
var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(pathToSolutionFile); var solutionFile = SlnHelper.ParseSolutionFileFromPath(pathToSolutionFile);
if (solutionFile == null) if (solutionFile == null)
{ {
Console.WriteLine( Console.WriteLine("Failed to parse solution file. The file was either not found or malformed.");
"Failed to parse solution file. The file was either not found or malformed."
);
return 1; return 1;
} }
var cSharpProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile( var cSharpProjects = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
solutionFile
);
Console.WriteLine($"Found {cSharpProjects.Count} C# Projects"); Console.WriteLine($"Found {cSharpProjects.Count} C# Projects");
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
// Get the list of projects // Get the list of projects
var projectsMissingImplicitUsings = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings( var projectsMissingImplicitUsings = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(cSharpProjects);
cSharpProjects
);
Console.WriteLine( Console.WriteLine(
$"{projectsMissingImplicitUsings.Count} C# Projects have missing or disabled implicit usings" $"{projectsMissingImplicitUsings.Count} C# Projects have missing or disabled implicit usings"
@@ -67,12 +60,8 @@ public class ImplicitUsingsCommand : Command<ImplicitUsingsCommand.Settings>
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
Console.WriteLine("Adding missing implicit usings"); Console.WriteLine("Adding missing implicit usings");
ImplicitUsings.AddMissingImplicitUsings(projectsMissingImplicitUsings); ImplicitUsings.AddMissingImplicitUsings(projectsMissingImplicitUsings);
var updatedProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile( var updatedProjects = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
solutionFile var projectsWithMissing = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(updatedProjects);
);
var projectsWithMissing = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(
updatedProjects
);
Console.WriteLine( Console.WriteLine(
$"There are now {projectsWithMissing.Count} C# Projects missing/disabled implicit usings" $"There are now {projectsWithMissing.Count} C# Projects missing/disabled implicit usings"
); );

View File

@@ -1,5 +1,6 @@
using System.ComponentModel; using System.ComponentModel;
using DotNetSolutionTools.Core; using DotNetSolutionTools.Core;
using DotNetSolutionTools.Core.Common;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands; namespace DotNetSolutionTools.CLI.Commands;
@@ -21,13 +22,13 @@ public class TreatWarningsAsErrorsCommand : Command<TreatWarningsAsErrorsCommand
var pathToSolutionFile = settings.SolutionFilePath; var pathToSolutionFile = settings.SolutionFilePath;
Console.WriteLine($"Retrieving Solution from {pathToSolutionFile}"); Console.WriteLine($"Retrieving Solution from {pathToSolutionFile}");
var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(pathToSolutionFile); var solutionFile = SlnHelper.ParseSolutionFileFromPath(pathToSolutionFile);
if (solutionFile == null) if (solutionFile == null)
{ {
Console.WriteLine("Failed to parse solution file. The file was either not found or malformed."); Console.WriteLine("Failed to parse solution file. The file was either not found or malformed.");
return 1; return 1;
} }
var cSharpProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var cSharpProjects = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
Console.WriteLine($"Found {cSharpProjects.Count} C# Projects"); Console.WriteLine($"Found {cSharpProjects.Count} C# Projects");
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
@@ -45,7 +46,7 @@ public class TreatWarningsAsErrorsCommand : Command<TreatWarningsAsErrorsCommand
Console.WriteLine("=================================================="); Console.WriteLine("==================================================");
Console.WriteLine("Adding missing Warnings As Errors"); Console.WriteLine("Adding missing Warnings As Errors");
WarningsAsErrors.AddMissingTreatWarningsAsErrors(projectsMissingTreatWarningsAsErrors); WarningsAsErrors.AddMissingTreatWarningsAsErrors(projectsMissingTreatWarningsAsErrors);
var updatedProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var updatedProjects = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
var projectsWithMissing = WarningsAsErrors.FindCSharpProjectsMissingTreatWarningsAsErrors(updatedProjects); var projectsWithMissing = WarningsAsErrors.FindCSharpProjectsMissingTreatWarningsAsErrors(updatedProjects);
Console.WriteLine( Console.WriteLine(
$"There are now {projectsWithMissing.Count} C# Projects missing Treat Warnings As Errors" $"There are now {projectsWithMissing.Count} C# Projects missing Treat Warnings As Errors"

View File

@@ -0,0 +1,29 @@
using DotNetSolutionTools.Core;
using Spectre.Console.Cli;
namespace DotNetSolutionTools.CLI.Commands;
public class UpdateProjectToNet80Command : Command<UpdateProjectToNet80Command.Settings>
{
public sealed class Settings : CommandSettings
{
[CommandArgument(1, "<CsprojFilePath>")]
public required string CsprojFilePath { get; set; }
}
public override int Execute(CommandContext context, Settings settings)
{
// validate a real folder path was passed in
if (!Directory.Exists(settings.CsprojFilePath))
{
Console.WriteLine("Invalid folder path");
return 1;
}
Console.WriteLine("Deleting bin, obj, and node_modules folders");
CleanFolder.DeleteBinObjAndNodeModulesFoldersInFolder(settings.CsprojFilePath);
Console.WriteLine("==================================================");
Console.WriteLine("Done!");
return 0;
}
}

View File

@@ -0,0 +1,24 @@
using Microsoft.Build.Construction;
namespace DotNetSolutionTools.Core.Common;
public static class CsprojHelper
{
public static string[] RetrieveAllCSharpProjectFullPathsFromFolder(string solutionFolderPath)
{
// if solutionFolderPath does not end with a slash, add one
if (solutionFolderPath[^1] != Path.DirectorySeparatorChar)
{
solutionFolderPath += Path.DirectorySeparatorChar;
}
var csprojList = Directory.GetFiles(solutionFolderPath, "*.csproj", SearchOption.AllDirectories);
return csprojList;
}
public static string[] RetrieveAllCSharpProjectFullPathsFromSolution(SolutionFile solution)
{
var result = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solution);
var csprojList = result.Select(x => x.FullPath).ToArray();
return csprojList;
}
}

View File

@@ -0,0 +1,23 @@
using Microsoft.Build.Construction;
namespace DotNetSolutionTools.Core.Common;
public static class SlnHelper
{
public static SolutionFile? ParseSolutionFileFromPath(string solutionFilePath)
{
var solutionFile = SolutionFile.Parse(solutionFilePath);
return solutionFile;
}
public static List<ProjectRootElement> GetCSharpProjectObjectsFromSolutionFile(SolutionFile solutionFile)
{
var projectList = solutionFile
.ProjectsByGuid.Where(x => x.Value.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
.Select(s => ProjectRootElement.Open(s.Value.AbsolutePath))
.ToList();
return projectList;
}
}

View File

@@ -1,4 +1,5 @@
using DotNetSolutionTools.Core.Infrastructure; using DotNetSolutionTools.Core.Common;
using DotNetSolutionTools.Core.Infrastructure;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.Build.Definition; using Microsoft.Build.Definition;
using Microsoft.Build.Evaluation; using Microsoft.Build.Evaluation;
@@ -11,7 +12,7 @@ public static class DotNetUpgrade
public static async Task UpdateProjectsInSolutionToNet80(string solutionFilePath) public static async Task UpdateProjectsInSolutionToNet80(string solutionFilePath)
{ {
var solutionFile = SolutionFile.Parse(solutionFilePath); var solutionFile = SolutionFile.Parse(solutionFilePath);
var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var csprojList = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
await UpdateProjectsToNet80(csprojList); await UpdateProjectsToNet80(csprojList);
} }
@@ -32,8 +33,7 @@ public static class DotNetUpgrade
private static async Task UpdateProjectToNet80(ProjectRootElement project) private static async Task UpdateProjectToNet80(ProjectRootElement project)
{ {
var targetFramework = project var targetFramework = project
.PropertyGroups .PropertyGroups.SelectMany(x => x.Properties)
.SelectMany(x => x.Properties)
.FirstOrDefault(x => x.Name == "TargetFramework"); .FirstOrDefault(x => x.Name == "TargetFramework");
if (targetFramework?.Value is "net8.0" or "net7.0" or "net6.0" or "net5.0") if (targetFramework?.Value is "net8.0" or "net7.0" or "net6.0" or "net5.0")
{ {
@@ -57,27 +57,20 @@ public static class DotNetUpgrade
new ProjectOptions() { LoadSettings = ProjectLoadSettings.IgnoreMissingImports } new ProjectOptions() { LoadSettings = ProjectLoadSettings.IgnoreMissingImports }
); );
var packages = evalProject var packages = evalProject
.Items .Items.Where(x =>
.Where( x.ItemType == "PackageReference"
x => && x.HasMetadata("Version")
x.ItemType == "PackageReference" && x.EvaluatedInclude.StartsWith("Microsoft.")
&& x.HasMetadata("Version")
&& x.EvaluatedInclude.StartsWith("Microsoft.")
) )
.ToList(); .ToList();
var packageNameAndVersion = packages var packageNameAndVersion = packages
.Select( .Select(x => new
x => {
new Package = x,
{ Name = x.EvaluatedInclude,
Package = x, NugetVersion = NuGetVersion.Parse(x.Metadata.First(s => s.Name == "Version").UnevaluatedValue)
Name = x.EvaluatedInclude, })
NugetVersion = NuGetVersion.Parse(
x.Metadata.First(s => s.Name == "Version").UnevaluatedValue
)
}
)
.ToList(); .ToList();
var shouldSave = false; var shouldSave = false;

View File

@@ -1,4 +1,5 @@
using Microsoft.Build.Construction; using DotNetSolutionTools.Core.Common;
using Microsoft.Build.Construction;
namespace DotNetSolutionTools.Core; namespace DotNetSolutionTools.Core;
@@ -7,27 +8,21 @@ public static class ImplicitUsings
public static List<string> FindCSharpProjectsMissingImplicitUsings(string solutionFilePath) public static List<string> FindCSharpProjectsMissingImplicitUsings(string solutionFilePath)
{ {
var solutionFile = SolutionFile.Parse(solutionFilePath); var solutionFile = SolutionFile.Parse(solutionFilePath);
var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile( var csprojList = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
solutionFile
);
var projectsMissingImplicitUsings = FindCSharpProjectsMissingImplicitUsings(csprojList); var projectsMissingImplicitUsings = FindCSharpProjectsMissingImplicitUsings(csprojList);
var projectsMissingImplicitUsingsStringList = projectsMissingImplicitUsings var projectsMissingImplicitUsingsStringList = projectsMissingImplicitUsings.Select(x => x.FullPath).ToList();
.Select(x => x.FullPath)
.ToList();
return projectsMissingImplicitUsingsStringList; return projectsMissingImplicitUsingsStringList;
} }
public static List<ProjectRootElement> FindCSharpProjectsMissingImplicitUsings( public static List<ProjectRootElement> FindCSharpProjectsMissingImplicitUsings(List<ProjectRootElement> projectList)
List<ProjectRootElement> projectList
)
{ {
var projectsMissingImplicitUsings = new List<ProjectRootElement>(); var projectsMissingImplicitUsings = new List<ProjectRootElement>();
foreach (var project in projectList) foreach (var project in projectList)
{ {
var implicitUsings = project.PropertyGroups var implicitUsings = project
.SelectMany(x => x.Properties) .PropertyGroups.SelectMany(x => x.Properties)
.FirstOrDefault(x => x.Name == "ImplicitUsings"); .FirstOrDefault(x => x.Name == "ImplicitUsings");
if (implicitUsings is null || implicitUsings.Value is not "enable") if (implicitUsings is null || implicitUsings.Value is not "enable")
{ {
@@ -38,9 +33,7 @@ public static class ImplicitUsings
return projectsMissingImplicitUsings; return projectsMissingImplicitUsings;
} }
public static void AddMissingImplicitUsings( public static void AddMissingImplicitUsings(List<ProjectRootElement> projectsMissingImplicitUsings)
List<ProjectRootElement> projectsMissingImplicitUsings
)
{ {
foreach (var project in projectsMissingImplicitUsings) foreach (var project in projectsMissingImplicitUsings)
{ {
@@ -53,24 +46,20 @@ public static class ImplicitUsings
} }
} }
public static void EnableDisabledImplicitUsings( public static void EnableDisabledImplicitUsings(List<ProjectRootElement> projectsMissingImplicitUsings)
List<ProjectRootElement> projectsMissingImplicitUsings
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public static void EnableAllImplicitUsings( public static void EnableAllImplicitUsings(List<ProjectRootElement> projectsMissingImplicitUsings)
List<ProjectRootElement> projectsMissingImplicitUsings
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public static bool ProjectIsMissingImplicitUsings(ProjectRootElement project) public static bool ProjectIsMissingImplicitUsings(ProjectRootElement project)
{ {
var implicitUsings = project.PropertyGroups var implicitUsings = project
.SelectMany(x => x.Properties) .PropertyGroups.SelectMany(x => x.Properties)
.FirstOrDefault(x => x.Name == "ImplicitUsings"); .FirstOrDefault(x => x.Name == "ImplicitUsings");
if (implicitUsings is null) if (implicitUsings is null)
{ {

View File

@@ -1,69 +1,30 @@
using Microsoft.Build.Construction; using DotNetSolutionTools.Core.Common;
using Microsoft.Build.Construction;
namespace DotNetSolutionTools.Core; namespace DotNetSolutionTools.Core;
public static class SolutionProjectParity public static class SolutionProjectParity
{ {
public static List<string> CompareSolutionAndCSharpProjects( public static List<string> CompareSolutionAndCSharpProjects(string solutionFolderPath, string solutionFilePath)
string solutionFolderPath,
string solutionFilePath
)
{ {
var csprojList = RetrieveAllCSharpProjectNamesFromFolder(solutionFolderPath); var csprojList = CsprojHelper.RetrieveAllCSharpProjectFullPathsFromFolder(solutionFolderPath);
var solutionFile = ParseSolutionFileFromPath(solutionFilePath); var solutionFile = SlnHelper.ParseSolutionFileFromPath(solutionFilePath);
ArgumentNullException.ThrowIfNull(solutionFile); ArgumentNullException.ThrowIfNull(solutionFile);
var projectsMissingFromSolution = FindProjectsMissingFromSolution(csprojList, solutionFile); var projectsMissingFromSolution = FindProjectsMissingFromSolution(csprojList, solutionFile);
return projectsMissingFromSolution; return projectsMissingFromSolution;
} }
public static string[] RetrieveAllCSharpProjectNamesFromFolder(string solutionFolderPath) public static List<string> FindProjectsMissingFromSolution(string[] csprojList, SolutionFile solutionFile)
{
var csprojList = RetrieveAllCSharpProjectFullPathsFromFolder(solutionFolderPath);
return csprojList;
}
public static string[] RetrieveAllCSharpProjectFullPathsFromFolder(string solutionFolderPath)
{
// if solutionFolderPath does not end with a slash, add one
if (solutionFolderPath[^1] != Path.DirectorySeparatorChar)
{
solutionFolderPath += Path.DirectorySeparatorChar;
}
var csprojList = Directory.GetFiles(
solutionFolderPath,
"*.csproj",
SearchOption.AllDirectories
);
return csprojList;
}
public static string[] RetrieveAllCSharpProjectFullPathsFromSolution(SolutionFile solution)
{
var result = GetCSharpProjectObjectsFromSolutionFile(solution);
var csprojList = result.Select(x => x.FullPath).ToArray();
return csprojList;
}
public static SolutionFile? ParseSolutionFileFromPath(string solutionFilePath)
{
var solutionFile = SolutionFile.Parse(solutionFilePath);
return solutionFile;
}
public static List<string> FindProjectsMissingFromSolution(
string[] csprojList,
SolutionFile solutionFile
)
{ {
var projects = solutionFile.ProjectsInOrder; var projects = solutionFile.ProjectsInOrder;
var projectsMissingFromSolution = new List<string>(); var projectsMissingFromSolution = new List<string>();
foreach (var project in csprojList) foreach (var project in csprojList)
{ {
var projectInSolution = projects.FirstOrDefault(x => NormalizePath(x.AbsolutePath) == NormalizePath(project)); var projectInSolution = projects.FirstOrDefault(x =>
NormalizePath(x.AbsolutePath) == NormalizePath(project)
);
if (projectInSolution == null) if (projectInSolution == null)
{ {
@@ -74,18 +35,6 @@ public static class SolutionProjectParity
return projectsMissingFromSolution; return projectsMissingFromSolution;
} }
public static List<ProjectRootElement> GetCSharpProjectObjectsFromSolutionFile(
SolutionFile solutionFile
)
{
var projectList = solutionFile.ProjectsByGuid
.Where(x => x.Value.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
.Select(s => ProjectRootElement.Open(s.Value.AbsolutePath))
.ToList();
return projectList;
}
private static string NormalizePath(string path) private static string NormalizePath(string path)
{ {
return Path.GetFullPath(new Uri(path).LocalPath) return Path.GetFullPath(new Uri(path).LocalPath)

View File

@@ -1,4 +1,5 @@
using Microsoft.Build.Construction; using DotNetSolutionTools.Core.Common;
using Microsoft.Build.Construction;
namespace DotNetSolutionTools.Core; namespace DotNetSolutionTools.Core;
@@ -7,7 +8,7 @@ public static class WarningsAsErrors
public static List<string> FindCSharpProjectsMissingTreatWarningsAsErrors(string solutionFilePath) public static List<string> FindCSharpProjectsMissingTreatWarningsAsErrors(string solutionFilePath)
{ {
var solutionFile = SolutionFile.Parse(solutionFilePath); var solutionFile = SolutionFile.Parse(solutionFilePath);
var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var csprojList = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
var projectsMissingImplicitUsings = FindCSharpProjectsMissingTreatWarningsAsErrors(csprojList); var projectsMissingImplicitUsings = FindCSharpProjectsMissingTreatWarningsAsErrors(csprojList);
var projectsMissingImplicitUsingsStringList = projectsMissingImplicitUsings.Select(x => x.FullPath).ToList(); var projectsMissingImplicitUsingsStringList = projectsMissingImplicitUsings.Select(x => x.FullPath).ToList();
@@ -37,7 +38,7 @@ public static class WarningsAsErrors
public static void AddMissingTreatWarningsAsErrorsToSolution(string solutionFilePath) public static void AddMissingTreatWarningsAsErrorsToSolution(string solutionFilePath)
{ {
var solutionFile = SolutionFile.Parse(solutionFilePath); var solutionFile = SolutionFile.Parse(solutionFilePath);
var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var csprojList = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
var projectsMissingImplicitUsings = FindCSharpProjectsMissingTreatWarningsAsErrors(csprojList); var projectsMissingImplicitUsings = FindCSharpProjectsMissingTreatWarningsAsErrors(csprojList);
AddMissingTreatWarningsAsErrors(projectsMissingImplicitUsings); AddMissingTreatWarningsAsErrors(projectsMissingImplicitUsings);
} }
@@ -45,7 +46,7 @@ public static class WarningsAsErrors
public static void RemoveAllTreatWarningsAsErrorsInSolution(string solutionFilePath) public static void RemoveAllTreatWarningsAsErrorsInSolution(string solutionFilePath)
{ {
var solutionFile = SolutionFile.Parse(solutionFilePath); var solutionFile = SolutionFile.Parse(solutionFilePath);
var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(solutionFile); var csprojList = SlnHelper.GetCSharpProjectObjectsFromSolutionFile(solutionFile);
RemoveTreatWarningsAsErrors(csprojList); RemoveTreatWarningsAsErrors(csprojList);
} }

View File

@@ -29,7 +29,7 @@ _options_
_options_ _options_
`-m|--add-missing` adds missing TreatWarningsAsErrors to all project files `-m|--add-missing` adds missing TreatWarningsAsErrors to all project files
**clear-bin-obj** `<SolutionFolderPath>` **NOT IMPLEMENTED IN CLI YET** Deletes all bin and obj folders, and node_modules folders in the solution folder. **clear-bin-obj** `<SolutionFolderPath>` Deletes all bin and obj folders, and node_modules folders in the solution folder.
**update-sln-net80** `<SolutionFilePath>` **NOT IMPLEMENTED IN CLI YET** Updates all projects and Microsoft NuGet packages in sln to .NET 8.0. **update-sln-net80** `<SolutionFilePath>` **NOT IMPLEMENTED IN CLI YET** Updates all projects and Microsoft NuGet packages in sln to .NET 8.0.