opentelemetry-dotnet-instru.../build/AssemblyRedirectionSourceGe...

98 lines
3.2 KiB
C#

using System.Text;
using Mono.Cecil;
using Serilog;
public static class AssemblyRedirectionSourceGenerator
{
public static void Generate(string assembliesFolderPath, string generatedFilePath)
{
Log.Debug("Generating assembly redirection file {0}", generatedFilePath);
var assemblies = new SortedDictionary<string, AssemblyNameDefinition>();
foreach (var fileName in Directory.EnumerateFiles(assembliesFolderPath))
{
try
{
using var moduleDef = ModuleDefinition.ReadModule(fileName);
var assemblyDef = moduleDef.Assembly.Name!;
if (assemblyDef.Name == "netstandard")
{
// Skip netstandard, since it doesn't need redirection.
continue;
}
assemblies[assemblyDef.Name] = assemblyDef;
Log.Debug("Adding {0} assembly to the redirection map. Targeted version {1}", assemblyDef.Name, assemblyDef.Version);
}
catch (BadImageFormatException)
{
Log.Debug("Skipping \"{0}\" couldn't open it as a managed assembly", fileName);
}
}
var sourceContents = GenerateSourceContents(assemblies);
File.WriteAllText(generatedFilePath, sourceContents);
Log.Information("Assembly redirection source generated {0}", generatedFilePath);
}
private static string GenerateSourceContents(SortedDictionary<string, AssemblyNameDefinition> assemblies)
{
#pragma warning disable format
return
$$"""
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
// Auto-generated file, do not change it - generated by the {{nameof(AssemblyRedirectionSourceGenerator)}} type
#include "cor_profiler.h"
#ifdef _WIN32
#define STR(Z1) #Z1
#define AUTO_MAJOR STR(OTEL_AUTO_VERSION_MAJOR)
namespace trace
{
void CorProfiler::InitNetFxAssemblyRedirectsMap()
{
const USHORT auto_major = atoi(AUTO_MAJOR);
assembly_version_redirect_map_.insert({
{{GenerateEntries(assemblies)}}
});
}
}
#endif
""";
#pragma warning restore format
}
private static string GenerateEntries(SortedDictionary<string, AssemblyNameDefinition> assemblies)
{
var longLineLength = 80;
var sb = new StringBuilder(assemblies.Count * longLineLength);
foreach (var kvp in assemblies)
{
var v = kvp.Value.Version!;
if (kvp.Key != "OpenTelemetry.AutoInstrumentation")
{
sb.AppendLine($" {{ L\"{kvp.Key}\", {{{v.Major}, {v.Minor}, {v.Build}, {v.Revision}}} }},");
}
else
{
sb.AppendLine($" {{ L\"{kvp.Key}\", {{auto_major, 0, 0, 0}} }},");
}
}
return sb.ToString()
.AsSpan() // Optimisation for following string manipulations
.Trim() // Remove whitespaces
.TrimEnd(',') // Remove trailing comma
.ToString();
}
}