Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/shared.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ definitions:
os: ubuntu-24.04
exe: verlite
- rid: osx-x64
os: macos-13
os: macos-14-large
exe: verlite
steps:
- *checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/continuous-delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
os: ubuntu-24.04
exe: verlite
- rid: osx-x64
os: macos-13
os: macos-14-large
exe: verlite
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
os: ubuntu-24.04
exe: verlite
- rid: osx-x64
os: macos-13
os: macos-14-large
exe: verlite
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
os: ubuntu-24.04
exe: verlite
- rid: osx-x64
os: macos-13
os: macos-14-large
exe: verlite
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ See [docs/VersionCalculation.md](docs/VersionCalculation.md) for further reading
| The remote endpoint to use when fetching tags and commits. | -r, --remote, VerliteRemote | origin |
| Generate version strings and embed them via a source generator. | VerliteEmbedVersion | true |
| Use a shadow repo (partial, only commits) to read commit history. | --enable-shadow-repo, VerliteEnableShadowRepo | false |
| Any change except for ignored files causes a version bump. | --dirty-version-bump- VerliteDirtyVersionBump | false |

## Comparison with GitVersion

Expand Down Expand Up @@ -247,6 +248,7 @@ namespace Verlite
public const string BuildMetadata;
public const string Commit;
public const string Height;
public const bool Dirty;
}
}
```
Expand Down
19 changes: 18 additions & 1 deletion src/Verlite.CLI/JsonOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public static string GenerateOutput(
SemVer version,
Commit? commit,
TaggedVersion? lastTag,
int? height)
int? height,
bool? dirty)
{
var sb = new StringBuilder();
sb.AppendLine("{");
Expand All @@ -21,6 +22,7 @@ public static string GenerateOutput(
sb.AppendString(1, "prerelease", version.Prerelease);
sb.AppendString(1, "meta", version.BuildMetadata);
sb.AppendInteger(1, "height", height);
sb.AppendBool(1, "dirty", dirty);
if (lastTag is null)
{
sb.AppendLine("\t" + @"""lastTag"": null");
Expand Down Expand Up @@ -63,5 +65,20 @@ private static void AppendInteger(this StringBuilder sb, int indentation, string
else
sb.AppendLine(",");
}
private static void AppendBool(this StringBuilder sb, int indentation, string key, bool? value, bool final = false)
{
var valuestr = value switch
{
null => "null",
true => "true",
false=> "false",
};
sb.Append(new string('\t', indentation));
sb.Append($@"""{key}"": ""{valuestr}""");
if (final)
sb.AppendLine("");
else
sb.AppendLine(",");
}
}
}
10 changes: 9 additions & 1 deletion src/Verlite.CLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ public static async Task<int> Main(string[] args)
aliases: new[] { "--enable-shadow-repo" },
getDefaultValue: () => false,
description: "Use a shadow repro for shallow clones using filter branches to fetch only commits."),
new Option<bool>(
aliases: new[] { "--dirty-version-bump" },
getDefaultValue: () => false,
description: "Any non-ignored modifications to the repo result in a version bump."),
new Option<AutoIncrement>(
aliases: new[] { "--auto-increment", "-a" },
isDefault: true,
Expand Down Expand Up @@ -123,6 +127,7 @@ private static async Task RootCommandAsync(
bool autoFetch,
bool enableLightweightTags,
bool enableShadowRepo,
bool dirtyVersionBump,
AutoIncrement autoIncrement,
string filterTags,
string remote,
Expand All @@ -148,12 +153,14 @@ private static async Task RootCommandAsync(
QueryRemoteTags = autoFetch,
AutoIncrement = autoIncrement.Value(),
Remote = remote,
DirtyVersionBump = dirtyVersionBump,
};

var version = opts.VersionOverride ?? new SemVer();
Commit? commit = null;
TaggedVersion? lastTag = null;
int? height = null;
bool? dirty = null;

if (opts.VersionOverride is null)
{
Expand All @@ -169,6 +176,7 @@ private static async Task RootCommandAsync(
commit = string.IsNullOrEmpty(revision)
? await repo.GetHead()
: await repo.ParseRevision(revision);
dirty = await repo.GetDirty();

(version, lastTag, height) = await VersionCalculator.FromRepository3(repo, commit, opts, log, tagFilter);
}
Expand All @@ -182,7 +190,7 @@ private static async Task RootCommandAsync(
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),
Show.json => JsonOutput.GenerateOutput(version, commit, lastTag, height, dirty),
_ => throw new NotImplementedException(),
};

Expand Down
14 changes: 14 additions & 0 deletions src/Verlite.Core/GitRepoInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,5 +464,19 @@ public void Dispose()
PrimaryCatfile?.Dispose();
ShadowRepo?.Dispose();
}

/// <inheritdoc/>
public async Task<bool> GetDirty()
{
try
{
var (stdout, stderr) = await Git("status", "--porcelain");
return !string.IsNullOrWhiteSpace(stdout);
}
catch (CommandException)
{
return true;
}
}
}
}
46 changes: 44 additions & 2 deletions src/Verlite.Core/HeightCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,48 @@ await repo.GetHead(),
/// <param name="log">The log to output verbose diagnostics to.</param>
/// <param name="tagFilter">A filter to test tags against. A value of <c>null</c> means do not filter.</param>
/// <returns>A task containing the height, and, if found, the tagged version.</returns>
public static async Task<(int height, TaggedVersion?)> FromRepository2(
[Obsolete("Use FromRepository3")]
public static Task<(int height, TaggedVersion?)> FromRepository2(
IRepoInspector repo,
Commit? commit,
string tagPrefix,
bool queryRemoteTags,
bool fetchTags,
ILogger? log,
ITagFilter? tagFilter)
{
return FromRepository3(
repo,
commit,
tagPrefix,
queryRemoteTags,
fetchTags,
dirtyBumpsHeight: false,
log,
tagFilter);
}

/// <summary>
/// Calculate the height from a repository by walking, from the head, the primary parents until a version tag is found.
/// </summary>
/// <param name="repo">The repo to walk.</param>
/// <param name="commit">The commit for which to find a version.</param>
/// <param name="tagPrefix">What version tags are prefixed with.</param>
/// <param name="queryRemoteTags">Whether to query local or local and remote tags.</param>
/// <param name="fetchTags">Whether to fetch tags we don't yet have locally.</param>
/// <param name="dirtyBumpsHeight">Should a dirty repo bump the height.</param>
/// <param name="log">The log to output verbose diagnostics to.</param>
/// <param name="tagFilter">A filter to test tags against. A value of <c>null</c> means do not filter.</param>
/// <returns>A task containing the height, and, if found, the tagged version.</returns>
public static async Task<(int height, TaggedVersion?)> FromRepository3(
IRepoInspector repo,
Commit? commit,
string tagPrefix,
bool queryRemoteTags,
bool fetchTags,
bool dirtyBumpsHeight,
ILogger? log,
ITagFilter? tagFilter)
{
var tags = await repo.GetTags(queryRemoteTags ? QueryTarget.Local | QueryTarget.Remote : QueryTarget.Local);

Expand Down Expand Up @@ -108,10 +142,18 @@ await repo.GetHead(),
}
}

return candidates
var (height, taggedVersion) = candidates
.OrderByDescending(x => x.version is not null)
.ThenByDescending(x => x.version?.Version)
.First();

if (dirtyBumpsHeight && await repo.GetDirty())
{
log?.Normal($"Local repo is dirty, bumping height from {height} to {height + 1}.");
height += 1;
}

return (height, taggedVersion);
}

/// <summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Verlite.Core/IRepoInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
/// <returns>A task containing the commit, or <c>null</c> if there is none.</returns>
Task<Commit?> GetHead();
/// <summary>
/// Check if a repo has changes.
/// </summary>
/// <returns>true if there are changes.</returns>
Task<bool> GetDirty();

Check warning on line 76 in src/Verlite.Core/IRepoInspector.cs

View workflow job for this annotation

GitHub Actions / Build Standalone Binaries (osx-x64, macos-14-large, verlite)

/// <summary>
/// Parse a revision to find the commit it points to.
/// </summary>
/// <param name="revision">The revision to parse.</param>
Expand Down
4 changes: 4 additions & 0 deletions src/Verlite.Core/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#nullable enable
static Verlite.HeightCalculator.FromRepository3(Verlite.IRepoInspector! repo, Verlite.Commit? commit, string! tagPrefix, bool queryRemoteTags, bool fetchTags, bool dirtyBumpsHeight, Verlite.ILogger? log, Verlite.ITagFilter? tagFilter) -> System.Threading.Tasks.Task<(int height, Verlite.TaggedVersion?)>!
static Verlite.SemVer.CompareMetadata(string? left, string? right) -> int
static Verlite.SemVer.ComparePrerelease(string? left, string? right) -> int
Verlite.GitRepoInspector.GetDirty() -> System.Threading.Tasks.Task<bool>!
Verlite.VersionCalculationOptions.DirtyVersionBump.get -> bool
Verlite.VersionCalculationOptions.DirtyVersionBump.set -> void
4 changes: 4 additions & 0 deletions src/Verlite.Core/VersionCalculationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public class VersionCalculationOptions
/// </summary>
public VersionPart AutoIncrement { get; set; } = VersionPart.Patch;
/// <summary>
/// Whether the version should be bumped if the repo is considered to be dirty.
/// </summary>
public bool DirtyVersionBump { get; set; }
/// <summary>
/// The remote endpoint to use when fetching tags and commits.
/// </summary>
public string Remote { get; set; } = "origin";
Expand Down
4 changes: 2 additions & 2 deletions src/Verlite.Core/VersionCalculator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

namespace Verlite
Expand Down Expand Up @@ -175,12 +174,13 @@ public static async Task<SemVer> FromRepository(
if (options.VersionOverride.HasValue)
return (options.VersionOverride.Value, null, null);

var (height, lastTag) = await HeightCalculator.FromRepository2(
var (height, lastTag) = await HeightCalculator.FromRepository3(
repo: repo,
commit: commit,
tagPrefix: options.TagPrefix,
queryRemoteTags: options.QueryRemoteTags,
fetchTags: options.QueryRemoteTags,
dirtyBumpsHeight: options.DirtyVersionBump,
log: log,
tagFilter: tagFilter);

Expand Down
8 changes: 8 additions & 0 deletions src/Verlite.MsBuild/GetVersionTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public sealed partial class GetVersionTask : MsBuildTask
public string FilterTags { get; set; } = "";
public string Remote { get; set; } = "";
public bool EnableShadowRepo { get; set; }
public bool DirtyVersionBump { get; set; }

public override bool Execute()
{
Expand Down Expand Up @@ -106,11 +107,14 @@ private async Task<bool> ExecuteAsync()

if (!string.IsNullOrWhiteSpace(Remote))
opts.Remote = Remote;

opts.DirtyVersionBump = DirtyVersionBump;
}

var version = opts.VersionOverride ?? new SemVer();
var commitString = string.Empty;
var heightString = string.Empty;
var dirtyString = string.Empty;
if (opts.VersionOverride is null)
{
using var repo = await GitRepoInspector.FromPath(ProjectDirectory, opts.Remote, log, commandRunner);
Expand All @@ -122,10 +126,12 @@ private async Task<bool> ExecuteAsync()

var commit = await repo.GetHead();
commitString = commit?.Id ?? string.Empty;
dirtyString = await repo.GetDirty() ? "true" : "false";

int? height;
(version, _, height) = await VersionCalculator.FromRepository3(repo, commit, opts, log, tagFilter);
heightString = height?.ToString(CultureInfo.InvariantCulture) ?? string.Empty;

}

Version = version.ToString();
Expand All @@ -136,6 +142,7 @@ private async Task<bool> ExecuteAsync()
VersionBuildMetadata = version.BuildMetadata ?? string.Empty;
Commit = commitString;
Height = heightString;
Dirty = dirtyString;

return true;
}
Expand All @@ -147,5 +154,6 @@ private async Task<bool> ExecuteAsync()
[Output] public string VersionBuildMetadata { get; private set; } = "";
[Output] public string Commit { get; private set; } = "";
[Output] public string Height { get; private set; } = "";
[Output] public string Dirty { get; private set; } = "";
}
}
10 changes: 10 additions & 0 deletions src/Verlite.MsBuild/VersionEmbedGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public void Execute(GeneratorExecutionContext context)
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);
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.VerliteDirty", out var dirty);

version ??= string.Empty;
major ??= string.Empty;
Expand All @@ -34,6 +35,14 @@ public void Execute(GeneratorExecutionContext context)
meta ??= string.Empty;
commit ??= string.Empty;
height ??= string.Empty;
dirty ??= string.Empty;

var normalizedDirty = dirty.Trim() switch
{
"true" or "1" => "true",
"false" or "0" => "false",
_ => "false",
};

var coreVersion = string.IsNullOrEmpty(version) ? string.Empty : $"{major}.{minor}.{patch}";

Expand All @@ -57,6 +66,7 @@ internal static class Version
public const string BuildMetadata = ""{meta}"";
public const string Commit = ""{commit}"";
public const string Height = ""{height}"";
public const bool Dirty = {normalizedDirty};
}}
}}
";
Expand Down
Loading
Loading