This repository has been archived by the owner on Jan 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 241
/
GenerateCurrentVersion.cs
149 lines (136 loc) · 6.07 KB
/
GenerateCurrentVersion.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
142
143
144
145
146
147
148
149
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Globalization;
using System.Text.RegularExpressions;
namespace Microsoft.DotNet.Build.Tasks
{
public sealed class GenerateCurrentVersion : BuildTask
{
/// <summary>
/// The passed in date that will be used to generate a version. (yyyy-MM-dd format)
/// </summary>
[Required]
public string SeedDate { get; set; }
/// <summary>
/// Optional parameter containing the Official Build Id. We'll use this to get the revision number out and use it as BuildNumberMinor.
/// </summary>
public string OfficialBuildId { get; set; }
/// <summary>
/// Optional parameter that sets the Padding for the version number. Must be 5 or bigger.
/// </summary>
public int Padding { get; set; }
/// <summary>
/// If basing off of internal builds version format is not required, this optional parameter lets you pass in a comparison date.
/// </summary>
public string ComparisonDate { get; set; }
/// <summary>
/// The Major Version that will be produced given a SeedDate.
/// </summary>
[Output]
public string GeneratedVersion { get; set; }
/// <summary>
/// The Revision number that will be produced from the BuildNumber.
/// </summary>
[Output]
public string GeneratedRevision { get; set; }
private const string DateFormat = "yyyy-MM-dd";
private const string LastModifiedTimeDateFormat = "yyyy-MM-dd HH:mm:ss.FFFFFFF";
private CultureInfo enUS = new CultureInfo("en-US");
public override bool Execute()
{
// If OfficialBuildId is passed in, then use that to calculate the version and revision.
if (string.IsNullOrEmpty(OfficialBuildId))
{
GeneratedRevision = "0";
}
else
{
bool success = SetVersionAndRevisionFromBuildId(OfficialBuildId);
return success;
}
// Calculating GeneratedVersion
if (Padding == 0)
{
Padding = 5;
}
else if (Padding < 5)
{
Log.LogWarning("The specified Padding '{0}' has to be equal to or greater than 5. Using 5 as a default now.", Padding);
Padding = 5;
}
DateTime date;
GeneratedVersion = string.Empty;
if (!(DateTime.TryParseExact(SeedDate, DateFormat, enUS, DateTimeStyles.AssumeLocal, out date)))
{
// Check if the timestamp matches the LastModifiedTimeDateFormat
if (!(DateTime.TryParseExact(SeedDate, LastModifiedTimeDateFormat, enUS, DateTimeStyles.AssumeLocal, out date)))
{
Log.LogError("The seed date '{0}' is not valid. Please specify a date in the short format.({1})", SeedDate, DateFormat);
return false;
}
}
//Convert Date to UTC to converge
date = date.ToUniversalTime();
GeneratedVersion = GetCurrentVersionForDate(date, ComparisonDate);
if (string.IsNullOrEmpty(GeneratedVersion))
{
Log.LogError("The date '{0}' is not valid. Please pass in a date after {1}.", SeedDate, ComparisonDate);
return false;
}
return true;
}
public bool SetVersionAndRevisionFromBuildId(string buildId)
{
Regex regex = new Regex(@"(\d{8})[\-\.](\d+)$");
string dateFormat = "yyyyMMdd";
Match match = regex.Match(buildId);
if (match.Success && match.Groups.Count > 2)
{
DateTime buildIdDate;
if (!DateTime.TryParseExact(match.Groups[1].Value, dateFormat, enUS, DateTimeStyles.AssumeLocal, out buildIdDate))
{
Log.LogError("The OfficialBuildId doesn't follow the expected({0}.rr) format: '{1}'", dateFormat, match.Groups[1].Value);
return false;
}
buildIdDate = buildIdDate.ToUniversalTime();
GeneratedVersion = GetCurrentVersionForDate(buildIdDate, ComparisonDate);
GeneratedRevision = match.Groups[2].Value;
return true;
}
Log.LogError("Error: Invalid OfficialBuildId was passed: '{0}'", buildId);
return false;
}
public string GetCurrentVersionForDate(DateTime seedDate, string comparisonDate)
{
DateTime compareDate;
if (string.IsNullOrEmpty(comparisonDate))
{
/*
* We need to ensure that our build numbers are higher that what we used to ship internal builds so this date
* will make that possible.
*/
compareDate = new DateTime(1996, 4, 1, 0, 0, 0, DateTimeKind.Utc);
}
else
{
bool isValidDate = DateTime.TryParseExact(comparisonDate, DateFormat, enUS, DateTimeStyles.AssumeLocal, out compareDate);
if (!isValidDate)
{
Log.LogError("The comparison date '{0}' is not valid. Please specify a date in the short format.({1})", comparisonDate, DateFormat);
}
//Convert to UTC to converge
compareDate = compareDate.ToUniversalTime();
}
int months = (seedDate.Year - compareDate.Year) * 12 + seedDate.Month - compareDate.Month;
if (months > 0) //only allow dates after comparedate
{
return string.Format("{0}{1}", months.ToString("D" + (Padding -2)), seedDate.Day.ToString("D2"));
}
return string.Empty;
}
}
}