diff --git a/Directory.Build.props b/Directory.Build.props
index 3dcd5dd..adbafb3 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -46,7 +46,7 @@
v
patch
- 2.2
+ 2.3
diff --git a/README.md b/README.md
index be698fb..77507ee 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@ See [docs/VersionCalculation.md](docs/VersionCalculation.md) for further reading
| Set the build data to this value. | -b, --build-metadata, VerliteBuildMetadata | |
| Part of the version to print. | -s, --show | all |
| Automatically fetch commits and a tag for shallow clones. | --auto-fetch | false |
-| Create a lightweight tag instead of fetching the remote's. | --enable-lightweight-tags | false |
+| Create a lightweight tag instead of fetching the remote's. | --enable-lightweight-tags | false |
| Set which version part should be bumped after an RTM release. | -a, --auto-increment, VerliteAutoIncrement | patch |
| A command to test whether a tag should be ignored via exit code. | -f, --filter-tags, VerliteFilterTags | |
| The remote endpoint to use when fetching tags and commits. | -r, --remote, VerliteRemote | origin |
@@ -243,6 +243,8 @@ namespace Verlite
public const string Patch;
public const string Prerelease;
public const string BuildMetadata;
+ public const string Commit;
+ public const string Height;
}
}
```
diff --git a/src/Verlite.CLI/JsonOutput.cs b/src/Verlite.CLI/JsonOutput.cs
new file mode 100644
index 0000000..47437e2
--- /dev/null
+++ b/src/Verlite.CLI/JsonOutput.cs
@@ -0,0 +1,67 @@
+using System.Globalization;
+using System.Text;
+
+namespace Verlite.CLI
+{
+ internal static class JsonOutput
+ {
+ public static string GenerateOutput(
+ SemVer version,
+ Commit? commit,
+ TaggedVersion? lastTag,
+ int? height)
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine("{");
+ sb.AppendString(1, "commit", commit?.Id);
+ sb.AppendString(1, "full", version.ToString());
+ sb.AppendInteger(1, "major", version.Major);
+ sb.AppendInteger(1, "minor", version.Minor);
+ sb.AppendInteger(1, "patch", version.Patch);
+ sb.AppendString(1, "prerelease", version.Prerelease);
+ sb.AppendString(1, "meta", version.BuildMetadata);
+ sb.AppendInteger(1, "height", height);
+ if (lastTag is null)
+ {
+ sb.AppendLine("\t" + @"""lastTag"": null");
+ }
+ else
+ {
+ sb.AppendLine("\t" + @"""lastTag"": {");
+ sb.AppendString(2, "tag", lastTag.Tag.Name);
+ sb.AppendString(2, "commit", lastTag.Tag.PointsTo.Id);
+ sb.AppendString(2, "full", lastTag.Version.ToString());
+ sb.AppendInteger(2, "major", lastTag.Version.Major);
+ sb.AppendInteger(2, "minor", lastTag.Version.Minor);
+ sb.AppendInteger(2, "patch", lastTag.Version.Patch);
+ sb.AppendString(2, "prerelease", lastTag.Version.Prerelease);
+ sb.AppendString(2, "meta", lastTag.Version.BuildMetadata, final: true);
+ sb.AppendLine("\t}");
+ }
+ sb.AppendLine("}");
+
+ return sb.ToString();
+ }
+
+ private static void AppendString(this StringBuilder sb, int indentation, string key, string? value, bool final = false)
+ {
+ value = value is null ? "null" : $@"""{System.Web.HttpUtility.JavaScriptStringEncode(value)}""";
+ sb.Append(new string('\t', indentation));
+ sb.Append($@"""{key}"": {value}");
+ if (final)
+ sb.AppendLine("");
+ else
+ sb.AppendLine(",");
+ }
+ private static void AppendInteger(this StringBuilder sb, int indentation, string key, int? value, bool final = false)
+ {
+ var valuestr = value is null ? "null" : value.Value.ToString(CultureInfo.InvariantCulture);
+ sb.Append(new string('\t', indentation));
+ sb.Append($@"""{key}"": ""{valuestr}""");
+ if (final)
+ sb.AppendLine("");
+ else
+ sb.AppendLine(",");
+ }
+ }
+}
diff --git a/src/Verlite.CLI/Program.cs b/src/Verlite.CLI/Program.cs
index f6e31bb..a1adc76 100644
--- a/src/Verlite.CLI/Program.cs
+++ b/src/Verlite.CLI/Program.cs
@@ -141,6 +141,10 @@ private async static Task RootCommandAsync(
};
var version = opts.VersionOverride ?? new SemVer();
+ Commit? commit = null;
+ TaggedVersion? lastTag = null;
+ int? height = null;
+
if (opts.VersionOverride is null)
{
using var repo = await GitRepoInspector.FromPath(sourceDirectory, opts.Remote, log, commandRunner);
@@ -151,7 +155,8 @@ private async static Task RootCommandAsync(
if (!string.IsNullOrWhiteSpace(filterTags))
tagFilter = new CommandTagFilter(commandRunner, log, filterTags, sourceDirectory);
- version = await VersionCalculator.FromRepository(repo, opts, log, tagFilter);
+ commit = await repo.GetHead();
+ (version, lastTag, height) = await VersionCalculator.FromRepository2(repo, opts, log, tagFilter);
}
string toShow = show switch
@@ -162,6 +167,8 @@ private async static Task RootCommandAsync(
Show.patch => version.Patch.ToString(CultureInfo.InvariantCulture),
Show.prerelease => version.Prerelease?.ToString(CultureInfo.InvariantCulture) ?? string.Empty,
Show.metadata => version.BuildMetadata?.ToString(CultureInfo.InvariantCulture) ?? string.Empty,
+ Show.height => height?.ToString(CultureInfo.InvariantCulture) ?? string.Empty,
+ Show.json => JsonOutput.GenerateOutput(version, commit, lastTag, height),
_ => throw new NotImplementedException(),
};
diff --git a/src/Verlite.CLI/Show.cs b/src/Verlite.CLI/Show.cs
index f3bb412..5b1a09e 100644
--- a/src/Verlite.CLI/Show.cs
+++ b/src/Verlite.CLI/Show.cs
@@ -11,6 +11,8 @@ internal enum Show
patch = 3,
prerelease = 4,
metadata = 5,
+ height = 6,
+ json = 7,
}
internal static partial class Parsers
{
@@ -34,6 +36,8 @@ Show invalid()
"PATCH" => Show.patch,
"PRERELEASE" => Show.prerelease,
"METADATA" => Show.metadata,
+ "HEIGHT" => Show.height,
+ "JSON" => Show.json,
_ => invalid(),
};
}
diff --git a/src/Verlite.Core/PublicAPI.Unshipped.txt b/src/Verlite.Core/PublicAPI.Unshipped.txt
index 7dc5c58..612b820 100644
--- a/src/Verlite.Core/PublicAPI.Unshipped.txt
+++ b/src/Verlite.Core/PublicAPI.Unshipped.txt
@@ -1 +1,2 @@
#nullable enable
+static Verlite.VersionCalculator.FromRepository2(Verlite.IRepoInspector! repo, Verlite.VersionCalculationOptions! options, Verlite.ILogger? log, Verlite.ITagFilter? tagFilter) -> System.Threading.Tasks.Task<(Verlite.SemVer version, Verlite.TaggedVersion? lastTag, int? height)>!
diff --git a/src/Verlite.Core/VersionCalculator.cs b/src/Verlite.Core/VersionCalculator.cs
index d1b5629..1a614c8 100644
--- a/src/Verlite.Core/VersionCalculator.cs
+++ b/src/Verlite.Core/VersionCalculator.cs
@@ -104,6 +104,7 @@ public static SemVer FromTagInfomation(SemVer? lastTag, VersionCalculationOption
/// A log for diagnostics.
/// A filter to ignore tags. When null no filter is used.
/// The version for the state of the repository.
+ [Obsolete("Use FromRepository2()")]
public static async Task FromRepository(
IRepoInspector repo,
VersionCalculationOptions options,
@@ -120,5 +121,34 @@ public static async Task FromRepository(
return FromTagInfomation(lastTagVer?.Version, options, height);
}
+
+ ///
+ /// Calculate the next version from a repository.
+ ///
+ /// The repo to use.
+ /// The options.
+ /// A log for diagnostics.
+ /// A filter to ignore tags. When null no filter is used.
+ /// The version for the state of the repository, and the associated tag information.
+ public static async Task<(SemVer version, TaggedVersion? lastTag, int? height)> FromRepository2(
+ IRepoInspector repo,
+ VersionCalculationOptions options,
+ ILogger? log,
+ ITagFilter? tagFilter)
+ {
+ if (options.VersionOverride.HasValue)
+ return (options.VersionOverride.Value, null, null);
+
+ var (height, lastTag) = await HeightCalculator.FromRepository(
+ repo: repo,
+ tagPrefix: options.TagPrefix,
+ queryRemoteTags: options.QueryRemoteTags,
+ fetchTags: options.QueryRemoteTags,
+ log: log,
+ tagFilter: tagFilter);
+
+ var version = FromTagInfomation(lastTag?.Version, options, height);
+ return (version, lastTag, height);
+ }
}
}
diff --git a/src/Verlite.MsBuild/GetVersionTask.cs b/src/Verlite.MsBuild/GetVersionTask.cs
index 413e7dd..20ffabe 100644
--- a/src/Verlite.MsBuild/GetVersionTask.cs
+++ b/src/Verlite.MsBuild/GetVersionTask.cs
@@ -109,6 +109,7 @@ private async Task ExecuteAsync()
var version = opts.VersionOverride ?? new SemVer();
var commit = string.Empty;
+ var height = string.Empty;
if (opts.VersionOverride is null)
{
using var repo = await GitRepoInspector.FromPath(ProjectDirectory, opts.Remote, log, commandRunner);
@@ -117,8 +118,10 @@ private async Task ExecuteAsync()
if (!string.IsNullOrWhiteSpace(FilterTags))
tagFilter = new CommandTagFilter(commandRunner, log, FilterTags, ProjectDirectory);
- version = await VersionCalculator.FromRepository(repo, opts, log, tagFilter);
+ int? heightInt;
+ (version, _, heightInt) = await VersionCalculator.FromRepository2(repo, opts, log, tagFilter);
commit = (await repo.GetHead())?.Id ?? string.Empty;
+ height = heightInt?.ToString(CultureInfo.InvariantCulture) ?? string.Empty;
}
Version = version.ToString();
@@ -128,6 +131,7 @@ private async Task ExecuteAsync()
VersionPrerelease = version.Prerelease ?? string.Empty;
VersionBuildMetadata = version.BuildMetadata ?? string.Empty;
Commit = commit;
+ Height = height;
return true;
}
@@ -138,5 +142,6 @@ private async Task ExecuteAsync()
[Output] public string VersionPrerelease { get; private set; } = "";
[Output] public string VersionBuildMetadata { get; private set; } = "";
[Output] public string Commit { get; private set; } = "";
+ [Output] public string Height { get; private set; } = "";
}
}
diff --git a/src/Verlite.MsBuild/VersionEmbedGenerator.cs b/src/Verlite.MsBuild/VersionEmbedGenerator.cs
index 75c12d4..b62c8ef 100644
--- a/src/Verlite.MsBuild/VersionEmbedGenerator.cs
+++ b/src/Verlite.MsBuild/VersionEmbedGenerator.cs
@@ -24,6 +24,7 @@ public void Execute(GeneratorExecutionContext context)
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.VerlitePrerelease", out var prerelease);
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.VerliteBuildMetadata", out var meta);
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.VerliteCommit", out var commit);
+ context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.VerliteHeight", out var height);
version ??= string.Empty;
major ??= string.Empty;
@@ -32,6 +33,7 @@ public void Execute(GeneratorExecutionContext context)
prerelease ??= string.Empty;
meta ??= string.Empty;
commit ??= string.Empty;
+ height ??= string.Empty;
var coreVersion = string.IsNullOrEmpty(version) ? string.Empty : $"{major}.{minor}.{patch}";
@@ -54,6 +56,7 @@ internal static class Version
public const string Prerelease = ""{prerelease}"";
public const string BuildMetadata = ""{meta}"";
public const string Commit = ""{commit}"";
+ public const string Height = ""{height}"";
}}
}}
";
diff --git a/src/Verlite.MsBuild/build/Verlite.MsBuild.targets b/src/Verlite.MsBuild/build/Verlite.MsBuild.targets
index 528eb19..8d52a7c 100644
--- a/src/Verlite.MsBuild/build/Verlite.MsBuild.targets
+++ b/src/Verlite.MsBuild/build/Verlite.MsBuild.targets
@@ -28,6 +28,7 @@ This file has been modified by Ashleigh Adams and adapted for Verlite -->
+
@@ -77,6 +78,7 @@ This file has been modified by Ashleigh Adams and adapted for Verlite -->
+
diff --git a/tests/UnitTests/VersionCalculationTests.cs b/tests/UnitTests/VersionCalculationTests.cs
index 9e5470e..0b6bab2 100644
--- a/tests/UnitTests/VersionCalculationTests.cs
+++ b/tests/UnitTests/VersionCalculationTests.cs
@@ -108,9 +108,11 @@ public async Task NoCommitHasMinVersionAlpha1()
{
var repo = new MockRepoInspector(Array.Empty());
- var semver = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ var (semver, lastTag, height) = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
semver.Should().Be(new SemVer(0, 1, 0, "alpha.1"));
+ lastTag.Should().BeNull();
+ height.Should().Be(1);
}
[Fact]
@@ -121,9 +123,11 @@ public async Task FirstCommitNoTagHasMinVersionAlpha1()
new("commit_a"),
});
- var semver = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ var (semver, lastTag, height) = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
semver.Should().Be(new SemVer(0, 1, 0, "alpha.1"));
+ lastTag.Should().BeNull();
+ height.Should().Be(1);
}
[Fact]
@@ -134,9 +138,10 @@ public async Task FirstCommitTaggedHasExactVersion()
new("commit_a") { Tags = new[] { "v5.4.3-rc.2.1" } },
});
- var semver = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ var (semver, _, height) = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
semver.Should().Be(new SemVer(5, 4, 3, "rc.2.1"));
+ height.Should().Be(0);
}
[Fact]
@@ -148,9 +153,10 @@ public async Task CommitAfterPrereleaseTagAppendsHeight()
new("commit_a") { Tags = new[] { "v4.3.2-rc.1" } },
});
- var semver = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ var (semver, _, height) = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
semver.Should().Be(new SemVer(4, 3, 2, "rc.1.1"));
+ height?.Should().Be(1);
}
[Fact]
@@ -162,9 +168,11 @@ public async Task CommitAfterRtmTagAppendsHeightAndBumpsMinor()
new("commit_a") { Tags = new[] { "v3.2.1" } },
});
- var semver = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ var (semver, lastTag, height) = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
semver.Should().Be(new SemVer(3, 2, 2, "alpha.1"));
+ lastTag?.Tag.Name.Should().Be("v3.2.1");
+ height?.Should().Be(1);
}
[Fact]
@@ -177,7 +185,7 @@ public async Task LatestTagIsFetchedWithQueryRemoteTags()
new("commit_a") { Tags = new[] { "v3.2.0" } },
});
- _ = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = true });
+ _ = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = true }, null, null);
repo.LocalTags.Should().Contain(new Tag[] { new Tag("v3.2.1", new Commit("commit_b")) });
}
@@ -192,7 +200,7 @@ public async Task LatestTagIsNotFetchedWithoutQueryRemoteTags()
new("commit_a") { Tags = new[] { "v3.2.0" } },
});
- _ = await VersionCalculator.FromRepository(repo, new() { QueryRemoteTags = false });
+ _ = await VersionCalculator.FromRepository2(repo, new() { QueryRemoteTags = false }, null, null);
repo.LocalTags.Should().BeEmpty();
}
@@ -205,12 +213,13 @@ public async Task TaggedBuildMetadataIsPreserved()
new("commit_a") { Tags = new[] { "v1.2.3+4" } },
});
- var version = await VersionCalculator.FromRepository(repo, new()
+ var (version, _, height) = await VersionCalculator.FromRepository2(repo, new()
{
QueryRemoteTags = true,
- });
+ }, null, null);
version.BuildMetadata.Should().Be("4");
+ height.Should().Be(0);
}
[Fact]
@@ -222,12 +231,13 @@ public async Task TaggedWithHeightBuildMetadataIsNotPreserved()
new("commit_a") { Tags = new[] { "v1.2.3+4" } },
});
- var version = await VersionCalculator.FromRepository(repo, new()
+ var (version, _, height) = await VersionCalculator.FromRepository2(repo, new()
{
QueryRemoteTags = true,
- });
+ }, null, null);
version.BuildMetadata.Should().BeNull();
+ height.Should().Be(1);
}
[Fact]
@@ -239,11 +249,11 @@ public async Task TaggedWithHeightStillUsesOptionsMetadata()
new("commit_a") { Tags = new[] { "v1.2.3+4" } },
});
- var version = await VersionCalculator.FromRepository(repo, new()
+ var (version, _, _) = await VersionCalculator.FromRepository2(repo, new()
{
QueryRemoteTags = true,
BuildMetadata = "git.a1b2c3d",
- });
+ }, null, null);
version.BuildMetadata.Should().Be("git.a1b2c3d");
}
@@ -256,11 +266,11 @@ public async Task DirectTagWithNoMetaUsesOnlyOptionsMetadata()
new("commit_a") { Tags = new[] { "v1.2.3" } },
});
- var version = await VersionCalculator.FromRepository(repo, new()
+ var (version, _, _) = await VersionCalculator.FromRepository2(repo, new()
{
QueryRemoteTags = true,
BuildMetadata = "git.a1b2c3d",
- });
+ }, null, null);
version.BuildMetadata.Should().Be("git.a1b2c3d");
}
@@ -273,11 +283,11 @@ public async Task TaggedBuildMetadataConcatenates()
new("commit_a") { Tags = new[] { "v1.2.3+4" } },
});
- var version = await VersionCalculator.FromRepository(repo, new()
+ var (version, _, _) = await VersionCalculator.FromRepository2(repo, new()
{
BuildMetadata = "git.a1b2c3d",
QueryRemoteTags = true,
- });
+ }, null, null);
version.BuildMetadata.Should().Be("4-git.a1b2c3d");
}