Last active
September 13, 2018 20:34
-
-
Save dhilgarth/2fb710f51d20767ccb1a3c25e4b6e412 to your computer and use it in GitHub Desktop.
Facade to read GitVersionInformation injected by GitTools\GitVersion MSBuild task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text.RegularExpressions; | |
namespace ReadGitVersionInformation | |
{ | |
public interface IGitVersionInformation | |
{ | |
string Major { get; } | |
string Minor { get; } | |
string Patch { get; } | |
string PreReleaseTag { get; } | |
string PreReleaseTagWithDash { get; } | |
string PreReleaseLabel { get; } | |
string PreReleaseNumber { get; } | |
string BuildMetaData { get; } | |
string BuildMetaDataPadded { get; } | |
string FullBuildMetaData { get; } | |
string MajorMinorPatch { get; } | |
string SemVer { get; } | |
string LegacySemVer { get; } | |
string LegacySemVerPadded { get; } | |
string AssemblySemVer { get; } | |
string FullSemVer { get; } | |
string InformationalVersion { get; } | |
string BranchName { get; } | |
string Sha { get; } | |
string NuGetVersionV2 { get; } | |
string NuGetVersion { get; } | |
string CommitsSinceVersionSource { get; } | |
string CommitsSinceVersionSourcePadded { get; } | |
string CommitDate { get; } | |
} | |
public static class GitVersion | |
{ | |
private static readonly Dictionary<string, IGitVersionInformation> _cache = | |
new Dictionary<string, IGitVersionInformation>(); | |
public static IGitVersionInformation GetVersionInformation(bool fallbackToNormalVersion = true) => | |
GetVersionInformation(Assembly.GetCallingAssembly(), fallbackToNormalVersion); | |
public static IGitVersionInformation GetVersionInformation(Assembly assembly, bool fallbackToNormalVersion = true) | |
{ | |
var name = assembly.GetName(); | |
if (_cache.TryGetValue(name.FullName, out var cached)) | |
return cached; | |
var assemblyName = name.Name; | |
IGitVersionInformation result; | |
var gitVersionInformationType = assembly.GetType(assemblyName + ".GitVersionInformation"); | |
if (gitVersionInformationType == null) | |
{ | |
var informationalVersion = (AssemblyInformationalVersionAttribute)assembly | |
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false) | |
.SingleOrDefault(); | |
if (informationalVersion == null) | |
{ | |
if (fallbackToNormalVersion) | |
result = new TransparentFallback(assembly); | |
else | |
throw new NotAGitVersionAssemblyException(assemblyName); | |
} | |
else | |
result = new GitVersionInformationFromInformationalVersion(informationalVersion.InformationalVersion); | |
} | |
else | |
result = new GitVersionInformationFromClass(gitVersionInformationType.GetFields()); | |
_cache.Add(name.FullName, result); | |
return result; | |
} | |
} | |
public class NotAGitVersionAssemblyException : Exception | |
{ | |
public NotAGitVersionAssemblyException(string assemblyName) | |
: base($"The specified assembly '{assemblyName}' does not contain GitVersion information.") => | |
AssemblyName = assemblyName; | |
public string AssemblyName { get; } | |
} | |
internal class GitVersionInformationFromClass : IGitVersionInformation | |
{ | |
private readonly Dictionary<string, string> _values; | |
public GitVersionInformationFromClass(IEnumerable<FieldInfo> fields) | |
{ | |
if (fields == null) | |
throw new ArgumentNullException(nameof(fields)); | |
_values = fields.ToDictionary(x => x.Name, x => (string)x.GetValue(null)); | |
} | |
public string Major => GetFieldValue("Major"); | |
public string Minor => GetFieldValue("Minor"); | |
public string Patch => GetFieldValue("Patch"); | |
public string PreReleaseTag => GetFieldValue("PreReleaseTag"); | |
public string PreReleaseTagWithDash => GetFieldValue("PreReleaseTagWithDash"); | |
public string PreReleaseLabel => GetFieldValue("PreReleaseLabel"); | |
public string PreReleaseNumber => GetFieldValue("PreReleaseNumber"); | |
public string BuildMetaData => GetFieldValue("BuildMetaData"); | |
public string BuildMetaDataPadded => GetFieldValue("BuildMetaDataPadded"); | |
public string FullBuildMetaData => GetFieldValue("FullBuildMetaData"); | |
public string MajorMinorPatch => GetFieldValue("MajorMinorPatch"); | |
public string SemVer => GetFieldValue("SemVer"); | |
public string LegacySemVer => GetFieldValue("LegacySemVer"); | |
public string LegacySemVerPadded => GetFieldValue("LegacySemVerPadded"); | |
public string AssemblySemVer => GetFieldValue("AssemblySemVer"); | |
public string FullSemVer => GetFieldValue("FullSemVer"); | |
public string InformationalVersion => GetFieldValue("InformationalVersion"); | |
public string BranchName => GetFieldValue("BranchName"); | |
public string Sha => GetFieldValue("Sha"); | |
public string NuGetVersionV2 => GetFieldValue("NuGetVersionV2"); | |
public string NuGetVersion => GetFieldValue("NuGetVersion"); | |
public string CommitsSinceVersionSource => GetFieldValue("CommitsSinceVersionSource"); | |
public string CommitsSinceVersionSourcePadded => GetFieldValue("CommitsSinceVersionSourcePadded"); | |
public string CommitDate => GetFieldValue("CommitDate"); | |
private string GetFieldValue(string fieldName) | |
{ | |
if (_values.TryGetValue(fieldName, out var value)) | |
return value; | |
throw new UnknownGitVersionAssemblyVersion(fieldName); | |
} | |
} | |
internal class GitVersionInformationFromInformationalVersion : IGitVersionInformation | |
{ | |
private static readonly Regex _regex = new Regex( | |
@"^(?<Major>\d?)\.(?<Minor>\d?)\.(?<Patch>\d?)-(?<PreReleaseLabel>[^.]+)\.(?<PreReleaseNumber>\d+)\+Branch\.(?<BranchName>[^.]+)\.Sha\.(?<Sha>[0-9a-z]+)$"); | |
public GitVersionInformationFromInformationalVersion(string informationalVersion) | |
{ | |
InformationalVersion = informationalVersion; | |
var match = _regex.Match(informationalVersion); | |
Major = match.Groups["Major"].Value; | |
Minor = match.Groups["Minor"].Value; | |
Patch = match.Groups["Patch"].Value; | |
PreReleaseLabel = match.Groups["PreReleaseLabel"].Value; | |
PreReleaseNumber = match.Groups["PreReleaseNumber"].Value; | |
BranchName = match.Groups["BranchName"].Value; | |
Sha = match.Groups["Sha"].Value; | |
} | |
public string Major { get; } | |
public string Minor { get; } | |
public string Patch { get; } | |
public string PreReleaseTag => $"{PreReleaseLabel}.{PreReleaseNumber}"; | |
public string PreReleaseTagWithDash => $"-{PreReleaseTag}"; | |
public string PreReleaseLabel { get; } | |
public string PreReleaseNumber { get; } | |
public string BuildMetaData => ""; | |
public string BuildMetaDataPadded => ""; | |
public string FullBuildMetaData => $"Branch.{BranchName}.Sha.{Sha}"; | |
public string MajorMinorPatch => $"{Major}.{Minor}.{Patch}"; | |
public string SemVer => $"{MajorMinorPatch}{PreReleaseTagWithDash}"; | |
public string LegacySemVer => $"{MajorMinorPatch}-{PreReleaseLabel}{PreReleaseNumber}"; | |
public string LegacySemVerPadded => $"{MajorMinorPatch}-{PreReleaseLabel}{CommitsSinceVersionSourcePadded}"; | |
public string AssemblySemVer => $"{MajorMinorPatch}.{PreReleaseNumber}"; | |
public string FullSemVer => SemVer; | |
public string InformationalVersion { get; } | |
public string BranchName { get; } | |
public string Sha { get; } | |
public string NuGetVersionV2 => LegacySemVerPadded; | |
public string NuGetVersion => LegacySemVerPadded; | |
public string CommitsSinceVersionSource => PreReleaseNumber; | |
public string CommitsSinceVersionSourcePadded => $"{PreReleaseNumber.PadLeft(4, '0')}"; | |
public string CommitDate => new DateTime().ToString("yyyy-dd-MM"); | |
} | |
internal class TransparentFallback : IGitVersionInformation | |
{ | |
public TransparentFallback(Assembly assembly) | |
{ | |
var version = assembly.GetName().Version; | |
Major = version.Major.ToString(); | |
Minor = version.Minor.ToString(); | |
Patch = version.Revision.ToString(); | |
PreReleaseNumber = version.Build.ToString(); | |
} | |
public string Major { get; } | |
public string Minor { get; } | |
public string Patch { get; } | |
public string PreReleaseTag => ""; | |
public string PreReleaseTagWithDash => ""; | |
public string PreReleaseLabel => ""; | |
public string PreReleaseNumber { get; } | |
public string BuildMetaData => ""; | |
public string BuildMetaDataPadded => ""; | |
public string FullBuildMetaData => SemVer; | |
public string MajorMinorPatch => $"{Major}.{Minor}.{Patch}"; | |
public string SemVer => $"{MajorMinorPatch}{PreReleaseTagWithDash}"; | |
public string LegacySemVer => SemVer; | |
public string LegacySemVerPadded => $"{MajorMinorPatch}{PreReleaseTagWithDash}{CommitsSinceVersionSourcePadded}"; | |
public string AssemblySemVer => $"{MajorMinorPatch}.{PreReleaseNumber}"; | |
public string FullSemVer => SemVer; | |
public string InformationalVersion => SemVer; | |
public string BranchName => ""; | |
public string Sha => ""; | |
public string NuGetVersionV2 => LegacySemVerPadded; | |
public string NuGetVersion => LegacySemVerPadded; | |
public string CommitsSinceVersionSource => PreReleaseNumber; | |
public string CommitsSinceVersionSourcePadded => $"{PreReleaseNumber.PadLeft(4, '0')}"; | |
public string CommitDate => new DateTime().ToString("yyyy-dd-MM"); | |
} | |
internal class UnknownGitVersionAssemblyVersion : Exception | |
{ | |
public UnknownGitVersionAssemblyVersion(string fieldName) | |
: base( | |
$"The field '{fieldName}' is not a known property of the automatically generated GitVersionInformation class. This most likely hints at a version mismatch.") => | |
FieldName = fieldName; | |
public string FieldName { get; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment