-
Notifications
You must be signed in to change notification settings - Fork 0
/
versioning.cake
141 lines (115 loc) · 4.87 KB
/
versioning.cake
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
using System.Text.RegularExpressions;
public class BuildVersion
{
private ISetupContext _context;
// TODO: Get GitVersion to work on Linux
private GitVersion _gitVersion;
// NOTE: This is complicated because (1) the user may have specified
// the package version on the command-line and (2) GitVersion may
// or may not be available. We'll work on solving (2) by getting
// GitVersion to run for us on Linux, but (1) will alwas remain.
//
// We simplify things a by figuring out the full package version and
// then parsing it to provide information that is used in the build.
public BuildVersion(ISetupContext context)
{
_context = context;
_gitVersion = context.GitVersion();
BranchName = _gitVersion.BranchName;
IsReleaseBranch = BranchName.StartsWith("release-");
string packageVersion = context.HasArgument("packageVersion")
? context.Argument<string>("packageVersion")
: CalculatePackageVersion();
int dash = packageVersion.IndexOf('-');
IsPreRelease = dash > 0;
string versionPart = packageVersion;
string suffix = "";
string label = "";
if (IsPreRelease)
{
versionPart = packageVersion.Substring(0, dash);
suffix = packageVersion.Substring(dash + 1);
foreach (char c in suffix)
{
if (!char.IsLetter(c))
break;
label += c;
}
}
Version version = new Version(versionPart);
SemVer = version.ToString(3);
PreReleaseLabel = label;
PreReleaseSuffix = suffix;
PackageVersion = packageVersion;
AssemblyVersion = SemVer + ".0";
AssemblyFileVersion = SemVer;
AssemblyInformationalVersion = packageVersion;
}
public string BranchName { get; }
public bool IsReleaseBranch { get; }
public string PackageVersion { get; }
public string AssemblyVersion { get; }
public string AssemblyFileVersion { get; }
public string AssemblyInformationalVersion { get; }
public string SemVer { get; }
public bool IsPreRelease { get; }
public string PreReleaseLabel { get; }
public string PreReleaseSuffix { get; }
private string CalculatePackageVersion()
{
string label = _gitVersion.PreReleaseLabel;
// Non pre-release is easy
if (string.IsNullOrEmpty(label))
return _gitVersion.MajorMinorPatch;
string branchName = _gitVersion.BranchName;
// We don't currently use this pattern, but check in case we do later.
if (branchName.StartsWith("feature/"))
branchName = branchName.Substring(8);
// Arbitrary branch names are ci builds
if (label == branchName)
label = "ci";
string suffix = "-" + label + _gitVersion.CommitsSinceVersionSourcePadded;
switch (label)
{
case "ci":
branchName = Regex.Replace(branchName, "[^0-9A-Za-z-]+", "-");
suffix += "-" + branchName;
// Nuget limits "special version part" to 20 chars. Add one for the hyphen.
if (suffix.Length > 21)
suffix = suffix.Substring(0, 21);
return _gitVersion.MajorMinorPatch + suffix;
case "dev":
case "pre":
return _gitVersion.MajorMinorPatch + suffix;
case "pr":
return _gitVersion.LegacySemVerPadded;
case "rc":
case "alpha":
case "beta":
default:
return _gitVersion.LegacySemVer;
}
}
string ReplaceAttributeString(string source, string attributeName, string value)
{
var matches = Regex.Matches(source, $@"\[assembly: {Regex.Escape(attributeName)}\(""(?<value>[^""]+)""\)\]");
if (matches.Count != 1) throw new InvalidOperationException($"Expected exactly one line similar to:\r\n[assembly: {attributeName}(\"1.2.3-optional\")]");
var group = matches[0].Groups["value"];
return source.Substring(0, group.Index) + value + source.Substring(group.Index + group.Length);
}
void ReplaceFileContents(string filePath, Func<string, string> update)
{
using (var file = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
string source;
using (var reader = new StreamReader(file, new UTF8Encoding(false), true, 4096, leaveOpen: true))
source = reader.ReadToEnd();
var newSource = update.Invoke(source);
if (newSource == source) return;
file.Seek(0, SeekOrigin.Begin);
using (var writer = new StreamWriter(file, new UTF8Encoding(false), 4096, leaveOpen: true))
writer.Write(newSource);
file.SetLength(file.Position);
}
}
}