From f096e6a93159ed3d9431211099eca14af71f4c45 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sat, 7 Sep 2024 10:19:02 +0200 Subject: [PATCH 01/10] Experimental new tracing --- src/Buildalyzer/BuildTrace.cs | 51 ++++++++ src/Buildalyzer/BuildTracer.cs | 190 +++++++++++++++++++++++++++++ src/Buildalyzer/ProjectAnalyzer.cs | 8 ++ 3 files changed, 249 insertions(+) create mode 100644 src/Buildalyzer/BuildTrace.cs create mode 100644 src/Buildalyzer/BuildTracer.cs diff --git a/src/Buildalyzer/BuildTrace.cs b/src/Buildalyzer/BuildTrace.cs new file mode 100644 index 00000000..7d8ee499 --- /dev/null +++ b/src/Buildalyzer/BuildTrace.cs @@ -0,0 +1,51 @@ +using Buildalyzer.IO; +using Microsoft.Build.Framework; + +namespace Buildalyzer; + +[DebuggerDisplay("{DebuggerDisplay}")] +public sealed class BuildTrace(BuildEventContext context) +{ + public BuildEventContext Context { get; } = context; + + public BuildTrace? Parent { get; internal set; } + + public IOPath ProjectFile { get; internal set; } + + public IOPath TargetFile { get; internal set; } + + public CompilerProperties GlobalProperties { get; internal set; } = new([]); + + public CompilerProperties Properties { get; internal set; } = new([]); + + public CompilerItemsCollection Items { get; internal set; } = new([]); + + public DateTime Timestamp { get; internal set; } + + public string? Message { get; internal set; } + + public MessageImportance Importance { get; internal set; } + + public TargetBuiltReason BuildReason { get; internal set; } + + public bool? Succeeded { get; internal set; } + + public void Update(Action update) + { + Guard.NotNull(update); + + lock (Locker) + { + update(this); + } + } + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private static readonly object Locker = new(); + + private string DebuggerDisplay + => $"{Context.ProjectContextId}, " + + $"Properties = {Properties.Count}, " + + $"Items = {Items.Count}, " + + $"Message = {Message}"; +} diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs new file mode 100644 index 00000000..33771a83 --- /dev/null +++ b/src/Buildalyzer/BuildTracer.cs @@ -0,0 +1,190 @@ +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; +using Buildalyzer.IO; +using Microsoft.Build.Framework; + +namespace Buildalyzer; + +public sealed class BuildTracer : IDisposable +{ + private readonly IEventSource EventSource; + + private ConcurrentDictionary Tracer = []; + + public IReadOnlyCollection Traces => Tracer.Values.ToArray(); + + public BuildTracer(IEventSource eventSource) + { + EventSource = Guard.NotNull(eventSource); + + EventSource.BuildStarted += BuildStarted; + EventSource.ProjectStarted += ProjectStarted; + EventSource.TaskStarted += TaskStarted; + EventSource.TargetStarted += TargetStarted; + + EventSource.CustomEventRaised += CustomEventRaised; + EventSource.MessageRaised += MessageRaised; + EventSource.ErrorRaised += ErrorRaised; + EventSource.StatusEventRaised += StatusEventRaised; + + EventSource.BuildFinished += BuildFinished; + EventSource.ProjectFinished += ProjectFinished; + EventSource.TaskFinished += TaskFinished; + EventSource.TargetFinished += TargetFinished; + } + + private void TaskStarted(object? sender, TaskStartedEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void TargetStarted(object? sender, TargetStartedEventArgs e) + { + var trace = Trace(e); + trace.Update(t => + { + t.BuildReason = e.BuildReason; + t.Message = e.Message; + t.ProjectFile = IOPath.Parse(e.ProjectFile); + t.TargetFile = IOPath.Parse(e.TargetFile); + t.Timestamp = e.Timestamp; + }); + Log(e); + } + + private void TargetFinished(object? sender, TargetFinishedEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void ProjectStarted(object? sender, ProjectStartedEventArgs e) + { + var trace = Trace(e); + trace.Update(t => + { + t.Parent = e.ParentProjectBuildEventContext is { } p ? Trace(p) : null; + t.Message = e.Message; + t.ProjectFile = IOPath.Parse(e.ProjectFile); + t.GlobalProperties = CompilerProperties.FromDictionaryEntries(e.GlobalProperties); + t.Properties = CompilerProperties.FromDictionaryEntries(e.Properties); + t.Items = CompilerItemsCollection.FromDictionaryEntries(e.Items); + t.Timestamp = e.Timestamp; + }); + Log(e); + } + + private void MessageRaised(object? sender, BuildMessageEventArgs e) + { + var trace = Trace(e); + trace.Update(t => + { + t.Message = e.Message; + t.ProjectFile = IOPath.Parse(e.ProjectFile); + t.Importance = e.Importance; + t.Timestamp = e.Timestamp; + }); + Log(e); + } + + private void StatusEventRaised(object? sender, BuildStatusEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void BuildStarted(object? sender, BuildStartedEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void ErrorRaised(object? sender, BuildErrorEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void CustomEventRaised(object? sender, CustomBuildEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void TaskFinished(object? sender, TaskFinishedEventArgs e) + { + var trace = Trace(e); + Log(e); + } + + private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) + { + var trace = Trace(e); + trace.Update(t => + { + t.Succeeded = e.Succeeded; + }); + Log(e); + } + + private void BuildFinished(object? sender, BuildFinishedEventArgs e) + { + if (e.BuildEventContext is { } ctx) + { + var trace = Trace(ctx); + } + Log(e); + } + + private static void Log(object obj, [CallerMemberName] string? paramName = null) + { + //var json = System.Text.Json.JsonSerializer.Serialize(obj, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); + Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: {paramName}"); + } + + private BuildTrace Trace(BuildEventArgs e) => Trace(e.BuildEventContext); + + private BuildTrace Trace(BuildStatusEventArgs e) => Trace(e.BuildEventContext); + + private BuildTrace Trace(BuildEventContext? context) + { + context = Guard.NotNull(context); + + if (!Tracer.TryGetValue(context, out var trace)) + { + trace = new BuildTrace(context); + Tracer[context] = trace; + } + return trace; + } + + public void Dispose() + { + if (!disposed) + { + EventSource.BuildStarted -= BuildStarted; + EventSource.ProjectStarted -= ProjectStarted; + EventSource.TaskStarted -= TaskStarted; + EventSource.TargetStarted -= TargetStarted; + + EventSource.CustomEventRaised -= CustomEventRaised; + EventSource.MessageRaised -= MessageRaised; + EventSource.ErrorRaised -= ErrorRaised; + EventSource.StatusEventRaised -= StatusEventRaised; + + EventSource.BuildFinished -= BuildFinished; + EventSource.ProjectFinished -= ProjectFinished; + EventSource.TaskFinished -= TaskFinished; + EventSource.TargetFinished -= TargetFinished; + disposed = true; + } + } + private bool disposed; +} + +public sealed class ProjectTrace +{ + public ProjectFinishedTrace? Finished { get; internal set; } +} +public sealed record ProjectFinishedTrace(bool Succeeded, string Message); \ No newline at end of file diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index 205bbfd8..4a0957b9 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Diagnostics; using System.IO; using System.Threading; using Buildalyzer.Construction; @@ -159,6 +160,9 @@ void OnPipeLoggerOnAnyEventRaised(object o, BuildEventArgs buildEventArgs) } pipeLogger.AnyEventRaised += OnPipeLoggerOnAnyEventRaised; + + using var tracer = new BuildTracer(pipeLogger); + using var eventProcessor = new EventProcessor(Manager, this, BuildLoggers, pipeLogger, results != null); // Run MSBuild @@ -169,6 +173,7 @@ void OnPipeLoggerOnAnyEventRaised(object o, BuildEventArgs buildEventArgs) targetsToBuild, pipeLogger.GetClientHandle(), out string arguments); + using (ProcessRunner processRunner = new ProcessRunner( fileName, arguments, @@ -200,6 +205,9 @@ void OnProcessRunnerExited() // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); + + var traces = tracer.Traces; + } return results; } From a0a22adf37cac6eece9f718f30ad5d87fd88030c Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 00:22:20 +0200 Subject: [PATCH 02/10] Wip --- src/Buildalyzer/BuildTrace.cs | 58 +++++++++-------- src/Buildalyzer/BuildTraceEvent.cs | 33 ++++++++++ src/Buildalyzer/BuildTraceId.cs | 13 ++++ src/Buildalyzer/BuildTracer.cs | 100 ++++++++++++++--------------- src/Buildalyzer/IO/IOPath.cs | 4 ++ src/Buildalyzer/ProjectAnalyzer.cs | 14 +++- 6 files changed, 142 insertions(+), 80 deletions(-) create mode 100644 src/Buildalyzer/BuildTraceEvent.cs create mode 100644 src/Buildalyzer/BuildTraceId.cs diff --git a/src/Buildalyzer/BuildTrace.cs b/src/Buildalyzer/BuildTrace.cs index 7d8ee499..1cbd82c6 100644 --- a/src/Buildalyzer/BuildTrace.cs +++ b/src/Buildalyzer/BuildTrace.cs @@ -1,51 +1,53 @@ -using Buildalyzer.IO; +using System.Runtime.CompilerServices; using Microsoft.Build.Framework; namespace Buildalyzer; [DebuggerDisplay("{DebuggerDisplay}")] -public sealed class BuildTrace(BuildEventContext context) +public sealed class BuildTrace(BuildTraceId id) { - public BuildEventContext Context { get; } = context; + public BuildTraceId Id { get; } = id; public BuildTrace? Parent { get; internal set; } - public IOPath ProjectFile { get; internal set; } + public List Events { get; } = []; - public IOPath TargetFile { get; internal set; } + public IEnumerable ProjectStarted => Events.Where(e => e.Event is ProjectStartedEventArgs); - public CompilerProperties GlobalProperties { get; internal set; } = new([]); - - public CompilerProperties Properties { get; internal set; } = new([]); - - public CompilerItemsCollection Items { get; internal set; } = new([]); - - public DateTime Timestamp { get; internal set; } - - public string? Message { get; internal set; } - - public MessageImportance Importance { get; internal set; } - - public TargetBuiltReason BuildReason { get; internal set; } + public BuildTrace Add(BuildEventArgs? e, [CallerMemberName] string? paramName = null) + { + if (e is { }) + { + lock (Locker) + { + Events.Add(new() { Context = e.BuildEventContext, Event = e, Name = paramName! }); + } + } - public bool? Succeeded { get; internal set; } + return this; + } - public void Update(Action update) + public BuildTrace Add(BuildStatusEventArgs? e, [CallerMemberName] string? paramName = null) { - Guard.NotNull(update); - - lock (Locker) + if (e is { }) { - update(this); + lock (Locker) + { + Events.Add(new() { Context = e.BuildEventContext, Event = e, Name = paramName! }); + } } + + return this; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly object Locker = new(); private string DebuggerDisplay - => $"{Context.ProjectContextId}, " - + $"Properties = {Properties.Count}, " - + $"Items = {Items.Count}, " - + $"Message = {Message}"; + => $"{Id}, " + + $"Events = {Events.Count}, " + + $"ProjectStarted = {ProjectStarted.Count()}" + ; + //+ $"Items = {Items.Count}, " + //+ $"Message = {Message}"; } diff --git a/src/Buildalyzer/BuildTraceEvent.cs b/src/Buildalyzer/BuildTraceEvent.cs new file mode 100644 index 00000000..1934a5b0 --- /dev/null +++ b/src/Buildalyzer/BuildTraceEvent.cs @@ -0,0 +1,33 @@ +using Buildalyzer.IO; +using Microsoft.Build.Framework; + +namespace Buildalyzer; + +[DebuggerDisplay("{DebuggerDisplay}")] +public sealed class BuildTraceEvent +{ + public DateTime Created { get; } = DateTime.Now; + + public BuildEventContext Context { get; init; } + + public string Name { get; init; } + + public object Event { get; init; } + + public string? Message => Event switch + { + BuildEventArgs a => a.Message, + _ => null, + }; + + private string DebuggerDisplay + => $"{Created:HH:mm:ss.ff}, " + + $"Project = {Context.ProjectContextId}, " + + $"Instance = {Context.ProjectInstanceId}, " + + $"Name = {Name}, " + + $"Event = {Event.GetType().Name}, " + + $"Message = {Message}, " + ; + //+ $"Items = {Items.Count}, " + //+ $"Message = {Message}"; +} diff --git a/src/Buildalyzer/BuildTraceId.cs b/src/Buildalyzer/BuildTraceId.cs new file mode 100644 index 00000000..2dd92eee --- /dev/null +++ b/src/Buildalyzer/BuildTraceId.cs @@ -0,0 +1,13 @@ +using Microsoft.Build.Framework; + +namespace Buildalyzer; + +public readonly record struct BuildTraceId( + int ProjectContextId, + int ProjectInstanceId) +{ + internal static BuildTraceId New(BuildEventContext c) + => new( + c.ProjectContextId, + c.ProjectInstanceId); +} diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs index 33771a83..5ab136d0 100644 --- a/src/Buildalyzer/BuildTracer.cs +++ b/src/Buildalyzer/BuildTracer.cs @@ -1,6 +1,5 @@ using System.Collections.Concurrent; using System.Runtime.CompilerServices; -using Buildalyzer.IO; using Microsoft.Build.Framework; namespace Buildalyzer; @@ -9,10 +8,30 @@ public sealed class BuildTracer : IDisposable { private readonly IEventSource EventSource; - private ConcurrentDictionary Tracer = []; + private ConcurrentDictionary Tracer = []; public IReadOnlyCollection Traces => Tracer.Values.ToArray(); + public IReadOnlyCollection Events => Tracer.Values.SelectMany(e => e.Events).ToArray(); + + public IEnumerable> Properties + => Events + .Where(e => e.Event is ProjectStartedEventArgs) + .Select(e => KeyValuePair.Create( + e.Context, CompilerProperties.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); + + public IEnumerable> CompilerItemsCollections + => Events + .Where(e => e.Event is ProjectStartedEventArgs) + .Select(e => KeyValuePair.Create( + e.Context, CompilerItemsCollection.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); + + public IEnumerable> Commands + => Events + .Where(e => e.Event is ProjectStartedEventArgs) + .Select(e => KeyValuePair.Create( + e.Context, CompilerProperties.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); + public BuildTracer(IEventSource eventSource) { EventSource = Guard.NotNull(eventSource); @@ -36,104 +55,84 @@ public BuildTracer(IEventSource eventSource) private void TaskStarted(object? sender, TaskStartedEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void TargetStarted(object? sender, TargetStartedEventArgs e) { var trace = Trace(e); - trace.Update(t => - { - t.BuildReason = e.BuildReason; - t.Message = e.Message; - t.ProjectFile = IOPath.Parse(e.ProjectFile); - t.TargetFile = IOPath.Parse(e.TargetFile); - t.Timestamp = e.Timestamp; - }); + trace?.Add(e); Log(e); } private void TargetFinished(object? sender, TargetFinishedEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void ProjectStarted(object? sender, ProjectStartedEventArgs e) { var trace = Trace(e); - trace.Update(t => - { - t.Parent = e.ParentProjectBuildEventContext is { } p ? Trace(p) : null; - t.Message = e.Message; - t.ProjectFile = IOPath.Parse(e.ProjectFile); - t.GlobalProperties = CompilerProperties.FromDictionaryEntries(e.GlobalProperties); - t.Properties = CompilerProperties.FromDictionaryEntries(e.Properties); - t.Items = CompilerItemsCollection.FromDictionaryEntries(e.Items); - t.Timestamp = e.Timestamp; - }); + trace?.Add(e); Log(e); } private void MessageRaised(object? sender, BuildMessageEventArgs e) { var trace = Trace(e); - trace.Update(t => - { - t.Message = e.Message; - t.ProjectFile = IOPath.Parse(e.ProjectFile); - t.Importance = e.Importance; - t.Timestamp = e.Timestamp; - }); + trace?.Add(e); Log(e); } private void StatusEventRaised(object? sender, BuildStatusEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void BuildStarted(object? sender, BuildStartedEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void ErrorRaised(object? sender, BuildErrorEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void CustomEventRaised(object? sender, CustomBuildEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void TaskFinished(object? sender, TaskFinishedEventArgs e) { var trace = Trace(e); + trace?.Add(e); Log(e); } private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) { var trace = Trace(e); - trace.Update(t => - { - t.Succeeded = e.Succeeded; - }); + trace?.Add(e); Log(e); } private void BuildFinished(object? sender, BuildFinishedEventArgs e) { - if (e.BuildEventContext is { } ctx) - { - var trace = Trace(ctx); - } + var trace = Trace(e); + trace?.Add(e); Log(e); } @@ -143,25 +142,30 @@ private static void Log(object obj, [CallerMemberName] string? paramName = null) Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: {paramName}"); } - private BuildTrace Trace(BuildEventArgs e) => Trace(e.BuildEventContext); + private BuildTrace? Trace(BuildEventArgs e) => Trace(e.BuildEventContext); - private BuildTrace Trace(BuildStatusEventArgs e) => Trace(e.BuildEventContext); + private BuildTrace? Trace(BuildStatusEventArgs e) => Trace(e.BuildEventContext); - private BuildTrace Trace(BuildEventContext? context) + private BuildTrace? Trace(BuildEventContext? context) { - context = Guard.NotNull(context); + if (context is null) + { + return null; + } - if (!Tracer.TryGetValue(context, out var trace)) + var id = BuildTraceId.New(context); + + if (!Tracer.TryGetValue(id, out var trace)) { - trace = new BuildTrace(context); - Tracer[context] = trace; + trace = new BuildTrace(id); + Tracer[id] = trace; } return trace; } public void Dispose() { - if (!disposed) + if (!Disposed) { EventSource.BuildStarted -= BuildStarted; EventSource.ProjectStarted -= ProjectStarted; @@ -177,14 +181,8 @@ public void Dispose() EventSource.ProjectFinished -= ProjectFinished; EventSource.TaskFinished -= TaskFinished; EventSource.TargetFinished -= TargetFinished; - disposed = true; + Disposed = true; } } - private bool disposed; -} - -public sealed class ProjectTrace -{ - public ProjectFinishedTrace? Finished { get; internal set; } + private bool Disposed; } -public sealed record ProjectFinishedTrace(bool Succeeded, string Message); \ No newline at end of file diff --git a/src/Buildalyzer/IO/IOPath.cs b/src/Buildalyzer/IO/IOPath.cs index dd71ef71..6dce0135 100644 --- a/src/Buildalyzer/IO/IOPath.cs +++ b/src/Buildalyzer/IO/IOPath.cs @@ -52,6 +52,10 @@ public override bool Equals([NotNullWhen(true)] object? obj) public bool Equals(IOPath other, bool caseSensitive) => string.Equals(_path, other._path, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + public static bool operator ==(IOPath left, IOPath right) => left.Equals(right); + + public static bool operator !=(IOPath left, IOPath right) => !(left == right); + /// [Pure] public override int GetHashCode() diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index 4a0957b9..ffc726c9 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -206,7 +206,19 @@ void OnProcessRunnerExited() // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); - var traces = tracer.Traces; + var es = tracer.Events; + + var commandlines = es.Where(e => e.Event is TaskCommandLineEventArgs).ToArray(); + + if (commandlines.Length > 1) + { + //var bs = es.Where(e => e.Event is BuildMessageEventArgs a && a.SenderName == "Fsc").ToArray(); + + //if (!bs.Any()) + { + throw new InvalidOperationException("No commandline event found."); + } + } } return results; From 06b132b8db46215fc5b9cd1d97faae58dd0ada80 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 01:15:29 +0200 Subject: [PATCH 03/10] Simplify. --- src/Buildalyzer/BuildTrace.cs | 53 ------------ src/Buildalyzer/BuildTraceEvent.cs | 33 -------- src/Buildalyzer/BuildTraceId.cs | 13 --- src/Buildalyzer/BuildTracer.cs | 118 ++++++++++++--------------- src/Buildalyzer/Extensions/String.cs | 7 ++ src/Buildalyzer/ProjectAnalyzer.cs | 15 ---- 6 files changed, 59 insertions(+), 180 deletions(-) delete mode 100644 src/Buildalyzer/BuildTrace.cs delete mode 100644 src/Buildalyzer/BuildTraceEvent.cs delete mode 100644 src/Buildalyzer/BuildTraceId.cs create mode 100644 src/Buildalyzer/Extensions/String.cs diff --git a/src/Buildalyzer/BuildTrace.cs b/src/Buildalyzer/BuildTrace.cs deleted file mode 100644 index 1cbd82c6..00000000 --- a/src/Buildalyzer/BuildTrace.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Runtime.CompilerServices; -using Microsoft.Build.Framework; - -namespace Buildalyzer; - -[DebuggerDisplay("{DebuggerDisplay}")] -public sealed class BuildTrace(BuildTraceId id) -{ - public BuildTraceId Id { get; } = id; - - public BuildTrace? Parent { get; internal set; } - - public List Events { get; } = []; - - public IEnumerable ProjectStarted => Events.Where(e => e.Event is ProjectStartedEventArgs); - - public BuildTrace Add(BuildEventArgs? e, [CallerMemberName] string? paramName = null) - { - if (e is { }) - { - lock (Locker) - { - Events.Add(new() { Context = e.BuildEventContext, Event = e, Name = paramName! }); - } - } - - return this; - } - - public BuildTrace Add(BuildStatusEventArgs? e, [CallerMemberName] string? paramName = null) - { - if (e is { }) - { - lock (Locker) - { - Events.Add(new() { Context = e.BuildEventContext, Event = e, Name = paramName! }); - } - } - - return this; - } - - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private static readonly object Locker = new(); - - private string DebuggerDisplay - => $"{Id}, " - + $"Events = {Events.Count}, " - + $"ProjectStarted = {ProjectStarted.Count()}" - ; - //+ $"Items = {Items.Count}, " - //+ $"Message = {Message}"; -} diff --git a/src/Buildalyzer/BuildTraceEvent.cs b/src/Buildalyzer/BuildTraceEvent.cs deleted file mode 100644 index 1934a5b0..00000000 --- a/src/Buildalyzer/BuildTraceEvent.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Buildalyzer.IO; -using Microsoft.Build.Framework; - -namespace Buildalyzer; - -[DebuggerDisplay("{DebuggerDisplay}")] -public sealed class BuildTraceEvent -{ - public DateTime Created { get; } = DateTime.Now; - - public BuildEventContext Context { get; init; } - - public string Name { get; init; } - - public object Event { get; init; } - - public string? Message => Event switch - { - BuildEventArgs a => a.Message, - _ => null, - }; - - private string DebuggerDisplay - => $"{Created:HH:mm:ss.ff}, " - + $"Project = {Context.ProjectContextId}, " - + $"Instance = {Context.ProjectInstanceId}, " - + $"Name = {Name}, " - + $"Event = {Event.GetType().Name}, " - + $"Message = {Message}, " - ; - //+ $"Items = {Items.Count}, " - //+ $"Message = {Message}"; -} diff --git a/src/Buildalyzer/BuildTraceId.cs b/src/Buildalyzer/BuildTraceId.cs deleted file mode 100644 index 2dd92eee..00000000 --- a/src/Buildalyzer/BuildTraceId.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.Build.Framework; - -namespace Buildalyzer; - -public readonly record struct BuildTraceId( - int ProjectContextId, - int ProjectInstanceId) -{ - internal static BuildTraceId New(BuildEventContext c) - => new( - c.ProjectContextId, - c.ProjectInstanceId); -} diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs index 5ab136d0..eaee5658 100644 --- a/src/Buildalyzer/BuildTracer.cs +++ b/src/Buildalyzer/BuildTracer.cs @@ -1,5 +1,7 @@ using System.Collections.Concurrent; +using System.IO; using System.Runtime.CompilerServices; +using Buildalyzer.IO; using Microsoft.Build.Framework; namespace Buildalyzer; @@ -8,29 +10,13 @@ public sealed class BuildTracer : IDisposable { private readonly IEventSource EventSource; - private ConcurrentDictionary Tracer = []; + public ConcurrentBag Events { get; } = []; - public IReadOnlyCollection Traces => Tracer.Values.ToArray(); + public ConcurrentBag> Paths { get; } = []; + public ConcurrentBag> Properties { get; } = []; + public ConcurrentBag> Items { get; } = []; - public IReadOnlyCollection Events => Tracer.Values.SelectMany(e => e.Events).ToArray(); - - public IEnumerable> Properties - => Events - .Where(e => e.Event is ProjectStartedEventArgs) - .Select(e => KeyValuePair.Create( - e.Context, CompilerProperties.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); - - public IEnumerable> CompilerItemsCollections - => Events - .Where(e => e.Event is ProjectStartedEventArgs) - .Select(e => KeyValuePair.Create( - e.Context, CompilerItemsCollection.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); - - public IEnumerable> Commands - => Events - .Where(e => e.Event is ProjectStartedEventArgs) - .Select(e => KeyValuePair.Create( - e.Context, CompilerProperties.FromDictionaryEntries(((ProjectStartedEventArgs)e.Event).Properties))); + public ConcurrentBag> Commands { get; } = []; public BuildTracer(IEventSource eventSource) { @@ -54,85 +40,106 @@ public BuildTracer(IEventSource eventSource) private void TaskStarted(object? sender, TaskStartedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void TargetStarted(object? sender, TargetStartedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void TargetFinished(object? sender, TargetFinishedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void ProjectStarted(object? sender, ProjectStartedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); + + var path = IOPath.Parse(e.ProjectFile); + var properties = CompilerProperties.FromDictionaryEntries(e.Properties); + var items = CompilerItemsCollection.FromDictionaryEntries(e.Items); + + Paths.Add(KeyValuePair.Create(e.BuildEventContext, path)); + Properties.Add(KeyValuePair.Create(e.BuildEventContext, properties)); + Items.Add(KeyValuePair.Create(e.BuildEventContext, items)); + Log(e); } private void MessageRaised(object? sender, BuildMessageEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); + + var path = Paths.First(p => p.Key.ProjectInstanceId == e.BuildEventContext.ProjectInstanceId); + + var dir = path.Value.File().Directory; + + var command = e switch + { + //TaskCommandLineEventArgs a when a.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.CSharp), + //TaskCommandLineEventArgs a when a.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.VisualBasic), + _ when e.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.CSharp), + _ when e.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.VisualBasic), + _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.FSharp), + _ => null, + }; + + if (command is { }) + { + Commands.Add(KeyValuePair.Create(e.BuildEventContext, command)); + } + else + { + + } + Log(e); } private void StatusEventRaised(object? sender, BuildStatusEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void BuildStarted(object? sender, BuildStartedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void ErrorRaised(object? sender, BuildErrorEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void CustomEventRaised(object? sender, CustomBuildEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void TaskFinished(object? sender, TaskFinishedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } private void BuildFinished(object? sender, BuildFinishedEventArgs e) { - var trace = Trace(e); - trace?.Add(e); + Events.Add(e); Log(e); } @@ -142,27 +149,6 @@ private static void Log(object obj, [CallerMemberName] string? paramName = null) Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: {paramName}"); } - private BuildTrace? Trace(BuildEventArgs e) => Trace(e.BuildEventContext); - - private BuildTrace? Trace(BuildStatusEventArgs e) => Trace(e.BuildEventContext); - - private BuildTrace? Trace(BuildEventContext? context) - { - if (context is null) - { - return null; - } - - var id = BuildTraceId.New(context); - - if (!Tracer.TryGetValue(id, out var trace)) - { - trace = new BuildTrace(id); - Tracer[id] = trace; - } - return trace; - } - public void Dispose() { if (!Disposed) diff --git a/src/Buildalyzer/Extensions/String.cs b/src/Buildalyzer/Extensions/String.cs new file mode 100644 index 00000000..851cdb04 --- /dev/null +++ b/src/Buildalyzer/Extensions/String.cs @@ -0,0 +1,7 @@ +namespace System; + +internal static class BuildalyzerStringExtensions +{ + public static bool IsMatch(this string? str, string? other) + => string.Equals(str, other, StringComparison.OrdinalIgnoreCase); +} diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index ffc726c9..e5409e46 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -205,21 +205,6 @@ void OnProcessRunnerExited() // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); - - var es = tracer.Events; - - var commandlines = es.Where(e => e.Event is TaskCommandLineEventArgs).ToArray(); - - if (commandlines.Length > 1) - { - //var bs = es.Where(e => e.Event is BuildMessageEventArgs a && a.SenderName == "Fsc").ToArray(); - - //if (!bs.Any()) - { - throw new InvalidOperationException("No commandline event found."); - } - } - } return results; } From cf12ad7cfedbe15bdefd2a1180b0c0133f3e283c Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 01:20:32 +0200 Subject: [PATCH 04/10] Shorten. --- src/Buildalyzer/BuildTracer.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs index eaee5658..ee7ff925 100644 --- a/src/Buildalyzer/BuildTracer.cs +++ b/src/Buildalyzer/BuildTracer.cs @@ -81,11 +81,9 @@ private void MessageRaised(object? sender, BuildMessageEventArgs e) var command = e switch { - //TaskCommandLineEventArgs a when a.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.CSharp), - //TaskCommandLineEventArgs a when a.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.VisualBasic), - _ when e.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.CSharp), - _ when e.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.VisualBasic), - _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.FSharp), + TaskCommandLineEventArgs a when a.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.CSharp), + TaskCommandLineEventArgs a when a.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.VisualBasic), + _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.FSharp), _ => null, }; @@ -93,11 +91,6 @@ _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, { Commands.Add(KeyValuePair.Create(e.BuildEventContext, command)); } - else - { - - } - Log(e); } From 37a6b67e4f73f2aec8c97c644b41f94cca851ac0 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 01:28:19 +0200 Subject: [PATCH 05/10] Clean-up --- src/Buildalyzer/BuildTracer.cs | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs index ee7ff925..383ab185 100644 --- a/src/Buildalyzer/BuildTracer.cs +++ b/src/Buildalyzer/BuildTracer.cs @@ -1,6 +1,4 @@ using System.Collections.Concurrent; -using System.IO; -using System.Runtime.CompilerServices; using Buildalyzer.IO; using Microsoft.Build.Framework; @@ -41,19 +39,16 @@ public BuildTracer(IEventSource eventSource) private void TaskStarted(object? sender, TaskStartedEventArgs e) { Events.Add(e); - Log(e); } private void TargetStarted(object? sender, TargetStartedEventArgs e) { Events.Add(e); - Log(e); } private void TargetFinished(object? sender, TargetFinishedEventArgs e) { Events.Add(e); - Log(e); } private void ProjectStarted(object? sender, ProjectStartedEventArgs e) @@ -67,8 +62,6 @@ private void ProjectStarted(object? sender, ProjectStartedEventArgs e) Paths.Add(KeyValuePair.Create(e.BuildEventContext, path)); Properties.Add(KeyValuePair.Create(e.BuildEventContext, properties)); Items.Add(KeyValuePair.Create(e.BuildEventContext, items)); - - Log(e); } private void MessageRaised(object? sender, BuildMessageEventArgs e) @@ -91,55 +84,41 @@ _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, { Commands.Add(KeyValuePair.Create(e.BuildEventContext, command)); } - Log(e); } private void StatusEventRaised(object? sender, BuildStatusEventArgs e) { Events.Add(e); - Log(e); } private void BuildStarted(object? sender, BuildStartedEventArgs e) { Events.Add(e); - Log(e); } private void ErrorRaised(object? sender, BuildErrorEventArgs e) { Events.Add(e); - Log(e); } private void CustomEventRaised(object? sender, CustomBuildEventArgs e) { Events.Add(e); - Log(e); } private void TaskFinished(object? sender, TaskFinishedEventArgs e) { Events.Add(e); - Log(e); } private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) { Events.Add(e); - Log(e); } private void BuildFinished(object? sender, BuildFinishedEventArgs e) { Events.Add(e); - Log(e); - } - - private static void Log(object obj, [CallerMemberName] string? paramName = null) - { - //var json = System.Text.Json.JsonSerializer.Serialize(obj, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); - Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: {paramName}"); } public void Dispose() @@ -163,5 +142,6 @@ public void Dispose() Disposed = true; } } + private bool Disposed; } From 0c236ff2ee87d664e2ada85729fc1a82955d8713 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 01:45:58 +0200 Subject: [PATCH 06/10] Split concerns: collect events as-is for further processing later. --- src/Buildalyzer/BuildEventCollector.cs | 83 ++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/Buildalyzer/BuildEventCollector.cs diff --git a/src/Buildalyzer/BuildEventCollector.cs b/src/Buildalyzer/BuildEventCollector.cs new file mode 100644 index 00000000..c7aa5b3c --- /dev/null +++ b/src/Buildalyzer/BuildEventCollector.cs @@ -0,0 +1,83 @@ +using System.Collections.Concurrent; +using Microsoft.Build.Framework; + +namespace Buildalyzer; + +public sealed class BuildEventCollector : IDisposable +{ + public BuildEventCollector(IEventSource eventSource) + { + EventSource = Guard.NotNull(eventSource); + + EventSource.BuildStarted += BuildStarted; + EventSource.ProjectStarted += ProjectStarted; + EventSource.TaskStarted += TaskStarted; + EventSource.TargetStarted += TargetStarted; + + EventSource.CustomEventRaised += CustomEventRaised; + EventSource.MessageRaised += MessageRaised; + EventSource.ErrorRaised += ErrorRaised; + EventSource.StatusEventRaised += StatusEventRaised; + + EventSource.BuildFinished += BuildFinished; + EventSource.ProjectFinished += ProjectFinished; + EventSource.TaskFinished += TaskFinished; + EventSource.TargetFinished += TargetFinished; + } + + public ImmutableArray Events => Bag.ToImmutableArray(); + + private readonly IEventSource EventSource; + + private readonly ConcurrentBag Bag = []; + + private void Add(BuildEventArgs e) => Bag.Add(e); + + private void TaskStarted(object? sender, TaskStartedEventArgs e) => Add(e); + + private void TargetStarted(object? sender, TargetStartedEventArgs e) => Add(e); + + private void TargetFinished(object? sender, TargetFinishedEventArgs e) => Add(e); + + private void ProjectStarted(object? sender, ProjectStartedEventArgs e) => Add(e); + + private void MessageRaised(object? sender, BuildMessageEventArgs e) => Add(e); + + private void StatusEventRaised(object? sender, BuildStatusEventArgs e) => Add(e); + + private void BuildStarted(object? sender, BuildStartedEventArgs e) => Add(e); + + private void ErrorRaised(object? sender, BuildErrorEventArgs e) => Add(e); + + private void CustomEventRaised(object? sender, CustomBuildEventArgs e) => Add(e); + + private void TaskFinished(object? sender, TaskFinishedEventArgs e) => Add(e); + + private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) => Add(e); + + private void BuildFinished(object? sender, BuildFinishedEventArgs e) => Add(e); + + public void Dispose() + { + if (!Disposed) + { + EventSource.BuildStarted -= BuildStarted; + EventSource.ProjectStarted -= ProjectStarted; + EventSource.TaskStarted -= TaskStarted; + EventSource.TargetStarted -= TargetStarted; + + EventSource.CustomEventRaised -= CustomEventRaised; + EventSource.MessageRaised -= MessageRaised; + EventSource.ErrorRaised -= ErrorRaised; + EventSource.StatusEventRaised -= StatusEventRaised; + + EventSource.BuildFinished -= BuildFinished; + EventSource.ProjectFinished -= ProjectFinished; + EventSource.TaskFinished -= TaskFinished; + EventSource.TargetFinished -= TargetFinished; + Disposed = true; + } + } + + private bool Disposed; +} From 0cf4d8ec1e8dad372b2dd69a50362a0b104cd121 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 11:22:13 +0200 Subject: [PATCH 07/10] Less is more --- src/Buildalyzer/BuildEventCollector.cs | 75 +++---------- src/Buildalyzer/BuildTracer.cs | 147 ------------------------- src/Buildalyzer/ProjectAnalyzer.cs | 4 +- 3 files changed, 20 insertions(+), 206 deletions(-) delete mode 100644 src/Buildalyzer/BuildTracer.cs diff --git a/src/Buildalyzer/BuildEventCollector.cs b/src/Buildalyzer/BuildEventCollector.cs index c7aa5b3c..f5b8d64e 100644 --- a/src/Buildalyzer/BuildEventCollector.cs +++ b/src/Buildalyzer/BuildEventCollector.cs @@ -1,80 +1,39 @@ using System.Collections.Concurrent; using Microsoft.Build.Framework; +using Microsoft.Build.Logging; namespace Buildalyzer; -public sealed class BuildEventCollector : IDisposable +[DebuggerDisplay("Count = {Count}")] +[DebuggerTypeProxy(typeof(Diagnostics.CollectionDebugView))] +internal sealed class BuildEventCollector : IReadOnlyCollection, IDisposable { - public BuildEventCollector(IEventSource eventSource) + public BuildEventCollector(EventArgsDispatcher server) { - EventSource = Guard.NotNull(eventSource); - - EventSource.BuildStarted += BuildStarted; - EventSource.ProjectStarted += ProjectStarted; - EventSource.TaskStarted += TaskStarted; - EventSource.TargetStarted += TargetStarted; - - EventSource.CustomEventRaised += CustomEventRaised; - EventSource.MessageRaised += MessageRaised; - EventSource.ErrorRaised += ErrorRaised; - EventSource.StatusEventRaised += StatusEventRaised; - - EventSource.BuildFinished += BuildFinished; - EventSource.ProjectFinished += ProjectFinished; - EventSource.TaskFinished += TaskFinished; - EventSource.TargetFinished += TargetFinished; + Server = server; + Server.AnyEventRaised += EventRaised; } - public ImmutableArray Events => Bag.ToImmutableArray(); - - private readonly IEventSource EventSource; - - private readonly ConcurrentBag Bag = []; - - private void Add(BuildEventArgs e) => Bag.Add(e); - - private void TaskStarted(object? sender, TaskStartedEventArgs e) => Add(e); - - private void TargetStarted(object? sender, TargetStartedEventArgs e) => Add(e); + /// + public int Count => Bag.Count; - private void TargetFinished(object? sender, TargetFinishedEventArgs e) => Add(e); + /// + public IEnumerator GetEnumerator() => Bag.GetEnumerator(); - private void ProjectStarted(object? sender, ProjectStartedEventArgs e) => Add(e); + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - private void MessageRaised(object? sender, BuildMessageEventArgs e) => Add(e); + private void EventRaised(object? sender, BuildEventArgs e) => Bag.Add(e); - private void StatusEventRaised(object? sender, BuildStatusEventArgs e) => Add(e); + private readonly EventArgsDispatcher Server; - private void BuildStarted(object? sender, BuildStartedEventArgs e) => Add(e); - - private void ErrorRaised(object? sender, BuildErrorEventArgs e) => Add(e); - - private void CustomEventRaised(object? sender, CustomBuildEventArgs e) => Add(e); - - private void TaskFinished(object? sender, TaskFinishedEventArgs e) => Add(e); - - private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) => Add(e); - - private void BuildFinished(object? sender, BuildFinishedEventArgs e) => Add(e); + private readonly ConcurrentBag Bag = []; public void Dispose() { if (!Disposed) { - EventSource.BuildStarted -= BuildStarted; - EventSource.ProjectStarted -= ProjectStarted; - EventSource.TaskStarted -= TaskStarted; - EventSource.TargetStarted -= TargetStarted; - - EventSource.CustomEventRaised -= CustomEventRaised; - EventSource.MessageRaised -= MessageRaised; - EventSource.ErrorRaised -= ErrorRaised; - EventSource.StatusEventRaised -= StatusEventRaised; - - EventSource.BuildFinished -= BuildFinished; - EventSource.ProjectFinished -= ProjectFinished; - EventSource.TaskFinished -= TaskFinished; - EventSource.TargetFinished -= TargetFinished; + Server.AnyEventRaised -= EventRaised; Disposed = true; } } diff --git a/src/Buildalyzer/BuildTracer.cs b/src/Buildalyzer/BuildTracer.cs deleted file mode 100644 index 383ab185..00000000 --- a/src/Buildalyzer/BuildTracer.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.Collections.Concurrent; -using Buildalyzer.IO; -using Microsoft.Build.Framework; - -namespace Buildalyzer; - -public sealed class BuildTracer : IDisposable -{ - private readonly IEventSource EventSource; - - public ConcurrentBag Events { get; } = []; - - public ConcurrentBag> Paths { get; } = []; - public ConcurrentBag> Properties { get; } = []; - public ConcurrentBag> Items { get; } = []; - - public ConcurrentBag> Commands { get; } = []; - - public BuildTracer(IEventSource eventSource) - { - EventSource = Guard.NotNull(eventSource); - - EventSource.BuildStarted += BuildStarted; - EventSource.ProjectStarted += ProjectStarted; - EventSource.TaskStarted += TaskStarted; - EventSource.TargetStarted += TargetStarted; - - EventSource.CustomEventRaised += CustomEventRaised; - EventSource.MessageRaised += MessageRaised; - EventSource.ErrorRaised += ErrorRaised; - EventSource.StatusEventRaised += StatusEventRaised; - - EventSource.BuildFinished += BuildFinished; - EventSource.ProjectFinished += ProjectFinished; - EventSource.TaskFinished += TaskFinished; - EventSource.TargetFinished += TargetFinished; - } - - private void TaskStarted(object? sender, TaskStartedEventArgs e) - { - Events.Add(e); - } - - private void TargetStarted(object? sender, TargetStartedEventArgs e) - { - Events.Add(e); - } - - private void TargetFinished(object? sender, TargetFinishedEventArgs e) - { - Events.Add(e); - } - - private void ProjectStarted(object? sender, ProjectStartedEventArgs e) - { - Events.Add(e); - - var path = IOPath.Parse(e.ProjectFile); - var properties = CompilerProperties.FromDictionaryEntries(e.Properties); - var items = CompilerItemsCollection.FromDictionaryEntries(e.Items); - - Paths.Add(KeyValuePair.Create(e.BuildEventContext, path)); - Properties.Add(KeyValuePair.Create(e.BuildEventContext, properties)); - Items.Add(KeyValuePair.Create(e.BuildEventContext, items)); - } - - private void MessageRaised(object? sender, BuildMessageEventArgs e) - { - Events.Add(e); - - var path = Paths.First(p => p.Key.ProjectInstanceId == e.BuildEventContext.ProjectInstanceId); - - var dir = path.Value.File().Directory; - - var command = e switch - { - TaskCommandLineEventArgs a when a.SenderName.IsMatch("Csc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.CSharp), - TaskCommandLineEventArgs a when a.SenderName.IsMatch("Vbc") => Compiler.CommandLine.Parse(dir, a.CommandLine, CompilerLanguage.VisualBasic), - _ when e.SenderName.IsMatch("Fsc") => Compiler.CommandLine.Parse(dir, e.Message, CompilerLanguage.FSharp), - _ => null, - }; - - if (command is { }) - { - Commands.Add(KeyValuePair.Create(e.BuildEventContext, command)); - } - } - - private void StatusEventRaised(object? sender, BuildStatusEventArgs e) - { - Events.Add(e); - } - - private void BuildStarted(object? sender, BuildStartedEventArgs e) - { - Events.Add(e); - } - - private void ErrorRaised(object? sender, BuildErrorEventArgs e) - { - Events.Add(e); - } - - private void CustomEventRaised(object? sender, CustomBuildEventArgs e) - { - Events.Add(e); - } - - private void TaskFinished(object? sender, TaskFinishedEventArgs e) - { - Events.Add(e); - } - - private void ProjectFinished(object? sender, ProjectFinishedEventArgs e) - { - Events.Add(e); - } - - private void BuildFinished(object? sender, BuildFinishedEventArgs e) - { - Events.Add(e); - } - - public void Dispose() - { - if (!Disposed) - { - EventSource.BuildStarted -= BuildStarted; - EventSource.ProjectStarted -= ProjectStarted; - EventSource.TaskStarted -= TaskStarted; - EventSource.TargetStarted -= TargetStarted; - - EventSource.CustomEventRaised -= CustomEventRaised; - EventSource.MessageRaised -= MessageRaised; - EventSource.ErrorRaised -= ErrorRaised; - EventSource.StatusEventRaised -= StatusEventRaised; - - EventSource.BuildFinished -= BuildFinished; - EventSource.ProjectFinished -= ProjectFinished; - EventSource.TaskFinished -= TaskFinished; - EventSource.TargetFinished -= TargetFinished; - Disposed = true; - } - } - - private bool Disposed; -} diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index e5409e46..976a9e26 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -161,7 +161,7 @@ void OnPipeLoggerOnAnyEventRaised(object o, BuildEventArgs buildEventArgs) pipeLogger.AnyEventRaised += OnPipeLoggerOnAnyEventRaised; - using var tracer = new BuildTracer(pipeLogger); + using var collector = new BuildEventCollector(pipeLogger); using var eventProcessor = new EventProcessor(Manager, this, BuildLoggers, pipeLogger, results != null); @@ -205,6 +205,8 @@ void OnProcessRunnerExited() // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); + + var events = collector.ToImmutableArray(); } return results; } From fb8b52faa9cf901f981eea5f57f7d332b95e8248 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 11:25:11 +0200 Subject: [PATCH 08/10] Rollback --- src/Buildalyzer/Extensions/String.cs | 7 ------- src/Buildalyzer/IO/IOPath.cs | 4 ---- 2 files changed, 11 deletions(-) delete mode 100644 src/Buildalyzer/Extensions/String.cs diff --git a/src/Buildalyzer/Extensions/String.cs b/src/Buildalyzer/Extensions/String.cs deleted file mode 100644 index 851cdb04..00000000 --- a/src/Buildalyzer/Extensions/String.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace System; - -internal static class BuildalyzerStringExtensions -{ - public static bool IsMatch(this string? str, string? other) - => string.Equals(str, other, StringComparison.OrdinalIgnoreCase); -} diff --git a/src/Buildalyzer/IO/IOPath.cs b/src/Buildalyzer/IO/IOPath.cs index 6dce0135..dd71ef71 100644 --- a/src/Buildalyzer/IO/IOPath.cs +++ b/src/Buildalyzer/IO/IOPath.cs @@ -52,10 +52,6 @@ public override bool Equals([NotNullWhen(true)] object? obj) public bool Equals(IOPath other, bool caseSensitive) => string.Equals(_path, other._path, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); - public static bool operator ==(IOPath left, IOPath right) => left.Equals(right); - - public static bool operator !=(IOPath left, IOPath right) => !(left == right); - /// [Pure] public override int GetHashCode() From 0208d72d55e333bc621bb7f85743591d62aac0f9 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 11:35:47 +0200 Subject: [PATCH 09/10] Rename. --- .../{BuildEventCollector.cs => BuildEventArgsCollector.cs} | 4 ++-- src/Buildalyzer/ProjectAnalyzer.cs | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) rename src/Buildalyzer/{BuildEventCollector.cs => BuildEventArgsCollector.cs} (85%) diff --git a/src/Buildalyzer/BuildEventCollector.cs b/src/Buildalyzer/BuildEventArgsCollector.cs similarity index 85% rename from src/Buildalyzer/BuildEventCollector.cs rename to src/Buildalyzer/BuildEventArgsCollector.cs index f5b8d64e..20e65bdd 100644 --- a/src/Buildalyzer/BuildEventCollector.cs +++ b/src/Buildalyzer/BuildEventArgsCollector.cs @@ -6,9 +6,9 @@ namespace Buildalyzer; [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(Diagnostics.CollectionDebugView))] -internal sealed class BuildEventCollector : IReadOnlyCollection, IDisposable +internal sealed class BuildEventArgsCollector : IReadOnlyCollection, IDisposable { - public BuildEventCollector(EventArgsDispatcher server) + public BuildEventArgsCollector(EventArgsDispatcher server) { Server = server; Server.AnyEventRaised += EventRaised; diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index 976a9e26..8fb3aa1f 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -161,8 +161,6 @@ void OnPipeLoggerOnAnyEventRaised(object o, BuildEventArgs buildEventArgs) pipeLogger.AnyEventRaised += OnPipeLoggerOnAnyEventRaised; - using var collector = new BuildEventCollector(pipeLogger); - using var eventProcessor = new EventProcessor(Manager, this, BuildLoggers, pipeLogger, results != null); // Run MSBuild @@ -205,8 +203,6 @@ void OnProcessRunnerExited() // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); - - var events = collector.ToImmutableArray(); } return results; } From 5dc85d7392e28aa78bd3f6fb2e35b992e5b54dfd Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Sun, 8 Sep 2024 11:44:55 +0200 Subject: [PATCH 10/10] rollback. --- src/Buildalyzer/ProjectAnalyzer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index 8fb3aa1f..cb75674f 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -1,5 +1,4 @@ using System.Collections.Concurrent; -using System.Diagnostics; using System.IO; using System.Threading; using Buildalyzer.Construction;