Skip to content

Commit

Permalink
.NET 8 and C# 12.
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel authored and phmonte committed Feb 20, 2024
1 parent 35f12d2 commit c9a0eb3
Show file tree
Hide file tree
Showing 52 changed files with 3,703 additions and 3,766 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
include-prerelease: true
dotnet-version: |
3.1.x
7.0.x
8.0.x
- name: Build and Test
run: dotnet test --logger "trx;LogFileName=test-results.trx"
- name: Upload Test Results
Expand Down
28 changes: 16 additions & 12 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
<Project>

<PropertyGroup>
<Version Condition="'$(BuildalyzerVersion)' == ''">1.0.0</Version>
<Version Condition="'$(BuildalyzerVersion)' != ''">$(BuildalyzerVersion)</Version>
<AssemblyVersion>$(Version.Split('-')[0])</AssemblyVersion>
<FileVersion>$(Version.Split('-')[0])</FileVersion>
<Authors>Dave Glick and contributors</Authors>
<Company>Dave Glick and contributors</Company>
<Authors>Dave Glick, Pablo Monteiro, and contributors</Authors>
<Company>Dave Glick, Pablo Monteiro, and contributors</Company>
<PackageIcon>icon.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/daveaglick/Buildalyzer</PackageProjectUrl>
<RepositoryUrl>https://github.com/daveaglick/Buildalyzer.git</RepositoryUrl>
<PackageProjectUrl>https://github.com/phmonte/Buildalyzer</PackageProjectUrl>
<RepositoryUrl>https://github.com/phmonte/Buildalyzer.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\LICENSE.md" Pack="true" PackagePath=""/>
<None Include="$(MSBuildThisFileDirectory)\icon.png" Pack="true" PackagePath="\"/>
<None Include="$(MSBuildThisFileDirectory)\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All"/>
<PackageReference Include="Roslynator.Analyzers" Version="4.0.2" PrivateAssets="All"/>
<!-- It appears as though there might be a performance issue in versions of Microsoft.VisualStudio.Threading.Analyzers past this at least through 17.0.64 -->
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="16.9.60" PrivateAssets="All"/>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
</ItemGroup>

<ItemGroup Label="Analyzers">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="*" PrivateAssets="All"/>
<PackageReference Include="Roslynator.Analyzers" Version="*" PrivateAssets="All"/>
<PackageReference Include="StyleCop.Analyzers" Version="*-*" PrivateAssets="All"/>
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions src/Buildalyzer.Logger/Buildalyzer.Logger.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>12</LangVersion>
<IncludeBuildOutput>true</IncludeBuildOutput>
<Description>The MSBuild logger for Buildalyzer. Not intended to be used directly.</Description>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);PackLogger</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="14.3.0" PrivateAssets="All" />
<PackageReference Include="MsBuildPipeLogger.Logger" Version="1.1.6" PrivateAssets="All" IsLogger="true" />
Expand All @@ -26,4 +29,5 @@
<BuildOutputInPackage Include="@(LoggerFiles)" />
</ItemGroup>
</Target>

</Project>
133 changes: 65 additions & 68 deletions src/Buildalyzer.Logger/BuildalyzerLogger.cs
Original file line number Diff line number Diff line change
@@ -1,96 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using MsBuildPipeLogger;

namespace Buildalyzer.Logger
namespace Buildalyzer.Logger;

public class BuildalyzerLogger : PipeLogger
{
public class BuildalyzerLogger : PipeLogger
{
private string _pipeHandleAsString;
private bool _logEverything;
private string _pipeHandleAsString;
private bool _logEverything;

public override void Initialize(IEventSource eventSource)
public override void Initialize(IEventSource eventSource)
{
// Parse the parameters
string[] parameters = Parameters.Split(';').Select(x => x.Trim()).ToArray();
if (parameters.Length != 2)
{
// Parse the parameters
string[] parameters = Parameters.Split(';').Select(x => x.Trim()).ToArray();
if (parameters.Length != 2)
{
throw new LoggerException("Unexpected number of parameters");
}
_pipeHandleAsString = parameters[0];
if (!bool.TryParse(parameters[1], out _logEverything))
{
throw new LoggerException("Second parameter (log everything) should be a bool");
}

base.Initialize(eventSource);
throw new LoggerException("Unexpected number of parameters");
}

protected override void InitializeEnvironmentVariables()
_pipeHandleAsString = parameters[0];
if (!bool.TryParse(parameters[1], out _logEverything))
{
// Only register the extra logging environment variables if logging everything
if (_logEverything)
{
base.InitializeEnvironmentVariables();
}
throw new LoggerException("Second parameter (log everything) should be a bool");
}

protected override IPipeWriter InitializePipeWriter() => new AnonymousPipeWriter(_pipeHandleAsString);
base.Initialize(eventSource);
}

protected override void InitializeEvents(IEventSource eventSource)
protected override void InitializeEnvironmentVariables()
{
// Only register the extra logging environment variables if logging everything
if (_logEverything)
{
if (eventSource is null)
{
throw new ArgumentNullException(nameof(eventSource));
}
base.InitializeEnvironmentVariables();
}
}

if (_logEverything)
{
base.InitializeEvents(eventSource);
return;
}
protected override IPipeWriter InitializePipeWriter() => new AnonymousPipeWriter(_pipeHandleAsString);

// Only log what we need for Buildalyzer
eventSource.ProjectStarted += (_, e) => Pipe.Write(e);
eventSource.ProjectFinished += (_, e) => Pipe.Write(e);
eventSource.BuildFinished += (_, e) => Pipe.Write(e);
eventSource.ErrorRaised += (_, e) => Pipe.Write(e);
eventSource.TargetStarted += TargetStarted;
eventSource.TargetFinished += TargetFinished;
eventSource.MessageRaised += MessageRaised;
protected override void InitializeEvents(IEventSource eventSource)
{
if (eventSource is null)
{
throw new ArgumentNullException(nameof(eventSource));
}

private void TargetStarted(object sender, TargetStartedEventArgs e)
if (_logEverything)
{
// Only send the CoreCompile target
if (e.TargetName == "CoreCompile")
{
Pipe.Write(e);
}
base.InitializeEvents(eventSource);
return;
}

private void TargetFinished(object sender, TargetFinishedEventArgs e)
// Only log what we need for Buildalyzer
eventSource.ProjectStarted += (_, e) => Pipe.Write(e);
eventSource.ProjectFinished += (_, e) => Pipe.Write(e);
eventSource.BuildFinished += (_, e) => Pipe.Write(e);
eventSource.ErrorRaised += (_, e) => Pipe.Write(e);
eventSource.TargetStarted += TargetStarted;
eventSource.TargetFinished += TargetFinished;
eventSource.MessageRaised += MessageRaised;
}

private void TargetStarted(object sender, TargetStartedEventArgs e)
{
// Only send the CoreCompile target
if (e.TargetName == "CoreCompile")
{
Pipe.Write(e);
}
}

private void TargetFinished(object sender, TargetFinishedEventArgs e)
{
// Only send the CoreCompile target
if (e.TargetName == "CoreCompile")
{
// Only send the CoreCompile target
if (e.TargetName == "CoreCompile")
{
Pipe.Write(e);
}
Pipe.Write(e);
}
}

private void MessageRaised(object sender, BuildMessageEventArgs e)
private void MessageRaised(object sender, BuildMessageEventArgs e)
{
// Only send if in the Csc Vbc, or the Fsc task
if ((e is TaskCommandLineEventArgs cmd &&
string.Equals(cmd.TaskName, "Csc", StringComparison.OrdinalIgnoreCase)) ||
string.Equals(e.SenderName, "Fsc", StringComparison.OrdinalIgnoreCase) ||
string.Equals(e.SenderName, "Vbc", StringComparison.OrdinalIgnoreCase))
{
// Only send if in the Csc Vbc, or the Fsc task
if ((e is TaskCommandLineEventArgs cmd &&
string.Equals(cmd.TaskName, "Csc", StringComparison.OrdinalIgnoreCase)) ||
string.Equals(e.SenderName, "Fsc", StringComparison.OrdinalIgnoreCase) ||
string.Equals(e.SenderName, "Vbc", StringComparison.OrdinalIgnoreCase))
{
Pipe.Write(e);
}
Pipe.Write(e);
}
}
}
86 changes: 42 additions & 44 deletions src/Buildalyzer.Workspaces/AnalyzerManagerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Build.Construction;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Logging;

namespace Buildalyzer.Workspaces
namespace Buildalyzer.Workspaces;

public static class AnalyzerManagerExtensions
{
public static class AnalyzerManagerExtensions
/// <summary>
/// Instantiates an empty AdhocWorkspace with logging event handlers.
/// </summary>
internal static AdhocWorkspace CreateWorkspace(this IAnalyzerManager manager)
{
ILogger logger = manager.LoggerFactory?.CreateLogger<AdhocWorkspace>();
AdhocWorkspace workspace = new AdhocWorkspace();
workspace.WorkspaceChanged += (sender, args) => logger?.LogDebug($"Workspace changed: {args.Kind.ToString()}{System.Environment.NewLine}");
workspace.WorkspaceFailed += (sender, args) => logger?.LogError($"Workspace failed: {args.Diagnostic}{System.Environment.NewLine}");
return workspace;
}

public static AdhocWorkspace GetWorkspace(this IAnalyzerManager manager)
{
/// <summary>
/// Instantiates an empty AdhocWorkspace with logging event handlers.
/// </summary>
internal static AdhocWorkspace CreateWorkspace(this IAnalyzerManager manager)
if (manager is null)
{
ILogger logger = manager.LoggerFactory?.CreateLogger<AdhocWorkspace>();
AdhocWorkspace workspace = new AdhocWorkspace();
workspace.WorkspaceChanged += (sender, args) => logger?.LogDebug($"Workspace changed: {args.Kind.ToString()}{System.Environment.NewLine}");
workspace.WorkspaceFailed += (sender, args) => logger?.LogError($"Workspace failed: {args.Diagnostic}{System.Environment.NewLine}");
return workspace;
throw new ArgumentNullException(nameof(manager));
}

public static AdhocWorkspace GetWorkspace(this IAnalyzerManager manager)
// Run builds in parallel
List<IAnalyzerResult> results = manager.Projects.Values
.AsParallel()
.Select(p => p.Build().FirstOrDefault())
.Where(x => x != null)
.ToList();

// Create a new workspace and add the solution (if there was one)
AdhocWorkspace workspace = manager.CreateWorkspace();
if (!string.IsNullOrEmpty(manager.SolutionFilePath))
{
if (manager is null)
{
throw new ArgumentNullException(nameof(manager));
}
SolutionInfo solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, manager.SolutionFilePath);
workspace.AddSolution(solutionInfo);

// Run builds in parallel
List<IAnalyzerResult> results = manager.Projects.Values
.AsParallel()
.Select(p => p.Build().FirstOrDefault())
.Where(x => x != null)
// Sort the projects so the order that they're added to the workspace in the same order as the solution file
List<ProjectInSolution> projectsInOrder = manager.SolutionFile.ProjectsInOrder.ToList();
results = results
.OrderBy(p => projectsInOrder.FindIndex(g => g.AbsolutePath == p.ProjectFilePath))
.ToList();
}

// Create a new workspace and add the solution (if there was one)
AdhocWorkspace workspace = manager.CreateWorkspace();
if (!string.IsNullOrEmpty(manager.SolutionFilePath))
{
SolutionInfo solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, manager.SolutionFilePath);
workspace.AddSolution(solutionInfo);

// Sort the projects so the order that they're added to the workspace in the same order as the solution file
List<ProjectInSolution> projectsInOrder = manager.SolutionFile.ProjectsInOrder.ToList();
results = results
.OrderBy(p => projectsInOrder.FindIndex(g => g.AbsolutePath == p.ProjectFilePath))
.ToList();
}

// Add each result to the new workspace (sorted in solution order above, if we have a solution)
foreach (IAnalyzerResult result in results)
// Add each result to the new workspace (sorted in solution order above, if we have a solution)
foreach (IAnalyzerResult result in results)
{
// Check for duplicate project files and don't add them
if (workspace.CurrentSolution.Projects.All(p => p.FilePath != result.ProjectFilePath))
{
// Check for duplicate project files and don't add them
if (workspace.CurrentSolution.Projects.All(p => p.FilePath != result.ProjectFilePath))
{
result.AddToWorkspace(workspace, true);
}
result.AddToWorkspace(workspace, true);
}
return workspace;
}
return workspace;
}
}
Loading

0 comments on commit c9a0eb3

Please sign in to comment.