Skip to content

Commit 8b439a9

Browse files
committed
tagged version wins even if MinVerMinimumMajorMinor is higher
1 parent 2e48c6e commit 8b439a9

File tree

6 files changed

+103
-21
lines changed

6 files changed

+103
-21
lines changed

MinVer.Lib/Versioner.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,40 @@ public static Version GetVersion(string workDir, string tagPrefix, MajorMinor mi
1010

1111
var defaultPreReleaseIdentifiersList = defaultPreReleaseIdentifiers.ToList();
1212

13-
var (version, height) = GetVersion(workDir, tagPrefix, defaultPreReleaseIdentifiersList, log);
13+
var (version, height, isFromTag) = GetVersion(workDir, tagPrefix, defaultPreReleaseIdentifiersList, log);
1414

1515
_ = height.HasValue && ignoreHeight && log.IsDebugEnabled && log.Debug("Ignoring height.");
1616
version = !height.HasValue || ignoreHeight ? version : version.WithHeight(height.Value, autoIncrement, defaultPreReleaseIdentifiersList);
1717

1818
version = version.AddBuildMetadata(buildMeta);
1919

20-
var calculatedVersion = version.Satisfying(minMajorMinor, defaultPreReleaseIdentifiersList);
20+
var ignoreMinMajorMinor = isFromTag && height is 0;
2121

22-
_ = calculatedVersion != version
23-
? log.IsInfoEnabled && log.Info($"Bumping version to {calculatedVersion} to satisfy minimum major minor {minMajorMinor}.")
24-
: log.IsDebugEnabled && log.Debug($"The calculated version {calculatedVersion} satisfies the minimum major minor {minMajorMinor}.");
22+
var calculatedVersion =
23+
ignoreMinMajorMinor
24+
? version.Satisfying(MajorMinor.Default, defaultPreReleaseIdentifiersList)
25+
: version.Satisfying(minMajorMinor, defaultPreReleaseIdentifiersList);
26+
27+
_ = ignoreMinMajorMinor
28+
? minMajorMinor != MajorMinor.Default && log.IsDebugEnabled && log.Debug($"Ignoring minimum major minor {minMajorMinor} because the commit is tagged.")
29+
: calculatedVersion != version
30+
? log.IsInfoEnabled && log.Info($"Bumping version to {calculatedVersion} to satisfy minimum major minor {minMajorMinor}.")
31+
: log.IsDebugEnabled && log.Debug($"The calculated version {calculatedVersion} satisfies the minimum major minor {minMajorMinor}.");
2532

2633
_ = log.IsInfoEnabled && log.Info($"Calculated version {calculatedVersion}.");
2734

2835
return calculatedVersion;
2936
}
3037

31-
private static (Version Version, int? Height) GetVersion(string workDir, string tagPrefix, List<string> defaultPreReleaseIdentifiers, ILogger log)
38+
private static (Version Version, int? Height, bool IsFromTag) GetVersion(string workDir, string tagPrefix, List<string> defaultPreReleaseIdentifiers, ILogger log)
3239
{
3340
if (!Git.IsWorkingDirectory(workDir, log))
3441
{
3542
var version = new Version(defaultPreReleaseIdentifiers);
3643

3744
_ = log.IsWarnEnabled && log.Warn(1001, $"'{workDir}' is not a valid Git working directory. Using default version {version}.");
3845

39-
return (version, default);
46+
return (version, default, default);
4047
}
4148

4249
if (!Git.TryGetHead(workDir, out var head, log))
@@ -45,7 +52,7 @@ private static (Version Version, int? Height) GetVersion(string workDir, string
4552

4653
_ = log.IsInfoEnabled && log.Info($"No commits found. Using default version {version}.");
4754

48-
return (version, default);
55+
return (version, default, default);
4956
}
5057

5158
var tags = Git.GetTags(workDir, log);
@@ -71,7 +78,7 @@ private static (Version Version, int? Height) GetVersion(string workDir, string
7178
_ = string.IsNullOrEmpty(selectedCandidate.Tag) && log.IsInfoEnabled && log.Info($"No commit found with a valid SemVer 2.0 version{(string.IsNullOrEmpty(tagPrefix) ? "" : $" prefixed with '{tagPrefix}'")}. Using default version {selectedCandidate.Version}.");
7279
_ = log.IsInfoEnabled && log.Info($"Using{(log.IsDebugEnabled && orderedCandidates.Count > 1 ? " " : " ")}{selectedCandidate.ToString(tagWidth, versionWidth, heightWidth)}.");
7380

74-
return (selectedCandidate.Version, selectedCandidate.Height);
81+
return (selectedCandidate.Version, selectedCandidate.Height, !string.IsNullOrEmpty(selectedCandidate.Tag));
7582
}
7683

7784
private static List<Candidate> GetCandidates(Commit head, IEnumerable<(string Name, string Sha)> tags, string tagPrefix, IReadOnlyCollection<string> defaultPreReleaseIdentifiers, ILogger log)

MinVerTests.Lib/LogMessages.cs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static class LogMessages
1313
[Theory]
1414
[InlineData(0, 0)]
1515
[InlineData(2, 0)]
16-
public static async Task RepoWithHistory(int minMajor, int minMinor)
16+
public static async Task MinimumMajorMinorAfterTag(int minMajor, int minMinor)
1717
{
1818
// arrange
1919
var minMajorMinor = new MajorMinor(minMajor, minMinor);
@@ -67,8 +67,52 @@ git checkout main
6767
_ = Versioner.GetVersion(path, "", minMajorMinor, "", default, PreReleaseIdentifiers.Default, false, log);
6868

6969
// assert
70-
var logMessages = log.ToString();
70+
var logMessages = await ReplaceShas(log.ToString(), path);
7171

72+
await AssertFile.Contains($"../../../log.{minMajorMinor}.txt", logMessages);
73+
}
74+
75+
[Theory]
76+
[InlineData(3, 0)]
77+
public static async Task MinimumMajorMinorOnTag(int minMajor, int minMinor)
78+
{
79+
// arrange
80+
var minMajorMinor = new MajorMinor(minMajor, minMinor);
81+
82+
var historicalCommands =
83+
@"
84+
git commit --allow-empty -m '.'
85+
git tag not-a-version
86+
git checkout -b foo
87+
git commit --allow-empty -m '.'
88+
git tag 1.0.0-foo.1
89+
";
90+
91+
var path = MethodBase.GetCurrentMethod().GetTestDirectory(minMajorMinor);
92+
93+
await EnsureEmptyRepository(path);
94+
95+
foreach (var item in historicalCommands
96+
.ToNonEmptyLines()
97+
.Select((command, index) => new { Command = command, Index = $"{index}", }))
98+
{
99+
var nameAndArgs = item.Command.Split(" ", 2);
100+
_ = await ReadAsync(nameAndArgs[0], nameAndArgs[1], path);
101+
}
102+
103+
var log = new TestLogger();
104+
105+
// act
106+
_ = Versioner.GetVersion(path, "", minMajorMinor, "", default, PreReleaseIdentifiers.Default, false, log);
107+
108+
// assert
109+
var logMessages = await ReplaceShas(log.ToString(), path);
110+
111+
await AssertFile.Contains($"../../../log.{minMajorMinor}.txt", logMessages);
112+
}
113+
114+
private static async Task<string> ReplaceShas(string logMessages, string path)
115+
{
72116
var shas = (await ReadAsync("git", "log --pretty=format:\"%H\"", path))
73117
.StandardOutput
74118
.ToNonEmptyLines()
@@ -85,6 +129,6 @@ git checkout main
85129
logMessages = logMessages.Replace(item.ShortSha, $"{item.Index}", StringComparison.Ordinal);
86130
}
87131

88-
await AssertFile.Contains($"../../../log.{minMajorMinor}.txt", logMessages);
132+
return logMessages;
89133
}
90134
}

MinVerTests.Lib/MinMajorMinor.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ public static async Task NoCommits()
2424
}
2525

2626
[Theory]
27-
[InlineData("4.0.0", 3, 2, "4.0.0", true)]
28-
[InlineData("4.3.0", 4, 3, "4.3.0", true)]
29-
[InlineData("4.3.0", 5, 4, "5.4.0-alpha.0", false)]
30-
public static async Task Tagged(string tag, int major, int minor, string expectedVersion, bool isRedundant)
27+
[InlineData("4.0.0", 3, 2, "4.0.0")]
28+
[InlineData("4.3.0", 4, 3, "4.3.0")]
29+
[InlineData("4.3.0", 5, 4, "4.3.0")]
30+
public static async Task Tagged(string tag, int major, int minor, string expectedVersion)
3131
{
3232
// arrange
3333
var path = MethodBase.GetCurrentMethod().GetTestDirectory((tag, major, minor));
@@ -41,10 +41,7 @@ public static async Task Tagged(string tag, int major, int minor, string expecte
4141
// assert
4242
Assert.Equal(expectedVersion, actualVersion.ToString());
4343

44-
if (isRedundant)
45-
{
46-
Assert.Contains(logger.Messages, message => message.Text.Contains($"The calculated version {actualVersion} satisfies the minimum major minor {major}.{minor}.", StringComparison.Ordinal));
47-
}
44+
Assert.Contains(logger.Messages, message => message.Text.Contains($"Ignoring minimum major minor {major}.{minor} because the commit is tagged.", StringComparison.Ordinal));
4845
}
4946

5047
[Fact]

MinVerTests.Lib/log.3.0.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Trace: Running Git: git status --short
2+
Trace: Git exit code: 0
3+
Trace: Git stdout:
4+
?? command-read-00.md
5+
?? command-read-01.md
6+
?? command-read-02.md
7+
?? command-read-03.md
8+
9+
Trace: Git stderr:
10+
11+
Trace: Running Git: git log --pretty=format:"%H %P"
12+
Trace: Git exit code: 0
13+
Trace: Git stdout:
14+
1 0
15+
0
16+
Trace: Git stderr:
17+
18+
Trace: Running Git: git show-ref --tags --dereference
19+
Trace: Git exit code: 0
20+
Trace: Git stdout:
21+
1 refs/tags/1.0.0-foo.1
22+
0 refs/tags/not-a-version
23+
24+
Trace: Git stderr:
25+
26+
Debug: Ignoring non-version tag { Name: not-a-version, Sha: 0 }.
27+
Trace: Checking commit 1 (height 0)...
28+
Trace: Found version tag { Commit: 1, Tag: '1.0.0-foo.1', Version: 1.0.0-foo.1, Height: 0 }.
29+
Debug: 1 commits checked.
30+
Info: Using { Commit: 1, Tag: '1.0.0-foo.1', Version: 1.0.0-foo.1, Height: 0 }.
31+
Debug: Ignoring minimum major minor 3.0 because the commit is tagged.
32+
Info: Calculated version 1.0.0-foo.1.

MinVerTests.Packages/MinimumMajorMinorOnTag.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static async Task HasMinimumMajorMinor()
1919

2020
var envVars = ("MinVerMinimumMajorMinor".ToAltCase(), "3.0");
2121

22-
var expected = Package.WithVersion(3, 0, 0, ["alpha", "0",]);
22+
var expected = Package.WithVersion(2, 3, 4);
2323

2424
// act
2525
var (actual, _, _) = await Sdk.BuildProject(path, envVars: envVars);

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ Note that `MinVerMinimumMajorMinor` will be redundant after you create the first
206206

207207
Also note that if the latest version tag found in the commit history has a higher `MAJOR.MINOR` than `MinVerMinimumMajorMinor`, then `MinVerMinimumMajorMinor` will be ignored.
208208

209+
Lastly, if the the current commit has a version tag, the tag will be used as-is, even if it has a lower `MAJOR.MINOR` than `MinVerMinimumMajorMinor`.
210+
209211
### Can I use my own pre-release versioning scheme?
210212

211213
Yes! MinVer doesn't care what your pre-release versioning scheme is. The default pre-release identifiers are `alpha.0`, but you can use whatever you like in your tags. If your versioning scheme is valid [SemVer 2.x](https://semver.org/spec/v2.0.0.html), it will work with MinVer.

0 commit comments

Comments
 (0)