diff --git a/src/Draco.Coverage.MSBuild/CoverageWeaveTask.cs b/src/Draco.Coverage.MSBuild/CoverageWeaveTask.cs index aecfba91a..37d8eb720 100644 --- a/src/Draco.Coverage.MSBuild/CoverageWeaveTask.cs +++ b/src/Draco.Coverage.MSBuild/CoverageWeaveTask.cs @@ -31,23 +31,7 @@ public override bool Execute() return true; } - private void Weave(string inputPath, string outputPath) - { - if (inputPath != outputPath) - { - using var readerStream = File.OpenRead(inputPath); - using var writerStream = File.OpenWrite(outputPath); - InstrumentedAssembly.Weave(readerStream, writerStream); - } - else - { - // We use memory streams to avoid locking the file - using var readerStream = new MemoryStream(File.ReadAllBytes(inputPath)); - using var writerStream = new MemoryStream(); - InstrumentedAssembly.Weave(readerStream, writerStream); - File.WriteAllBytes(outputPath, writerStream.ToArray()); - } - } + private void Weave(string inputPath, string outputPath) => InstrumentedAssembly.Weave(inputPath, outputPath); // MSBuild passes in the path to all binaries copied, concatenated with a semocilon // We need to split them and filter for .dll files diff --git a/src/Draco.Coverage/InstrumentationWeaver.cs b/src/Draco.Coverage/InstrumentationWeaver.cs index d8fa15104..6e7089bd2 100644 --- a/src/Draco.Coverage/InstrumentationWeaver.cs +++ b/src/Draco.Coverage/InstrumentationWeaver.cs @@ -15,6 +15,28 @@ namespace Draco.Coverage; /// internal sealed class InstrumentationWeaver { + /// + /// Weaves the instrumentation code into the specified assembly. + /// + /// The path to the assembly that should be weaved. + /// The path to write the weaved assembly to. + /// The settings for the weaver. + public static void WeaveInstrumentationCode( + string sourcePath, + string targetPath, + InstrumentationWeaverSettings? settings = null) + { + var readerParameters = new ReaderParameters { ReadSymbols = true }; + using var targetStream = new MemoryStream(); + // NOTE: We don't fall-back to the stream-based method here, because Cecil needs the path of the assembly to read the symbols + using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(sourcePath, readerParameters)) + { + WeaveInstrumentationCode(assemblyDefinition, targetStream, settings); + } + + File.WriteAllBytes(targetPath, targetStream.ToArray()); + } + /// /// Weaves the instrumentation code into the specified assembly. /// @@ -25,11 +47,19 @@ public static void WeaveInstrumentationCode( Stream targetStream, InstrumentationWeaverSettings? settings = null) { - settings ??= InstrumentationWeaverSettings.Default; - var readerParameters = new ReaderParameters { ReadSymbols = true }; using var assemblyDefinition = AssemblyDefinition.ReadAssembly(sourceStream, readerParameters); + WeaveInstrumentationCode(assemblyDefinition, targetStream, settings); + } + + private static void WeaveInstrumentationCode( + AssemblyDefinition assemblyDefinition, + Stream targetStream, + InstrumentationWeaverSettings? settings = null) + { + settings ??= InstrumentationWeaverSettings.Default; + var weaver = new InstrumentationWeaver(assemblyDefinition.MainModule, settings); weaver.WeaveModule(); diff --git a/src/Draco.Coverage/InstrumentedAssembly.cs b/src/Draco.Coverage/InstrumentedAssembly.cs index ccad86ac3..35aad859c 100644 --- a/src/Draco.Coverage/InstrumentedAssembly.cs +++ b/src/Draco.Coverage/InstrumentedAssembly.cs @@ -11,6 +11,15 @@ namespace Draco.Coverage; /// public sealed class InstrumentedAssembly : IDisposable { + /// + /// Weaves instrumentation code into the given assembly. + /// + /// The path to the assembly to weave. + /// The path to write the weaved assembly to. + /// The settings for the weaver. + public static void Weave(string sourcePath, string targetPath, InstrumentationWeaverSettings? settings = null) => + InstrumentationWeaver.WeaveInstrumentationCode(sourcePath, targetPath, settings); + /// /// Weaves instrumentation code into the given assembly. ///