diff --git a/MinVer.Lib/Version.cs b/MinVer.Lib/Version.cs index 7bd92809..66c9ef90 100644 --- a/MinVer.Lib/Version.cs +++ b/MinVer.Lib/Version.cs @@ -119,6 +119,8 @@ public Version AddBuildMetadata(string buildMetadata) return new Version(this.Major, this.Minor, this.Patch, this.preReleaseIdentifiers, this.height, $"{this.buildMetadata}{separator}{buildMetadata}"); } + public static bool TryParse(string text, out Version version) => (version = ParseOrDefault(text, default)) != default; + public static Version ParseOrDefault(string text, string prefix) => text == default || !text.StartsWith(prefix ?? "") ? default : ParseOrDefault(text.Substring(prefix?.Length ?? 0)); diff --git a/MinVer/Logger.cs b/MinVer/Logger.cs index 8849a332..fa4f6f0b 100644 --- a/MinVer/Logger.cs +++ b/MinVer/Logger.cs @@ -54,6 +54,11 @@ public static void ErrorInvalidMinMajorMinor(string minMajorMinor) => public static void ErrorInvalidVerbosity(string verbosity) => Error(1004, $"Invalid verbosity '{verbosity}'. The value must be {VerbosityMap.ValidValue}."); +#if MINVER + public static void ErrorInvalidVersionOverride(string versionOverride) => + Error(1005, $"Invalid version override '{versionOverride}'"); +#endif + private static void Error(int code, string message) => Message($"error MINVER{code:D4} : {message}"); private static void Message(string message) => Console.Error.WriteLine($"MinVer: {message}"); diff --git a/MinVer/MinVer.csproj b/MinVer/MinVer.csproj index 27582e27..df941fcc 100644 --- a/MinVer/MinVer.csproj +++ b/MinVer/MinVer.csproj @@ -1,6 +1,7 @@  + $(DefineConstants);MINVER Minimalistic versioning for .NET SDK-style projects using Git tags. true false diff --git a/MinVer/build/MinVer.targets b/MinVer/build/MinVer.targets index dee3bf26..6e189a11 100644 --- a/MinVer/build/MinVer.targets +++ b/MinVer/build/MinVer.targets @@ -18,12 +18,14 @@ + + diff --git a/README.md b/README.md index b24170c2..71060367 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ Options can be specified as either MSBuild properties or environment variables. - [`MinVerMinimumMajorMinor`](#can-i-bump-the-major-or-minor-version) (this is still named `MinVerMajorMinor` in 1.0.0-beta.1, the new name will be used in 1.0.0-beta.2) - [`MinVerTagPrefix`](#can-i-prefix-my-tag-names) - [`MinVerVerbosity`](#can-I-get-log-output-to-see-how-minver-calculates-the-version) +- [`MinVerVersionOverride`](#can-i-use-minver-to-version-software-which-is-not-built-using-a-net-sdk-style-project) Note that the option names are case-insensitive. @@ -205,6 +206,8 @@ In a future version of MinVer, the verbosity level may be inherited from MSBuild Yes! MinVer is also available as a [command line tool](https://www.nuget.org/packages/minver-cli). Run `minver --help` for usage. The calculated version is printed to standard output (stdout). +Sometimes you may want to version both .NET projects and other outputs, such as non-.NET projects, or a container image, in the same build. In those scenarios, you should use both the command line tool _and_ the regular MinVer package. Before building any .NET projects, your build script should run the command line tool and set the [`MINVERVERSIONOVERRIDE`](#options) environment variable to the calculated version. The MinVer package will then use that value rather than calculating the version a second time. This ensures that the command line tool and the MinVer package produce the same version. + ### What if the history diverges, and more than one tag is found? The tag with the higher version is used. diff --git a/minver-cli/Program.cs b/minver-cli/Program.cs index 61bbb3ff..b5f0c136 100644 --- a/minver-cli/Program.cs +++ b/minver-cli/Program.cs @@ -28,6 +28,9 @@ private static int Main(string[] args) var repoOrWorkDirOption = app.Option("-r|--repo ", "Repository or working directory.", CommandOptionType.SingleValue); var tagPrefixOption = app.Option("-t|--tag-prefix ", "", CommandOptionType.SingleValue); var verbosityOption = app.Option("-v|--verbosity ", VerbosityMap.ValidValue, CommandOptionType.SingleValue); +#if MINVER + var versionOverrideOption = app.Option("-o|--version-override ", "", CommandOptionType.SingleValue); +#endif app.OnExecute(() => { @@ -43,7 +46,25 @@ private static int Main(string[] args) log.Debug($"MinVer {informationalVersion}."); } +#if MINVER + Lib.Version version; + if (!string.IsNullOrEmpty(versionOverrideOption.Value())) + { + if (!Lib.Version.TryParse(versionOverrideOption.Value(), out version)) + { + Logger.ErrorInvalidVersionOverride(versionOverrideOption.Value()); + return 2; + } + + log.Info($"Using version override {version}."); + } + else + { + version = Versioner.GetVersion(repoOrWorkDir, tagPrefixOption.Value(), minMajorMinor, buildMetaOption.Value(), log); + } +#else var version = Versioner.GetVersion(repoOrWorkDir, tagPrefixOption.Value(), minMajorMinor, buildMetaOption.Value(), log); +#endif Console.Out.WriteLine(version); diff --git a/targets/Program.cs b/targets/Program.cs index 8e1b9ae5..0a353b3b 100644 --- a/targets/Program.cs +++ b/targets/Program.cs @@ -185,7 +185,27 @@ public static async Task Main(string[] args) } }); - Target("test-package", DependsOn("test-package-minimum-major-minor")); + Target( + "test-package-version-override", + DependsOn("test-package-minimum-major-minor"), + async () => + { + using (var repo = new Repository(testRepo)) + { + // arrange + Environment.SetEnvironmentVariable("MinVerVersionOverride", "3.2.1-rc.4+build.5", EnvironmentVariableTarget.Process); + + var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-version-override"); + + // act + await CleanAndPack(testRepo, output, "diagnostic"); + + // assert + AssertPackageFileNameContains("3.2.1-rc.4.nupkg", output); + } + }); + + Target("test-package", DependsOn("test-package-version-override")); await RunTargetsAndExitAsync(args); }