/
GenerateVersionFile.cs
141 lines (116 loc) · 5.54 KB
/
GenerateVersionFile.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Xenko.GitVersioning
{
public class GenerateVersionFile : Task
{
/// <summary>
/// Gets or sets the version file.
/// </summary>
/// <value>The version file.</value>
[Required]
public ITaskItem VersionFile { get; set; }
/// <summary>
/// The output file for the version information.
/// </summary>
[Required]
public ITaskItem GeneratedVersionFile { get; set; }
/// <summary>
/// Gets or sets the root directory.
/// </summary>
[Required]
public ITaskItem RootDirectory { get; set; }
[Output]
public string NuGetVersion { get; set; }
public string SpecialVersion { get; set; }
public bool SpecialVersionGitHeight { get; set; }
public bool SpecialVersionGitCommit { get; set; }
public override bool Execute()
{
if (RootDirectory == null || !Directory.Exists(RootDirectory.ItemSpec))
{
Log.LogError("PackageFile is not set or doesn't exist");
return false;
}
if (VersionFile == null || !File.Exists(Path.Combine(RootDirectory.ItemSpec, VersionFile.ItemSpec)))
{
Log.LogError("VersionFile is not set or doesn't exist");
return false;
}
if (GeneratedVersionFile == null)
{
Log.LogError("OutputVersionFile is not set");
return false;
}
var currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
var mainPlatformDirectory = Path.GetFileName(Path.GetDirectoryName(currentAssemblyLocation));
// TODO: Right now we patch the VersionFile, but ideally we should make a copy and make the build system use it
var versionFileData = File.ReadAllText(Path.Combine(RootDirectory.ItemSpec, VersionFile.ItemSpec));
var publicVersionMatch = Regex.Match(versionFileData, "PublicVersion = \"(.*)\";");
var publicVersion = publicVersionMatch.Success ? publicVersionMatch.Groups[1].Value : "0.0.0.0";
// Patch NuGetVersion
var versionSuffix = SpecialVersion ?? string.Empty;
EnsureLibGit2UnmanagedInPath(mainPlatformDirectory);
// Compute Git Height using Nerdbank.GitVersioning
// For now we assume top level package directory is git folder
try
{
var rootDirectory = RootDirectory.ItemSpec;
var repo = LibGit2Sharp.Repository.IsValid(rootDirectory) ? new LibGit2Sharp.Repository(rootDirectory) : null;
if (repo == null)
{
Log.LogError("Could not open Git repository");
return false;
}
// Patch AssemblyInformationalVersion
var headCommitSha = repo.Head.Commits.FirstOrDefault()?.Sha;
if (SpecialVersionGitHeight)
{
// Compute version based on Git info
var height = Nerdbank.GitVersioning.GitExtensions.GetVersionHeight(repo, VersionFile.ItemSpec);
versionSuffix += height.ToString("D4");
}
// Replace NuGetVersionSuffix
versionFileData = Regex.Replace(versionFileData, "NuGetVersionSuffix = \"(.*)\";", $"NuGetVersionSuffix = \"$1{versionSuffix}\";");
// Always include git commit (even if not part of NuGetVersionSuffix)
if (SpecialVersionGitCommit && headCommitSha != null)
{
// Replace build metadata
versionFileData = Regex.Replace(versionFileData, "BuildMetadata = (.*);", $"BuildMetadata = \"+g{headCommitSha.Substring(0, 8)}\";");
}
// Write back new file
File.WriteAllText(Path.Combine(RootDirectory.ItemSpec, GeneratedVersionFile.ItemSpec), versionFileData);
NuGetVersion = publicVersion + versionSuffix;
return true;
}
catch (Exception e)
{
NuGetVersion = publicVersion + versionSuffix;
Log.LogWarning($"Could not determine version using git history: {e}", e);
return false;
}
}
private static void EnsureLibGit2UnmanagedInPath(string mainPlatformDirectory)
{
// On .NET Framework (on Windows), we find native binaries by adding them to our PATH.
var libgit2Directory = Nerdbank.GitVersioning.GitExtensions.FindLibGit2NativeBinaries(mainPlatformDirectory);
if (libgit2Directory != null)
{
string pathEnvVar = Environment.GetEnvironmentVariable("PATH");
string[] searchPaths = pathEnvVar.Split(Path.PathSeparator);
if (!searchPaths.Contains(libgit2Directory, StringComparer.OrdinalIgnoreCase))
{
pathEnvVar += Path.PathSeparator + libgit2Directory;
Environment.SetEnvironmentVariable("PATH", pathEnvVar);
}
}
}
}
}