From ee52201eff8db5254299e54f93120ed4a3082851 Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Mon, 10 Jul 2017 09:54:32 +0300 Subject: [PATCH 01/12] Migrated to netcore 2.0-preview. msbuild project support instead of obsoleted project.json. Removed support for -t/-c arguments (this functionality should be implemented in the calling script). --- dotnet-bump.sln | 14 +++-- global.json | 6 -- readme.md | 41 ++++-------- src/dotnet-bump/Program.cs | 63 ++++++++++--------- src/dotnet-bump/Properties/AssemblyInfo.cs | 19 ------ .../Properties/launchSettings.json | 8 --- src/dotnet-bump/dotnet-bump.csproj | 24 +++++++ src/dotnet-bump/dotnet-bump.xproj | 21 ------- src/dotnet-bump/project.json | 31 --------- 9 files changed, 76 insertions(+), 151 deletions(-) delete mode 100644 global.json delete mode 100644 src/dotnet-bump/Properties/AssemblyInfo.cs delete mode 100644 src/dotnet-bump/Properties/launchSettings.json create mode 100644 src/dotnet-bump/dotnet-bump.csproj delete mode 100644 src/dotnet-bump/dotnet-bump.xproj delete mode 100644 src/dotnet-bump/project.json diff --git a/dotnet-bump.sln b/dotnet-bump.sln index d9a64d4..3471dcf 100644 --- a/dotnet-bump.sln +++ b/dotnet-bump.sln @@ -1,17 +1,16 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26621.2 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D45B9303-5D06-45E7-BF9A-183AA38C42E0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D88039FE-C432-42B5-B47C-9D850A1B9DAD}" ProjectSection(SolutionItems) = preProject - global.json = global.json readme.md = readme.md EndProjectSection EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-bump", "src\dotnet-bump\dotnet-bump.xproj", "{DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-bump", "src\dotnet-bump\dotnet-bump.csproj", "{DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,8 +18,8 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Debug|Any CPU.Build.0 = Release|Any CPU + {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection @@ -30,4 +29,7 @@ Global GlobalSection(NestedProjects) = preSolution {DAB044EF-EDBF-4D78-BCFF-DCC4D3B942D4} = {D45B9303-5D06-45E7-BF9A-183AA38C42E0} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B2D5EF42-9B32-4A80-88C2-A20C529E734C} + EndGlobalSection EndGlobal diff --git a/global.json b/global.json deleted file mode 100644 index 9d09ab5..0000000 --- a/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "projects": [ "src", "test" ], - "sdk": { - "version": "1.0.0-preview2-003131" - } -} diff --git a/readme.md b/readme.md index 6b51bce..dd0d868 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# dotnet-bump +# dotnet-bump-version A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. Use this command before `dotnet pack` to increment a specific part of @@ -7,36 +7,17 @@ and all your .NET Core projects in different solutions can reference the latest ## Usage -Add `dotnet bump` as a tool to your project by including the following into your `project.json`: +Add `dotnet bump` as a tool to your project by including the following into your `.csproj`: -```json -{ - "tools": - { - "dotnet-bump": "1.0.1" - } -} +```xml + + + + + ``` -Update the `scripts` section of `project.json` so that the version number is incremented before `dotnet pack`: +Run `dotnet restore` to fetch bump-version binaries, after that you may use `dotnet bump-version` command to maintain version. -```json -{ - "scripts": { - "postcompile": [ - "dotnet bump revision", - "dotnet pack ..." - ] - } -} -``` - -The command will increment a part of the version number of your `project.json` according to the argument passed to it (`major`, `minor`, `patch` or `revision`). -When this argument is ommited, the revision number is bumped. - -Alternatively, you can limit bumping the version number to a specific configuration by adding a `-t` (or `--target-configuration`) option -paired with a `-c` (or `--configuration`) option that gets its value from a macro: - -``` -dotnet bump revision -t Release -c %compile:Configuration% -``` \ No newline at end of file +The command will increment a part of the version number of your `.csproj` according to the argument passed to it (`major`, `minor`, `patch` or `revision`). +When this argument is ommited, the revision number is bumped. You may specify path to `.csproj` on the command line as nameless argument or rely on automatic discovery which would look for first `.csproj` file in the current directory. diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index 24b3e68..c03b125 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -1,24 +1,19 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Security; -using System.Threading.Tasks; -using Microsoft.DotNet.ProjectModel; -using Newtonsoft.Json; +using System.Xml.Linq; using NuGet.Versioning; namespace DotnetBump { public class Program { - public static void Main(string[] args) + public static int Main(string[] args) { string[] validParts = new[] { "major", "minor", "patch", "revision" }; string part = "revision"; - var targetConfiguration = ""; - var configuration = ""; var i = 0; + var projectFilePath = string.Empty; if (args.Length > 0) { var idx = Array.FindIndex(validParts, x => x == args[0].ToLower()); @@ -28,35 +23,42 @@ public static void Main(string[] args) i++; } } - while (i < args.Length) + try { - if (args[i] == "-t" || args[i] == "--target-configuration") + while (i < args.Length) { - i++; - targetConfiguration = args[i]; - i++; + if (File.Exists(args[i])) + { + projectFilePath = args[i]; + i++; + } + else + InvalidArgs(); } - else if (args[i] == "-c" || args[i] == "--configuration") + if (string.IsNullOrEmpty(projectFilePath)) + projectFilePath = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj").FirstOrDefault(); + if (string.IsNullOrEmpty(projectFilePath)) { - i++; - configuration = args[i]; - i++; - } - else + Console.Error.WriteLine("Cannot find project file"); InvalidArgs(); + } + } + catch (ArgumentException e) + { + Console.Error.WriteLine(e.Message); + return -1; } - if (!string.IsNullOrEmpty(targetConfiguration) && configuration != targetConfiguration) - return; - var projectFilePath = - $"{Directory.GetCurrentDirectory()}{Path.DirectorySeparatorChar}{Project.FileName}"; Console.WriteLine($"Loading project from {projectFilePath}..."); - dynamic projectFile = JsonConvert.DeserializeObject(File.ReadAllText(projectFilePath)); - var version = (string)projectFile.version; - if (string.IsNullOrEmpty(version)) + XDocument projectFile; + using (var f = File.OpenRead(projectFilePath)) + projectFile = XDocument.Load(f); + var versionElement=projectFile.Root?.Elements("PropertyGroup").Select(x=>x.Element("Version")).FirstOrDefault(); + if (string.IsNullOrEmpty(versionElement?.Value)) { Console.WriteLine("Missing project version, left unchanged"); - return; + return -1; } + var version = versionElement.Value; var suffix = version.EndsWith("-*"); if (suffix) { @@ -86,15 +88,16 @@ public static void Main(string[] args) version = newVersion.ToString(); if (suffix) version = version + "-*"; - projectFile.version = version; + versionElement.Value = version; Console.WriteLine($"Saving project...."); - File.WriteAllText(projectFilePath, JsonConvert.SerializeObject(projectFile, Formatting.Indented)); + using(var f=File.CreateText(projectFilePath))projectFile.Save(f); Console.WriteLine($"Project saved."); + return 0; } private static void InvalidArgs() { - throw new ArgumentException("Usage: dotnet bump [major | minor | patch | revision] [--configuration ] [--target-configuration ]"); + throw new ArgumentException("Usage: dotnet bump-version [major | minor | patch | revision] [path-to-project-file]"); } } } diff --git a/src/dotnet-bump/Properties/AssemblyInfo.cs b/src/dotnet-bump/Properties/AssemblyInfo.cs deleted file mode 100644 index 8f94957..0000000 --- a/src/dotnet-bump/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("dotnet_bump")] -[assembly: AssemblyTrademark("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("dab044ef-edbf-4d78-bcff-dcc4d3b942d4")] diff --git a/src/dotnet-bump/Properties/launchSettings.json b/src/dotnet-bump/Properties/launchSettings.json deleted file mode 100644 index 6c67a0e..0000000 --- a/src/dotnet-bump/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "dotnet-bump": { - "commandName": "Project", - "commandLineArgs": "aasdas" - } - } -} \ No newline at end of file diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj new file mode 100644 index 0000000..3c531a4 --- /dev/null +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -0,0 +1,24 @@ + + + + A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. + Balassa Marton, Andrey Zakharov + netcoreapp2.0 + dotnet-bump-version + Exe + dotnet-bump-version + https://github.com/killwort/dotnet-bump + http://www.opensource.org/licenses/MIT + false + false + false + dotnet-bump-version + 1.2.0 + DotnetBump.Program + + + + + + + diff --git a/src/dotnet-bump/dotnet-bump.xproj b/src/dotnet-bump/dotnet-bump.xproj deleted file mode 100644 index f3847cd..0000000 --- a/src/dotnet-bump/dotnet-bump.xproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - dab044ef-edbf-4d78-bcff-dcc4d3b942d4 - dotnet_bump - .\obj - .\bin\ - v4.6 - - - - 2.0 - - - diff --git a/src/dotnet-bump/project.json b/src/dotnet-bump/project.json deleted file mode 100644 index 52e12ba..0000000 --- a/src/dotnet-bump/project.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "version": "1.0.1-*", - "authors": [ - "Balassa Marton" - ], - "description": "A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages.", - "buildOptions": { - "emitEntryPoint": true - }, - "packOptions": { - "licenseUrl": "http://www.opensource.org/licenses/MIT", - "projectUrl": "https://github.com/BalassaMarton/dotnet-bump", - "owners": [ - "Balassa Marton" - ] - }, - "dependencies": { - "Microsoft.DotNet.ProjectModel": "1.0.0-rc3-003121", - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0" - }, - "Newtonsoft.Json": "9.0.1", - "NuGet.Client": "3.5.0-rc1-final" - }, - "frameworks": { - "netcoreapp1.0": { - "imports": "dnxcore50" - } - } -} \ No newline at end of file From a50e194f41adc8b3a972c9bfb3c151ffb6107a76 Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Wed, 29 Nov 2017 09:11:10 +0300 Subject: [PATCH 02/12] Removed dependecies on nuget libs, cleaned up stdout to have parsable format (unrelated stuff moved to stderr) --- src/dotnet-bump/Program.cs | 24 ++-- src/dotnet-bump/SemVer.cs | 177 +++++++++++++++++++++++++++++ src/dotnet-bump/dotnet-bump.csproj | 4 - 3 files changed, 189 insertions(+), 16 deletions(-) create mode 100644 src/dotnet-bump/SemVer.cs diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index c03b125..729a3ec 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using System.Xml.Linq; -using NuGet.Versioning; namespace DotnetBump { @@ -48,14 +47,14 @@ public static int Main(string[] args) Console.Error.WriteLine(e.Message); return -1; } - Console.WriteLine($"Loading project from {projectFilePath}..."); + Console.Error.WriteLine($"Loading project from {projectFilePath}..."); XDocument projectFile; using (var f = File.OpenRead(projectFilePath)) projectFile = XDocument.Load(f); var versionElement=projectFile.Root?.Elements("PropertyGroup").Select(x=>x.Element("Version")).FirstOrDefault(); if (string.IsNullOrEmpty(versionElement?.Value)) { - Console.WriteLine("Missing project version, left unchanged"); + Console.Error.WriteLine("Missing project version, left unchanged"); return -1; } var version = versionElement.Value; @@ -64,34 +63,35 @@ public static int Main(string[] args) { version = version.Substring(0, version.Length - 2); } - var oldVersion = new NuGetVersion(version); - NuGetVersion newVersion; + var oldVersion = new SemVer(version); + SemVer newVersion; switch (part) { case "major": - newVersion = new NuGetVersion(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Patch, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); + newVersion = new SemVer(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); break; case "minor": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Patch, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); break; case "patch": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor, oldVersion.Patch + 1, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build + 1, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); break; case "revision": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor, oldVersion.Patch, oldVersion.Revision + 1, oldVersion.ReleaseLabels, oldVersion.Metadata); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, oldVersion.Suffix, oldVersion.Buildvars); break; default: throw new InvalidOperationException(); } - Console.WriteLine($"Changing version from \"{oldVersion.ToString()}\" to \"{newVersion.ToString()}\""); + Console.Error.WriteLine($"Changing version from \"{oldVersion}\" to \"{newVersion}\""); version = newVersion.ToString(); if (suffix) version = version + "-*"; versionElement.Value = version; - Console.WriteLine($"Saving project...."); + Console.Error.WriteLine($"Saving project...."); using(var f=File.CreateText(projectFilePath))projectFile.Save(f); - Console.WriteLine($"Project saved."); + Console.Error.WriteLine($"Project saved."); + Console.WriteLine($"\"{oldVersion}\" to \"{newVersion}\""); return 0; } diff --git a/src/dotnet-bump/SemVer.cs b/src/dotnet-bump/SemVer.cs new file mode 100644 index 0000000..091637e --- /dev/null +++ b/src/dotnet-bump/SemVer.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace DotnetBump +{ + class SemVer : IComparable, IEquatable + { + public int Major; + public int? Minor, Build, Fix; + public string Suffix,Buildvars; + public bool IsAny; + + private static readonly Regex _semverRegex = new Regex(@"^(?[0-9]+)(\.(?[0-9]+))?(\.(?[0-9]+))?(\.(?[0-9]+))?(-(?.*))?(\+(?.*))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public SemVer(int major, int? minor, int? build, int? fix, string suffix, string buildvars) + { + Major = major; + Minor = minor; + Build = build; + Fix = fix; + Suffix = suffix; + Buildvars = buildvars; + } + + public SemVer(string src) + { + if (string.IsNullOrEmpty(src) || src == "*") + { + IsAny = true; + return; + } + var m = _semverRegex.Match(src); + if (!m.Success) + throw new FormatException($"Unparsable version string: {src}"); + Major = int.Parse(m.Groups["major"].Value); + if (m.Groups["minor"].Success) + Minor = int.Parse(m.Groups["minor"].Value); + if (m.Groups["build"].Success) + Build = int.Parse(m.Groups["build"].Value); + if (m.Groups["fix"].Success) + Fix = int.Parse(m.Groups["fix"].Value); + if (m.Groups["suffix"].Success) + Suffix = m.Groups["suffix"].Value; + if (m.Groups["buildvars"].Success) + Buildvars = m.Groups["buildvars"].Value; + } + + public bool Equals(SemVer other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Major == other.Major && Minor == other.Minor && Build == other.Build && Fix == other.Fix && string.Equals(Suffix, other.Suffix) && IsAny == other.IsAny; + } + + public int CompareTo(SemVer other) + { + if (ReferenceEquals(this, other)) return 0; + if (ReferenceEquals(null, other)) return 1; + var majorComparison = Major.CompareTo(other.Major); + if (majorComparison != 0) return majorComparison; + var minorComparison = Nullable.Compare(Minor, other.Minor); + if (minorComparison != 0) return minorComparison; + var buildComparison = Nullable.Compare(Build, other.Build); + if (buildComparison != 0) return buildComparison; + var fixComparison = Nullable.Compare(Fix, other.Fix); + if (fixComparison != 0) return fixComparison; + var suffixComparison = CompareSuffix(Suffix, other.Suffix); + if (suffixComparison != 0) return suffixComparison; + return IsAny.CompareTo(other.IsAny); + } + + private int CompareSuffix(string a, string b) + { + if (string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b)) return 0; + if (string.IsNullOrEmpty(a)) return 1; + if (string.IsNullOrEmpty(b)) return -1; + var aparts = a.Split('.'); + var bparts = b.Split('.'); + for (int i = 0, l = Math.Max(aparts.Length, bparts.Length); i < l; i++) + { + if (aparts.Length <= i) + return -1; + if (bparts.Length <= i) + return 1; + + bool ai = int.TryParse(aparts[i], out var aa), + bi = int.TryParse(bparts[i], out var bb); + if (ai && bi) + if (aa != bb) + return aa - bb; + else + continue; + if (ai) return-1; + if (bi) return 1; + var sc = string.Compare(aparts[i], bparts[i], StringComparison.Ordinal); + if (sc != 0) + return sc; + } + return 0; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((SemVer) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Major; + hashCode = (hashCode * 397) ^ Minor.GetHashCode(); + hashCode = (hashCode * 397) ^ Build.GetHashCode(); + hashCode = (hashCode * 397) ^ Fix.GetHashCode(); + hashCode = (hashCode * 397) ^ (Suffix != null ? Suffix.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ IsAny.GetHashCode(); + return hashCode; + } + } + + private sealed class SemVerEqualityComparer : IEqualityComparer + { + public bool Equals(SemVer x, SemVer y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + if (x.GetType() != y.GetType()) return false; + return x.Major == y.Major && x.Minor == y.Minor && x.Build == y.Build && x.Fix == y.Fix && string.Equals(x.Suffix, y.Suffix) && x.IsAny == y.IsAny; + } + + public int GetHashCode(SemVer obj) + { + unchecked + { + var hashCode = obj.Major; + hashCode = (hashCode * 397) ^ obj.Minor.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Build.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Fix.GetHashCode(); + hashCode = (hashCode * 397) ^ (obj.Suffix != null ? obj.Suffix.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ obj.IsAny.GetHashCode(); + return hashCode; + } + } + } + + public static IEqualityComparer SemVerComparer { get; } = new SemVerEqualityComparer(); + + public override string ToString() + { + if (IsAny) + return "*"; + string rv = Major.ToString(); + if (Minor.HasValue) + { + rv += "." + Minor.ToString(); + if (Build.HasValue) + { + rv += "." + Build.ToString(); + if (Fix.HasValue) + { + rv += "." + Fix.ToString(); + } + } + } + if (!string.IsNullOrEmpty(Suffix)) + rv += "-" + Suffix; + if (!string.IsNullOrEmpty(Buildvars)) + rv += "+" + Buildvars; + return rv; + } + } +} \ No newline at end of file diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index 3c531a4..b31f0ff 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -17,8 +17,4 @@ DotnetBump.Program - - - - From b4c618774769719ff2846ab5f5b06602fd40e2af Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Sun, 9 Oct 2022 16:29:22 +0500 Subject: [PATCH 03/12] - dotnet version updated to 6.0 - Command line arguments made pretty - Solution option added, all project files are updated within a solution - AssemblyVersion, FileVersion, Version, all three parameters are now updated --- src/dotnet-bump/Program.cs | 258 ++++++++++++++++++++--------- src/dotnet-bump/dotnet-bump.csproj | 11 +- 2 files changed, 189 insertions(+), 80 deletions(-) diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index 729a3ec..a527a80 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -1,103 +1,205 @@ using System; using System.IO; using System.Linq; +using System.Text; using System.Xml.Linq; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Threading.Tasks; +using System.Reflection; +using System.Runtime.CompilerServices; +using Microsoft.Build.Construction; -namespace DotnetBump +namespace DotnetBump; + +public class Program { - public class Program + + /// + /// Entry point of application + /// + /// + /// + public static async Task Main(string[] args) { - public static int Main(string[] args) + var rootCommand = new RootCommand($"Command line tool for version bump of dotnet applications v {Assembly.GetAssembly(typeof(Program)).GetName().Version}"); + + var partOption = new Option( + name: "--part", + description: "The part of version to be updated, supported values are major, minor, patch, revision."); + + var csprojFileOption = new Option( + name: "--csproj", + description: "The path to C# project (.csproj) file."); + + var slnFileOption = new Option( + name: "--sln", + description: "The path to solution (.sln) file."); + + rootCommand.AddOption(partOption); + rootCommand.AddOption(csprojFileOption); + rootCommand.AddOption(slnFileOption); + + rootCommand.SetHandler(async (pov, cfov) => { + //pov contains part option value + //cfov contains csproj file option value + await UpdateVersionAsync(pov, cfov); + }, partOption, csprojFileOption); + + rootCommand.SetHandler(async (pov, sfov) => { + //pov contains part option value + //sfov contains sln file option value + await UpdateVersionSolutionAsync(pov, sfov); + }, partOption, slnFileOption); + + return await rootCommand.InvokeAsync(args); + } + + private static async Task UpdateVersionAsync(object pov, object cfov) + { + await Task.Run(() => { - string[] validParts = new[] { "major", "minor", "patch", "revision" }; - string part = "revision"; - var i = 0; - var projectFilePath = string.Empty; - if (args.Length > 0) - { - var idx = Array.FindIndex(validParts, x => x == args[0].ToLower()); - if (idx >= 0) - { - part = validParts[idx]; - i++; - } - } try { - while (i < args.Length) + //Different XML version tags for csproj file + string[] versiontag_map = new[] { "Version", "AssemblyVersion", "FileVersion" }; + + string[] validParts = new[] { "major", "minor", "patch", "revision" }; + string part = "revision"; + + //Setting part + if (pov != null) { - if (File.Exists(args[i])) + var idx = Array.FindIndex(validParts, x => x == pov.ToString().ToLower()); + if (idx >= 0) { - projectFilePath = args[i]; - i++; + part = validParts[idx]; } - else - InvalidArgs(); } - if (string.IsNullOrEmpty(projectFilePath)) - projectFilePath = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj").FirstOrDefault(); - if (string.IsNullOrEmpty(projectFilePath)) + else { - Console.Error.WriteLine("Cannot find project file"); - InvalidArgs(); + Console.WriteLine($"Part is not provided, will update the {part} by default"); } - } - catch (ArgumentException e) + + //csproj file + FileInfo csprojFI = cfov as FileInfo; + if (csprojFI == null) + { + throw new ArgumentException("please provide a csproj file"); + } + + var projectFilePath = csprojFI.FullName; + + Console.WriteLine($"Loading project from {projectFilePath}..."); + XDocument projectFile; + using (var f = File.OpenRead(projectFilePath)) + projectFile = XDocument.Load(f); + + //first check for any possibility of available tags + var availableTags = projectFile.Root?.Elements("PropertyGroup").Descendants().Where(s => versiontag_map.Contains(s.Name.ToString())); + if (availableTags?.Count() <= 0) + { + Console.Error.WriteLine("Missing project version, left unchanged"); + } + else + { + StringBuilder sbVersionUpdates = new StringBuilder(); + //loop through possibilities and update + foreach (var versionElement in availableTags) + { + var version = versionElement.Value; + var suffix = version.EndsWith("-*"); + if (suffix) + { + version = version.Substring(0, version.Length - 2); + } + var oldVersion = new SemVer(version); + SemVer newVersion; + switch (part) + { + case "major": + newVersion = new SemVer(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + break; + case "minor": + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + break; + case "patch": + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build + 1, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + break; + case "revision": + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, oldVersion.Suffix, oldVersion.Buildvars); + break; + default: + throw new InvalidOperationException(); + + } + //Console.Error.WriteLine($"Changing version from \"{oldVersion}\" to \"{newVersion}\""); + version = newVersion.ToString(); + if (suffix) + version = version + "-*"; + versionElement.Value = version; + + + //update string builder to reflect version change + sbVersionUpdates.AppendLine($"{versionElement.Name.ToString()} updated from \"{oldVersion}\" to \"{newVersion}\""); + } + + Console.Error.WriteLine($"Saving project...."); + using (var f = File.CreateText(projectFilePath)) + { + projectFile.Save(f); + } + Console.Error.WriteLine($"Project saved."); + Console.WriteLine(sbVersionUpdates.ToString()); + } + }catch (Exception exp) { - Console.Error.WriteLine(e.Message); - return -1; + var old_color = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(exp.Message); + Console.WriteLine(exp.StackTrace); + Console.ForegroundColor = old_color; } - Console.Error.WriteLine($"Loading project from {projectFilePath}..."); - XDocument projectFile; - using (var f = File.OpenRead(projectFilePath)) - projectFile = XDocument.Load(f); - var versionElement=projectFile.Root?.Elements("PropertyGroup").Select(x=>x.Element("Version")).FirstOrDefault(); - if (string.IsNullOrEmpty(versionElement?.Value)) + }); + } + + private static async Task UpdateVersionSolutionAsync(object pov, object sfov) + { + await Task.Run(async () => + { + //csproj file + FileInfo slnjFI = sfov as FileInfo; + if (slnjFI == null) { - Console.Error.WriteLine("Missing project version, left unchanged"); - return -1; + throw new ArgumentException("please provide an sln file"); } - var version = versionElement.Value; - var suffix = version.EndsWith("-*"); - if (suffix) + + var solutionFilePath = slnjFI.FullName; + + var sfData = SolutionFile.Parse(solutionFilePath); + + var projectsInSolution = sfData.ProjectsInOrder; + foreach (var project in projectsInSolution) { - version = version.Substring(0, version.Length - 2); + switch (project.ProjectType) + { + case SolutionProjectType.KnownToBeMSBuildFormat: + { + await UpdateVersionAsync(pov, new FileInfo(project.AbsolutePath)); + break; + } + case SolutionProjectType.SolutionFolder: + { + Console.WriteLine("Another solution file found, skipping it"); + break; + } + } } - var oldVersion = new SemVer(version); - SemVer newVersion; - switch (part) - { - case "major": - newVersion = new SemVer(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); - break; - case "minor": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); - break; - case "patch": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build + 1, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); - break; - case "revision": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, oldVersion.Suffix, oldVersion.Buildvars); - break; - default: - throw new InvalidOperationException(); + }); + } - } - Console.Error.WriteLine($"Changing version from \"{oldVersion}\" to \"{newVersion}\""); - version = newVersion.ToString(); - if (suffix) - version = version + "-*"; - versionElement.Value = version; - Console.Error.WriteLine($"Saving project...."); - using(var f=File.CreateText(projectFilePath))projectFile.Save(f); - Console.Error.WriteLine($"Project saved."); - Console.WriteLine($"\"{oldVersion}\" to \"{newVersion}\""); - return 0; - } - - private static void InvalidArgs() - { - throw new ArgumentException("Usage: dotnet bump-version [major | minor | patch | revision] [path-to-project-file]"); - } + private static void InvalidArgs() + { + throw new ArgumentException("Usage: dotnet bump-version [major | minor | patch | revision] [path-to-project-file]"); } } diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index b31f0ff..ee8ed85 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -3,7 +3,7 @@ A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. Balassa Marton, Andrey Zakharov - netcoreapp2.0 + net6.0 dotnet-bump-version Exe dotnet-bump-version @@ -13,8 +13,15 @@ false false dotnet-bump-version - 1.2.0 + 2.0.0 DotnetBump.Program + 2.0.0 + 2.0.0 + + + + + From 44f0867e4bc4a0440d9f012996f7fb93a396fe79 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Sun, 9 Oct 2022 17:35:45 +0500 Subject: [PATCH 04/12] Docker file added + some fixes --- .dockerignore | 25 ++++++++++++++++ .gitignore | 1 + Dockerfile | 20 +++++++++++++ dotnet-bump.sln | 5 ++-- src/dotnet-bump/Program.cs | 46 ++++++++++++++++-------------- src/dotnet-bump/dotnet-bump.csproj | 3 ++ 6 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1c9a181..566ffcf 100644 --- a/.gitignore +++ b/.gitignore @@ -240,3 +240,4 @@ ModelManifest.xml # FAKE - F# Make .fake/ +/src/dotnet-bump/Properties/launchSettings.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d1b8c9e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["src/dotnet-bump/dotnet-bump.csproj", "src/dotnet-bump/"] +RUN dotnet restore "src/dotnet-bump/dotnet-bump.csproj" +COPY . . +WORKDIR "/src/src/dotnet-bump" +RUN dotnet build "dotnet-bump.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "dotnet-bump.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "dotnet-bump-version.dll"] \ No newline at end of file diff --git a/dotnet-bump.sln b/dotnet-bump.sln index 3471dcf..5f364f3 100644 --- a/dotnet-bump.sln +++ b/dotnet-bump.sln @@ -1,12 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26621.2 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32811.315 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D45B9303-5D06-45E7-BF9A-183AA38C42E0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D88039FE-C432-42B5-B47C-9D850A1B9DAD}" ProjectSection(SolutionItems) = preProject + Dockerfile = Dockerfile readme.md = readme.md EndProjectSection EndProject diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index a527a80..0bbdfeb 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -36,10 +36,15 @@ public static async Task Main(string[] args) name: "--sln", description: "The path to solution (.sln) file."); - rootCommand.AddOption(partOption); + var partArgument = new Argument( + name: "part", + description: "The part of version to be updated, supported values are major, minor, patch, revision."); + + rootCommand.AddArgument(partArgument); rootCommand.AddOption(csprojFileOption); rootCommand.AddOption(slnFileOption); + rootCommand.SetHandler(async (pov, cfov) => { //pov contains part option value //cfov contains csproj file option value @@ -169,30 +174,29 @@ await Task.Run(async () => { //csproj file FileInfo slnjFI = sfov as FileInfo; - if (slnjFI == null) + if (slnjFI != null) { - throw new ArgumentException("please provide an sln file"); - } + //throw new ArgumentException("please provide a sln file"); + var solutionFilePath = slnjFI.FullName; - var solutionFilePath = slnjFI.FullName; + var sfData = SolutionFile.Parse(solutionFilePath); - var sfData = SolutionFile.Parse(solutionFilePath); - - var projectsInSolution = sfData.ProjectsInOrder; - foreach (var project in projectsInSolution) - { - switch (project.ProjectType) + var projectsInSolution = sfData.ProjectsInOrder; + foreach (var project in projectsInSolution) { - case SolutionProjectType.KnownToBeMSBuildFormat: - { - await UpdateVersionAsync(pov, new FileInfo(project.AbsolutePath)); - break; - } - case SolutionProjectType.SolutionFolder: - { - Console.WriteLine("Another solution file found, skipping it"); - break; - } + switch (project.ProjectType) + { + case SolutionProjectType.KnownToBeMSBuildFormat: + { + await UpdateVersionAsync(pov, new FileInfo(project.AbsolutePath)); + break; + } + case SolutionProjectType.SolutionFolder: + { + Console.WriteLine("Another solution file found, skipping it"); + break; + } + } } } }); diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index ee8ed85..a723fd2 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -17,10 +17,13 @@ DotnetBump.Program 2.0.0 2.0.0 + Linux + ..\.. + From 6fcce9e95151c964a3724175ae23a3d38ab13caf Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Sun, 9 Oct 2022 17:40:34 +0500 Subject: [PATCH 05/12] argument fix --- src/dotnet-bump/Program.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index 0bbdfeb..403c16d 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -24,10 +24,6 @@ public static async Task Main(string[] args) { var rootCommand = new RootCommand($"Command line tool for version bump of dotnet applications v {Assembly.GetAssembly(typeof(Program)).GetName().Version}"); - var partOption = new Option( - name: "--part", - description: "The part of version to be updated, supported values are major, minor, patch, revision."); - var csprojFileOption = new Option( name: "--csproj", description: "The path to C# project (.csproj) file."); @@ -49,13 +45,13 @@ public static async Task Main(string[] args) //pov contains part option value //cfov contains csproj file option value await UpdateVersionAsync(pov, cfov); - }, partOption, csprojFileOption); + }, partArgument, csprojFileOption); rootCommand.SetHandler(async (pov, sfov) => { //pov contains part option value //sfov contains sln file option value await UpdateVersionSolutionAsync(pov, sfov); - }, partOption, slnFileOption); + }, partArgument, slnFileOption); return await rootCommand.InvokeAsync(args); } From 12a88ae7cc3fb65d6c02df5a683698debef1a9e6 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Mon, 10 Oct 2022 17:18:12 +0500 Subject: [PATCH 06/12] Readme updated --- readme.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/readme.md b/readme.md index dd0d868..b389fd5 100644 --- a/readme.md +++ b/readme.md @@ -5,8 +5,38 @@ placed in different solutions, referencing each other as NuGet packages. Use thi the version number in `project.json` before pushing your project to your local NuGet feed. This ensures that NuGet will not fetch the package from cache, and all your .NET Core projects in different solutions can reference the latest compiled version. +## Whats new in v 2.0.0 +- Upgraded to dotnet 6.0 +- Interface for command line is upgraded to `System.CommandLine`, for pretty command line options +- Solution file support added, use `--sln` option with `.sln` file and it will update all available `.csproj` files +- `Version`, `AssemblyVersion` and `FileVersion` is now searched and updated in `.csproj` file +- `Docker` support added, can be handy to be used in `CI/CD` pipelines + ## Usage +### Version 2.0.0 + +```sh +D:\Checkout\dotnet-bump\src\dotnet-bump\bin\Debug\net6.0>dotnet dotnet-bump-version.dll +Required argument missing for command: 'dotnet-bump-version'. + +Description: + Command line tool for version bump of dotnet applications v 2.0.0.0 + +Usage: + dotnet-bump-version [options] + +Arguments: + The part of version to be updated, supported values are major, minor, patch, revision. + +Options: + --csproj The path to C# project (.csproj) file. + --sln The path to solution (.sln) file. + --version Show version information + -?, -h, --help Show help and usage information +``` + +### Older versions Add `dotnet bump` as a tool to your project by including the following into your `.csproj`: ```xml From 531c832618898d551e8f67062bd1f979e13e0133 Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Tue, 11 Oct 2022 05:21:15 +0300 Subject: [PATCH 07/12] Multitarget --- src/dotnet-bump/Program.cs | 3 ++- src/dotnet-bump/dotnet-bump.csproj | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index 403c16d..e2fcfdc 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -10,7 +10,7 @@ using System.Runtime.CompilerServices; using Microsoft.Build.Construction; -namespace DotnetBump; +namespace DotnetBump{ public class Program { @@ -203,3 +203,4 @@ private static void InvalidArgs() throw new ArgumentException("Usage: dotnet bump-version [major | minor | patch | revision] [path-to-project-file]"); } } +} \ No newline at end of file diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index a723fd2..eba273d 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -3,7 +3,7 @@ A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. Balassa Marton, Andrey Zakharov - net6.0 + net5.0;net6.0;netcoreapp3.1 dotnet-bump-version Exe dotnet-bump-version @@ -13,12 +13,13 @@ false false dotnet-bump-version - 2.0.0 + 2.0.1 DotnetBump.Program - 2.0.0 - 2.0.0 + 2.0.1 + 2.0.1 Linux ..\.. + 10 From 7b66c3837b6abcfc3238448985f08f2557cfdc54 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Fri, 18 Nov 2022 15:13:24 +0500 Subject: [PATCH 08/12] - --csproj issue fixed - --suffix option is added --- readme.md | 18 +++-- src/dotnet-bump/Program.cs | 110 ++++++++++++++++++----------- src/dotnet-bump/dotnet-bump.csproj | 4 +- 3 files changed, 80 insertions(+), 52 deletions(-) diff --git a/readme.md b/readme.md index b389fd5..dbe06af 100644 --- a/readme.md +++ b/readme.md @@ -12,16 +12,17 @@ and all your .NET Core projects in different solutions can reference the latest - `Version`, `AssemblyVersion` and `FileVersion` is now searched and updated in `.csproj` file - `Docker` support added, can be handy to be used in `CI/CD` pipelines +## Whats new in v 2.0.1 +- Bugfix, when `--csproj` is provided it doesn't work +- `--suffix` command line option is added + ## Usage -### Version 2.0.0 +### Version 2.0.1 ```sh -D:\Checkout\dotnet-bump\src\dotnet-bump\bin\Debug\net6.0>dotnet dotnet-bump-version.dll -Required argument missing for command: 'dotnet-bump-version'. - Description: - Command line tool for version bump of dotnet applications v 2.0.0.0 + Command line tool for version bump of dotnet applications v 2.0.1.0 Usage: dotnet-bump-version [options] @@ -30,8 +31,11 @@ Arguments: The part of version to be updated, supported values are major, minor, patch, revision. Options: - --csproj The path to C# project (.csproj) file. - --sln The path to solution (.sln) file. + --suffix The suffix to be appended to version, it would be appended to version with leading -. e.g. if + suffix is set to 'rc1' final version would be x.x.x.x-rc1 + --csproj The path to C# project (.csproj) file. This option will be given precedence over --sln if both are + provided at same time. + --sln The path to solution (.sln) file. If --csproj is provided, this option will be ignored. --version Show version information -?, -h, --help Show help and usage information ``` diff --git a/src/dotnet-bump/Program.cs b/src/dotnet-bump/Program.cs index 403c16d..0bbeb37 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -26,37 +26,44 @@ public static async Task Main(string[] args) var csprojFileOption = new Option( name: "--csproj", - description: "The path to C# project (.csproj) file."); + description: "The path to C# project (.csproj) file. This option will be given precedence over --sln if both are provided at same time."); var slnFileOption = new Option( name: "--sln", - description: "The path to solution (.sln) file."); + description: "The path to solution (.sln) file. If --csproj is provided, this option will be ignored."); var partArgument = new Argument( name: "part", description: "The part of version to be updated, supported values are major, minor, patch, revision."); + var suffixOption = new Option( + name: "--suffix", + description: "The suffix to be appended to version, it would be appended to version with leading -. e.g. if suffix is set to 'rc1' final version would be x.x.x.x-rc1" + ); + rootCommand.AddArgument(partArgument); + rootCommand.AddOption(suffixOption); rootCommand.AddOption(csprojFileOption); rootCommand.AddOption(slnFileOption); - - rootCommand.SetHandler(async (pov, cfov) => { - //pov contains part option value - //cfov contains csproj file option value - await UpdateVersionAsync(pov, cfov); - }, partArgument, csprojFileOption); - - rootCommand.SetHandler(async (pov, sfov) => { + rootCommand.SetHandler(async (pov, sfov, cfov, sfxov) => { //pov contains part option value //sfov contains sln file option value - await UpdateVersionSolutionAsync(pov, sfov); - }, partArgument, slnFileOption); + //cfov contains csproj file option value + //sfxov contains suffix option value + await UpdateVersionSolutionAsync(pov, sfov, cfov, sfxov); + }, partArgument, slnFileOption, csprojFileOption, suffixOption); return await rootCommand.InvokeAsync(args); } - private static async Task UpdateVersionAsync(object pov, object cfov) + /// + /// Update a csproj file + /// + /// + /// + /// + private static async Task UpdateProjectVersionAsync(object pov, object cfov, object sfxov) { await Task.Run(() => { @@ -115,20 +122,24 @@ await Task.Run(() => version = version.Substring(0, version.Length - 2); } var oldVersion = new SemVer(version); + + //check for suffix, if that is provided give precidence to it + string newSuffix = sfxov?.ToString() ?? oldVersion.Suffix; + SemVer newVersion; switch (part) { case "major": - newVersion = new SemVer(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + newVersion = new SemVer(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Build, oldVersion.Fix, newSuffix, oldVersion.Buildvars); break; case "minor": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Build, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Build, oldVersion.Fix, newSuffix, oldVersion.Buildvars); break; case "patch": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build + 1, oldVersion.Fix, oldVersion.Suffix, oldVersion.Buildvars); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build + 1, oldVersion.Fix, newSuffix, oldVersion.Buildvars); break; case "revision": - newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, oldVersion.Suffix, oldVersion.Buildvars); + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, newSuffix, oldVersion.Buildvars); break; default: throw new InvalidOperationException(); @@ -164,42 +175,55 @@ await Task.Run(() => }); } - private static async Task UpdateVersionSolutionAsync(object pov, object sfov) + /// + /// Iterate a solution file and update all included csproj files + /// + /// + /// + /// + private static async Task UpdateVersionSolutionAsync(object pov, object sfov, object cfov, object sfxov) { await Task.Run(async () => { - //csproj file - FileInfo slnjFI = sfov as FileInfo; - if (slnjFI != null) + //Check if csproj file is provided, give precedence to it. + FileInfo csprojFI = cfov as FileInfo; + if (csprojFI != null) { - //throw new ArgumentException("please provide a sln file"); - var solutionFilePath = slnjFI.FullName; + if (csprojFI != null) + { + await UpdateProjectVersionAsync(pov, csprojFI, sfxov); + } + } + else + { + //sln file + FileInfo slnjFI = sfov as FileInfo; + if (slnjFI != null) + { + //throw new ArgumentException("please provide a sln file"); + var solutionFilePath = slnjFI.FullName; - var sfData = SolutionFile.Parse(solutionFilePath); + var sfData = SolutionFile.Parse(solutionFilePath); - var projectsInSolution = sfData.ProjectsInOrder; - foreach (var project in projectsInSolution) - { - switch (project.ProjectType) + var projectsInSolution = sfData.ProjectsInOrder; + foreach (var project in projectsInSolution) { - case SolutionProjectType.KnownToBeMSBuildFormat: - { - await UpdateVersionAsync(pov, new FileInfo(project.AbsolutePath)); - break; - } - case SolutionProjectType.SolutionFolder: - { - Console.WriteLine("Another solution file found, skipping it"); - break; - } + switch (project.ProjectType) + { + case SolutionProjectType.KnownToBeMSBuildFormat: + { + await UpdateProjectVersionAsync(pov, new FileInfo(project.AbsolutePath), sfxov); + break; + } + case SolutionProjectType.SolutionFolder: + { + Console.WriteLine("Another solution file found, skipping it"); + break; + } + } } } } }); } - - private static void InvalidArgs() - { - throw new ArgumentException("Usage: dotnet bump-version [major | minor | patch | revision] [path-to-project-file]"); - } } diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index a723fd2..da7b8f1 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -15,8 +15,8 @@ dotnet-bump-version 2.0.0 DotnetBump.Program - 2.0.0 - 2.0.0 + 2.0.1 + 2.0.1 Linux ..\.. From 7595f4f1b311633e0c0db571b9f1cd44565fb086 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Fri, 18 Nov 2022 15:25:26 +0500 Subject: [PATCH 09/12] version fix --- src/dotnet-bump/dotnet-bump.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index eba273d..ac8201c 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -3,7 +3,7 @@ A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. Balassa Marton, Andrey Zakharov - net5.0;net6.0;netcoreapp3.1 + net6.0 dotnet-bump-version Exe dotnet-bump-version From e98dbbc5f622ccdd265b3c6a9c3facaa37a27617 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Fri, 18 Nov 2022 18:45:11 +0500 Subject: [PATCH 10/12] targeting only dotnet 6.0 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 566ffcf..680b556 100644 --- a/.gitignore +++ b/.gitignore @@ -241,3 +241,4 @@ ModelManifest.xml # FAKE - F# Make .fake/ /src/dotnet-bump/Properties/launchSettings.json +/src/dotnet-bump/Properties/PublishProfiles/FolderProfile.pubxml From 5f918c33f4117043c4bb378adfb98b8f6f239863 Mon Sep 17 00:00:00 2001 From: Muhammad Ummar Iqbal Date: Fri, 18 Nov 2022 18:45:51 +0500 Subject: [PATCH 11/12] dotnet 6.0 as a target --- src/dotnet-bump/dotnet-bump.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index ac8201c..e305e41 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -1,9 +1,9 @@ - + + net6.0 A dotnet-cli command that bumps the version number of the current project. This is useful when working with multiple .NET Core projects placed in different solutions, referencing each other as NuGet packages. Balassa Marton, Andrey Zakharov - net6.0 dotnet-bump-version Exe dotnet-bump-version From 9fe668d684c1b296494c136e7ce2023a1e33c2d2 Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Fri, 18 Nov 2022 19:12:25 +0300 Subject: [PATCH 12/12] Version bump --- src/dotnet-bump/dotnet-bump.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dotnet-bump/dotnet-bump.csproj b/src/dotnet-bump/dotnet-bump.csproj index e305e41..b8ecf1e 100644 --- a/src/dotnet-bump/dotnet-bump.csproj +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -13,10 +13,10 @@ false false dotnet-bump-version - 2.0.1 + 2.0.2 DotnetBump.Program - 2.0.1 - 2.0.1 + 2.0.2 + 2.0.2 Linux ..\.. 10