Skip to content

Commit

Permalink
This is version 0.0.4.
Browse files Browse the repository at this point in the history
Change the API to a more functional one.
  • Loading branch information
teo-tsirpanis committed Apr 4, 2020
1 parent 43c931f commit 3f74b28
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 53 deletions.
7 changes: 4 additions & 3 deletions Sigourney/MSBuildWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Mono.Cecil;
using Serilog;

namespace Sigourney
Expand Down Expand Up @@ -35,9 +36,9 @@ public abstract class MSBuildWeaver: Task
public string? OutputPath { get; set; }

/// <summary>
/// The instance of the weaver to be used.
/// Modifies the assembly.
/// </summary>
protected abstract Weaver CreateWeaver();
protected abstract bool DoWeave(AssemblyDefinition asm);

/// <inheritdoc cref="Task.Execute"/>
public override bool Execute()
Expand All @@ -48,7 +49,7 @@ public override bool Execute()
.CreateLogger();
try
{
CreateWeaver().Weave(AssemblyPath, OutputPath, log, new WeaverConfig(SigourneyConfig));
Weaver.Weave(AssemblyPath, OutputPath, DoWeave, log, new WeaverConfig(SigourneyConfig));
return !Log.HasLoggedErrors;
}
catch (Exception e)
Expand Down
5 changes: 3 additions & 2 deletions Sigourney/Sigourney.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<PropertyGroup>
<PackageId>Sigourney</PackageId>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<Version>0.0.3</Version>
<PackageReleaseNotes>Third test release.</PackageReleaseNotes>
<Version>0.0.4</Version>
<PackageReleaseNotes>Fourth test release.</PackageReleaseNotes>
<Authors>Theodore Tsirpanis</Authors>
<Copyright>Copyright © Theodore Tsirpanis. Licensed under the MIT License. Contains some code from Fody, which is licensed under the MIT License as well.</Copyright>
<PackageProjectUrl>https://github.com/teo-tsirpanis/Sigourney</PackageProjectUrl>
Expand All @@ -19,6 +19,7 @@
</PropertyGroup>
<ItemGroup>
<None Include="Sigourney.targets" Pack="true" PackagePath="build" />
<None Include="buildMultiTargeting/Sigourney.targets" Pack="true" PackagePath="buildMultiTargeting" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
Expand Down
22 changes: 11 additions & 11 deletions Sigourney/StrongNameKeyFinder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Theodore Tsirpanis
//
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

Expand All @@ -15,13 +15,13 @@

namespace Sigourney
{
public partial class Weaver
internal static class StrongNameKeyFinder
{
private StrongNameKeyPair? _keyPair;
private byte[]? _publicKey;

private void FindStrongNameKey(WeaverConfig config, AssemblyDefinition asm, ILogger log)
internal static void FindStrongNameKey(WeaverConfig config, AssemblyDefinition asm, ILogger log,
out StrongNameKeyPair? keyPair, out byte[]? publicKey)
{
keyPair = null;
publicKey = null;
if (!config.SignAssembly)
{
return;
Expand All @@ -34,21 +34,21 @@ private void FindStrongNameKey(WeaverConfig config, AssemblyDefinition asm, ILog
throw new FileNotFoundException("KeyFilePath was defined but file does not exist.", keyFilePath);

var fileBytes = File.ReadAllBytes(keyFilePath);
_keyPair = new StrongNameKeyPair(fileBytes);
keyPair = new StrongNameKeyPair(fileBytes);

try
{
_publicKey = _keyPair.PublicKey;
publicKey = keyPair.PublicKey;
}
catch (ArgumentException e)
{
log.Debug(e, "Exception while trying to load strong-name key pair.");
_keyPair = null;
_publicKey = fileBytes;
keyPair = null;
publicKey = fileBytes;
}
}

private string? GetKeyFilePath(WeaverConfig config, AssemblyDefinition asm, ILogger log)
private static string? GetKeyFilePath(WeaverConfig config, AssemblyDefinition asm, ILogger log)
{
var keyFilePath = config.KeyFilePath;
if (keyFilePath != null)
Expand Down
66 changes: 29 additions & 37 deletions Sigourney/Weaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

using System;
using System.IO;
using System.Reflection;
using JetBrains.Annotations;
Expand All @@ -14,56 +15,67 @@ namespace Sigourney
/// <summary>
/// An abstract class for a procedure that modifies (weaves) a .NET assembly.
/// </summary>
/// <remarks>Yes, I know about the type's fully qualified name...</remarks>
/// <remarks>The type's fully qualified name does not imply an endorsement
/// or support of any kind whatsoever.</remarks>
[PublicAPI]
public abstract partial class Weaver
public static class Weaver
{
private readonly string _version;

/// <summary>
/// Creates a <see cref="Weaver"/>.
/// </summary>
protected Weaver()
private static string GetAssemblyVersion(Assembly asm)
{
var ownerAssembly = GetType().Assembly;
_version = ownerAssembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
?.InformationalVersion ?? ownerAssembly.GetName().Version.ToString();
return asm.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
?.InformationalVersion ?? asm.GetName().Version.ToString();
}

/// <summary>
/// Weaves an assembly.
/// </summary>
/// <remarks>If weaving succeeds, a static class named "ProcessedBy<see cref="ProductName"/>"
/// <remarks>If weaving succeeds, a static class named "ProcessedBy<paramref name="productName"/>"
/// will be presented to instruct Sigourney not to weave it again.</remarks>
/// <param name="inputPath">The path of the assembly to weave.</param>
/// <param name="outputPath">The path where the weaved assembly will be stored.
/// Defaults to <paramref name="inputPath"/> if null.</param>
/// <param name="fWeave">A function that accepts an <see cref="AssemblyDefinition"/>
/// and returns whether it was actually modified (returning <see langword="false"/>
/// will not write it to disk).</param>
/// <param name="log">A Serilog <see cref="ILogger"/> that will
/// record any events that happen in the weaver.</param>
/// <param name="config">An <see cref="WeaverConfig"/> object to
/// <param name="config">A <see cref="WeaverConfig"/> object to
/// further parameterize the weaving process.</param>
public void Weave(string inputPath, string? outputPath, ILogger log, WeaverConfig config)
/// <param name="productName">The name of the program that weaved the assembly.
/// If not specified, it will be the name of the assembly in which <paramref name="fWeave"/>
/// was declared.</param>
public static void Weave(string inputPath, string? outputPath,
Converter<AssemblyDefinition, bool> fWeave, ILogger log, WeaverConfig config,
string? productName = null)
{
// The declaring type is null on "global module functions",
// something I don't think it can happen with the known .NETt languages.
var weaverAssembly = fWeave.Method.DeclaringType?.Assembly ?? Assembly.GetCallingAssembly();
var productNameActual = productName ?? weaverAssembly.GetName().Name;
var assemblyVersion = GetAssemblyVersion(weaverAssembly);
using var resultingAsembly = new MemoryStream();
using (var asm = AssemblyDefinition.ReadAssembly(inputPath))
{
var assemblyName = asm.Name.Name;
FindStrongNameKey(config, asm, log);
StrongNameKeyFinder.FindStrongNameKey(config, asm, log, out var keyPair, out var publicKey);

if (AssemblyMarker.ShouldProcess(asm, ProductName))
if (AssemblyMarker.ShouldProcess(asm, productNameActual))
{
if (!DoWeave(asm, log, config))
if (!fWeave(asm))
{
log.Debug("Skipping weaving {AssemblyName} as requested.", assemblyName);
return;
}

AssemblyMarker.MarkAsProcessed(asm, ProductName, _version, log);
AssemblyMarker.MarkAsProcessed(asm, productNameActual, assemblyVersion, log);
var writerParams = new WriterParameters
{
StrongNameKeyPair = _keyPair
StrongNameKeyPair = keyPair
};
asm.Name.PublicKey = _publicKey;
asm.Name.PublicKey = publicKey;
asm.Write(resultingAsembly, writerParams);
}
else
Expand All @@ -76,25 +88,5 @@ public void Weave(string inputPath, string? outputPath, ILogger log, WeaverConfi
resultingAsembly.Position = 0;
resultingAsembly.CopyTo(outputFile);
}

/// <summary>
/// Gets an informative name of the weaver.
/// </summary>
/// <remarks>Defaults to the name of the assembly
/// the weaver's class was defined.</remarks>
protected virtual string ProductName => GetType().Assembly.GetName().Name;

/// <summary>
/// Performs the actual weaving using Mono.Cecil.
/// </summary>
/// <param name="asm">The assembly to modify in an <see cref="AssemblyDefinition"/> format.</param>
/// <param name="log">A Serilog <see cref="ILogger"/> that will
/// record any events that happen in the weaver.</param>
/// <param name="config">An <see cref="WeaverConfig"/> object to
/// further parameterize the weaving process.</param>
/// <returns>Whether weaving actually happened. The weaver might
/// determine that weaving is unnecessary for this assembly
/// and Sigourney will skip modifying it entirely.</returns>
protected abstract bool DoWeave(AssemblyDefinition asm, ILogger log, WeaverConfig config);
}
}

0 comments on commit 3f74b28

Please sign in to comment.