Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output version number parts as properties and set AssemblyVersion #113

Merged
merged 1 commit into from
Nov 22, 2018
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
31 changes: 17 additions & 14 deletions MinVer.Lib/Version.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ namespace MinVer.Lib
public class Version : IComparable<Version>
#pragma warning restore CA1036 // Override methods on comparable types
{
private readonly int major;
private readonly int minor;
private readonly int patch;
private readonly List<string> preReleaseIdentifiers;
private readonly int height;
private readonly string buildMetadata;
Expand All @@ -22,32 +19,38 @@ public Version() : this(default, default) { }

private Version(int major, int minor, int patch, IEnumerable<string> preReleaseIdentifiers, int height, string buildMetadata)
{
this.major = major;
this.minor = minor;
this.patch = patch;
this.Major = major;
this.Minor = minor;
this.Patch = patch;
this.preReleaseIdentifiers = preReleaseIdentifiers?.ToList() ?? new List<string>();
this.height = height;
this.buildMetadata = buildMetadata;
}

public int Major { get; }

public int Minor { get; }

public int Patch { get; }

public override string ToString() =>
$"{this.major}.{this.minor}.{this.patch}{(this.preReleaseIdentifiers.Count == 0 ? "" : $"-{string.Join(".", this.preReleaseIdentifiers)}")}{(this.height == 0 ? "" : $".{this.height}")}{(string.IsNullOrEmpty(this.buildMetadata) ? "" : $"+{this.buildMetadata}")}";
$"{this.Major}.{this.Minor}.{this.Patch}{(this.preReleaseIdentifiers.Count == 0 ? "" : $"-{string.Join(".", this.preReleaseIdentifiers)}")}{(this.height == 0 ? "" : $".{this.height}")}{(string.IsNullOrEmpty(this.buildMetadata) ? "" : $"+{this.buildMetadata}")}";

public int CompareTo(Version other)
{
var major = this.major.CompareTo(other.major);
var major = this.Major.CompareTo(other.Major);
if (major != 0)
{
return major;
}

var minor = this.minor.CompareTo(other.minor);
var minor = this.Minor.CompareTo(other.Minor);
if (minor != 0)
{
return minor;
}

var patch = this.patch.CompareTo(other.patch);
var patch = this.Patch.CompareTo(other.Patch);
if (patch != 0)
{
return patch;
Expand Down Expand Up @@ -99,16 +102,16 @@ public int CompareTo(Version other)

public Version WithHeight(int height) =>
this.preReleaseIdentifiers.Count == 0 && height > 0
? new Version(this.major, this.minor, this.patch + 1, new[] { "alpha", "0" }, height, default)
: new Version(this.major, this.minor, this.patch, this.preReleaseIdentifiers, height, height == 0 ? this.buildMetadata : default);
? new Version(this.Major, this.Minor, this.Patch + 1, new[] { "alpha", "0" }, height, default)
: new Version(this.Major, this.Minor, this.Patch, this.preReleaseIdentifiers, height, height == 0 ? this.buildMetadata : default);

public Version AddBuildMetadata(string buildMetadata)
{
var separator = !string.IsNullOrEmpty(this.buildMetadata) && !string.IsNullOrEmpty(buildMetadata) ? "." : "";
return new Version(this.major, this.minor, this.patch, this.preReleaseIdentifiers, this.height, $"{this.buildMetadata}{separator}{buildMetadata}");
return new Version(this.Major, this.Minor, this.Patch, this.preReleaseIdentifiers, this.height, $"{this.buildMetadata}{separator}{buildMetadata}");
}

public bool IsBefore(int major, int minor) => this.major < major || (this.major == major && this.minor < minor);
public bool IsBefore(int major, int minor) => this.Major < major || (this.Major == major && this.Minor < minor);

public static Version ParseOrDefault(string text, string prefix) =>
text == default || !text.StartsWith(prefix ?? "") ? default : ParseOrDefault(text.Substring(prefix?.Length ?? 0));
Expand Down
16 changes: 16 additions & 0 deletions MinVer/TextWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace MinVer
{
using System.IO;
using MinVer.Lib;

internal static class TextWriterExtensions
{
public static void WriteVersion(this TextWriter writer, Version version)
{
writer.WriteLine($"Version:{version}");
writer.WriteLine($"Major:{version.Major}");
writer.WriteLine($"Minor:{version.Minor}");
writer.WriteLine($"Patch:{version.Patch}");
}
}
}
23 changes: 12 additions & 11 deletions MinVer/build/MinVer.targets
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<GetPackageVersionDependsOn>$(GetPackageVersionDependsOn);MinVer</GetPackageVersionDependsOn>
</PropertyGroup>

<Target Name="MinVer_GetVersion" Condition="'$(MinVerVersionOverride)' == ''">
<Target Name="MinVer_GetVersion">
<ItemGroup>
<MinVerInputs Include="--build-metadata &quot;$(MinVerBuildMetadata)&quot;" />
<MinVerInputs Include="--major-minor &quot;$(MinVerMajorMinor)&quot;" />
Expand All @@ -17,24 +17,25 @@
<Output TaskParameter="ConsoleOutput" ItemName="MinVerConsoleOutput" />
</Exec>
<ItemGroup>
<MinVerOutput Include="@(MinVerConsoleOutput)" Condition="'$([System.String]::new(`%(Identity)`).StartsWith(`MinVer:`))' != 'true'" />
<MinVerOutputVersion Include="@(MinVerConsoleOutput)" Condition="'$([System.String]::new(`%(Identity)`).StartsWith(`Version:`))' == 'true'" />
<MinVerOutputMajor Include="@(MinVerConsoleOutput)" Condition="'$([System.String]::new(`%(Identity)`).StartsWith(`Major:`))' == 'true'" />
<MinVerOutputMinor Include="@(MinVerConsoleOutput)" Condition="'$([System.String]::new(`%(Identity)`).StartsWith(`Minor:`))' == 'true'" />
<MinVerOutputPatch Include="@(MinVerConsoleOutput)" Condition="'$([System.String]::new(`%(Identity)`).StartsWith(`Patch:`))' == 'true'" />
</ItemGroup>
<PropertyGroup>
<MinVerVersion>@(MinVerOutput)</MinVerVersion>
</PropertyGroup>
</Target>

<Target Name="MinVer_OverrideVersion" BeforeTargets="MinVer_GetVersion" Condition="'$(MinVerVersionOverride)' != ''">
<Message Text="MinVer: Using version override $(MinVerVersionOverride)." Importance="high" />
<PropertyGroup>
<MinVerVersion>$(MinVerVersionOverride)</MinVerVersion>
<MinVerVersion>@(MinVerOutputVersion->Substring(8))</MinVerVersion>
<MinVerMajor>@(MinVerOutputMajor->Substring(6))</MinVerMajor>
<MinVerMinor>@(MinVerOutputMinor->Substring(6))</MinVerMinor>
<MinVerPatch>@(MinVerOutputPatch->Substring(6))</MinVerPatch>
</PropertyGroup>
</Target>

<Target Name="MinVer" BeforeTargets="CoreCompile;GenerateNuspec" DependsOnTargets="MinVer_GetVersion" Condition="'$(UsingMicrosoftNETSdk)' == 'true' And '$(DesignTimeBuild)' != 'true'">
<PropertyGroup>
<Version>$(MinVerVersion)</Version>
<AssemblyVersion>$(MinVerMajor).0.0.0</AssemblyVersion>
<FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).0</FileVersion>
<PackageVersion>$(MinVerVersion)</PackageVersion>
<Version>$(MinVerVersion)</Version>
</PropertyGroup>
</Target>

Expand Down
40 changes: 17 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Your project will be versioned according to the latest tag found in the commit h

## Usage

When you want to release a version of your software, whether it's a pre-release, RTM, patch, or anything else, simply create a tag with a name which is a valid [SemVer 2.0](https://semver.org/spec/v2.0.0.html) version and build your projects. MinVer will apply the version to the assemblies and packages. (If you like to prefix your tag names, see the [FAQ](#can-i-prefix-my-tag-names).)
When you want to release a version of your software, whether it's a pre-release, RTM, patch, or anything else, simply create a tag with a name which is a valid [SemVer 2.0](https://semver.org/spec/v2.0.0.html) version and build your projects. MinVer will apply the version to the assemblies and packages. (If you like to prefix your tag names, see the [FAQ](#can-i-prefix-my-tag-names).) Note that MinVer sets `AssemblyVersion` to `{MAJOR}.0.0.0`, but [this behaviour can be overridden](#can-i-use-the-version-calculated-by-minver-for-other-purposes).

When the current commit is not tagged, MinVer searches the commit history for the latest tag. If the latest tag found is a [pre-release](https://semver.org/spec/v2.0.0.html#spec-item-9), MinVer will use it as-is. If the latest tag found is RTM (not pre-release), MinVer will increase the patch number and add default pre-release identifiers, e.g. `1.0.0` becomes `1.0.1-alpha.0`. If no tag is found, the default version `0.0.0-alpha.0` is used.

Expand All @@ -43,7 +43,6 @@ Options can be specified as either MSBuild properties or environment variables.
- [`MinVerMajorMinor`](#can-i-bump-the-major-or-minor-version)
- [`MinVerTagPrefix`](#can-i-prefix-my-tag-names)
- [`MinVerVerbosity`](#can-i-control-the-logging-verbosity)
- [`MinVerVersionOverride`](#what-if-it-all-goes-wrong)

Note that the option names are case-insensitive.

Expand All @@ -63,7 +62,6 @@ _(With TL;DR answers inline.)_
- [What if the history diverges, and then converges again, before the latest tag (or root commit) is found?](#what-if-the-history-diverges-and-then-converges-again-before-the-latest-tag-or-root-commit-is-found) _(nothing bad)_
- [Why does MinVer fail with `LibGit2Sharp.NotFoundException`?](#why-does-minver-fail-with-libgit2sharpnotfoundexception) _(easy to fix)_
- [Why does MinVer fail with `System.TypeInitializationException`?](#why-does-minver-fail-with-systemtypeinitializationexception) _(easy to fix)_
- [What if it all goes wrong?](#what-if-it-all-goes-wrong) _(don't panic!)_

### Can I bump the major or minor version?

Expand Down Expand Up @@ -129,12 +127,25 @@ You can also specify build metadata in a version tag. If the tag is on the curre

### Can I use the version calculated by MinVer for other purposes?

Yes! MinVer sets both the `Version` and `PackageVersion` MSBuild properties. Use them in a target which runs after MinVer. E.g.
Yes! MinVer sets the `Version`, `PackageVersion`, `AssemblyVersion`, `FileVersion`, `MinVerMajor`, `MinVerMinor`, and `MinVerPatch` MSBuild properties. You can use them, or override their values, in a target which runs after MinVer.

For example, MinVer sets `AssemblyVersion` to `{MAJOR}.0.0.0`, as recommended in the official [open source library guidance](https://docs.microsoft.com/en-ca/dotnet/standard/library-guidance/versioning#assembly-version). For projects which do not create NuGet packages, you may want to override this behaviour and populate [all four parts](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/assembly-versioning#assembly-version-number) of `AssemblyVersion`. E.g. using Appveyor:

```xml
<Target Name="MyTarget" AfterTargets="MinVer">
<PropertyGroup>
<AssemblyVersion>$(MinVerMajor).$(MinVerMinor).$(APPVEYOR_BUILD_NUMBER).$(MinVerPatch)</AssemblyVersion>
</PropertyGroup>
</Target>
```

Or, for example, for projects which _do_ create NuGet packages, you may want to adjust the assembly file version as recommended in the official [open source library guidance](https://docs.microsoft.com/en-ca/dotnet/standard/library-guidance/versioning#assembly-file-version). E.g. when using Appveyor:

```xml
<Target Name="MyTarget" AfterTargets="MinVer">
<Message Text="Version=$(Version)" Importance="high" />
<Message Text="PackageVersion=$(PackageVersion)" Importance="high" />
<PropertyGroup>
<FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(APPVEYOR_BUILD_NUMBER)</FileVersion>
</PropertyGroup>
</Target>
```

Expand Down Expand Up @@ -174,23 +185,6 @@ You may see an exception of this form:

This is probably because you are running on Linux, and you do not have libcurl installed. See the [prerequisites](#prerequisites).

### What if it all goes wrong?

If MinVer calculates an unexpected version and you can't figure out why, but you need to ship your software in the meantime, you can specify a temporary override with [`MinVerVersionOverride`](#options).

**Important:** This is a _complete_ override which disables _all_ versioning logic in MinVer. It must include the full version, including any required [pre-release identifiers](https://semver.org/spec/v2.0.0.html#spec-item-9) and [build metadata](https://semver.org/spec/v2.0.0.html#spec-item-10).

For example, in the [Appveyor](https://www.appveyor.com/) UI, under _Settings → Environment → Environment variables_, add an environment variable named `MINVERVERSIONOVERRIDE`:

| E.g. to release: | Set the value to: |
|----------------------------------------------------------------|----------------------------------------------|
| ...the fourth beta of version 1.2.3, with build metadata | `1.2.3-beta.4+build.%APPVEYOR_BUILD_NUMBER%` |
| ...the fourth beta of version 1.2.3, without build metadata | `1.2.3-beta.4` |
| ...the stable(/final/RTM) version 1.2.3 with build metadata | `1.2.3+build.%APPVEYOR_BUILD_NUMBER%` |
| ...the stable(/final/RTM) version 1.2.3 without build metadata | `1.2.3` |

The same applies if you find a bug in MinVer (consider that a challenge!) and you're waiting for a fix.

---

<sub>[Tag](https://thenounproject.com/term/tag/938952) by [Ananth](https://thenounproject.com/ananthshas/) from [the Noun Project](https://thenounproject.com/).</sub>
2 changes: 1 addition & 1 deletion minver-cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static int Main(string[] args)

var version = GetVersion(path, tagPrefix.Value(), range, buildMetadata.Value(), level);

Console.Out.WriteLine(version);
Console.Out.WriteVersion(version);

return 0;
});
Expand Down
10 changes: 10 additions & 0 deletions minver-cli/TextWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace MinVer
{
using System.IO;
using MinVer.Lib;

internal static class TextWriterExtensions
{
public static void WriteVersion(this TextWriter writer, Version version) => writer.WriteLine(version);
}
}
14 changes: 0 additions & 14 deletions targets/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,6 @@ public static Task Main(string[] args)
throw new Exception($"'{package}' does not contain '{expected}'.");
}

Environment.SetEnvironmentVariable("MinVerVersionOverride", "3.0.0-beta.2+build.52", EnvironmentVariableTarget.Process);

DeletePackages();

await RunAsync("dotnet", "build --no-restore", path);
await RunAsync("dotnet", "pack --no-build", path);

package = Directory.EnumerateFiles(path, "*.nupkg", new EnumerationOptions { RecurseSubdirectories = true }).First();
expected = "3.0.0-beta.2.nupkg";
if (!package.Contains(expected))
{
throw new Exception($"'{package}' does not contain '{expected}'.");
}

void DeletePackages()
{
foreach (var file in Directory.EnumerateFiles(path, "*.nupkg", new EnumerationOptions { RecurseSubdirectories = true }))
Expand Down