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..680b556 100644 --- a/.gitignore +++ b/.gitignore @@ -240,3 +240,5 @@ ModelManifest.xml # FAKE - F# Make .fake/ +/src/dotnet-bump/Properties/launchSettings.json +/src/dotnet-bump/Properties/PublishProfiles/FolderProfile.pubxml 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 d9a64d4..5f364f3 100644 --- a/dotnet-bump.sln +++ b/dotnet-bump.sln @@ -1,17 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# 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 - global.json = global.json + Dockerfile = Dockerfile 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 +19,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 +30,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..dbe06af 100644 --- a/readme.md +++ b/readme.md @@ -1,42 +1,57 @@ -# 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 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 + +## Whats new in v 2.0.1 +- Bugfix, when `--csproj` is provided it doesn't work +- `--suffix` command line option is added + ## Usage -Add `dotnet bump` as a tool to your project by including the following into your `project.json`: +### Version 2.0.1 -```json -{ - "tools": - { - "dotnet-bump": "1.0.1" - } -} -``` +```sh +Description: + Command line tool for version bump of dotnet applications v 2.0.1.0 -Update the `scripts` section of `project.json` so that the version number is incremented before `dotnet pack`: - -```json -{ - "scripts": { - "postcompile": [ - "dotnet bump revision", - "dotnet pack ..." - ] - } -} -``` +Usage: + dotnet-bump-version [options] -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. +Arguments: + The part of version to be updated, supported values are major, minor, patch, revision. -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: +Options: + --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 +``` + +### Older versions +Add `dotnet bump` as a tool to your project by including the following into your `.csproj`: +```xml + + + + + ``` -dotnet bump revision -t Release -c %compile:Configuration% -``` \ No newline at end of file + +Run `dotnet restore` to fetch bump-version binaries, after that you may use `dotnet bump-version` command to maintain version. + +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..031d51f 100644 --- a/src/dotnet-bump/Program.cs +++ b/src/dotnet-bump/Program.cs @@ -1,100 +1,230 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Security; +using System.Text; +using System.Xml.Linq; +using System.CommandLine; +using System.CommandLine.Invocation; using System.Threading.Tasks; -using Microsoft.DotNet.ProjectModel; -using Newtonsoft.Json; -using NuGet.Versioning; +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) + { + var rootCommand = new RootCommand($"Command line tool for version bump of dotnet applications v {Assembly.GetAssembly(typeof(Program)).GetName().Version}"); + + var csprojFileOption = new Option( + name: "--csproj", + 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. 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, sfov, cfov, sfxov) => { + //pov contains part option value + //sfov contains sln file option value + //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); + } + + /// + /// Update a csproj file + /// + /// + /// + /// + private static async Task UpdateProjectVersionAsync(object pov, object cfov, object sfxov) { - public static void Main(string[] args) + await Task.Run(() => { - string[] validParts = new[] { "major", "minor", "patch", "revision" }; - string part = "revision"; - var targetConfiguration = ""; - var configuration = ""; - var i = 0; - if (args.Length > 0) + try { - var idx = Array.FindIndex(validParts, x => x == args[0].ToLower()); - if (idx >= 0) + //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) { - part = validParts[idx]; - i++; + var idx = Array.FindIndex(validParts, x => x == pov.ToString().ToLower()); + if (idx >= 0) + { + part = validParts[idx]; + } } - } - while (i < args.Length) - { - if (args[i] == "-t" || args[i] == "--target-configuration") + else { - i++; - targetConfiguration = args[i]; - i++; + Console.WriteLine($"Part is not provided, will update the {part} by default"); } - else if (args[i] == "-c" || args[i] == "--configuration") + + //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) { - i++; - configuration = args[i]; - i++; + Console.Error.WriteLine("Missing project version, left unchanged"); } else - InvalidArgs(); - } - 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)) + { + 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); + + //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, newSuffix, oldVersion.Buildvars); + break; + case "minor": + 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, newSuffix, oldVersion.Buildvars); + break; + case "revision": + newVersion = new SemVer(oldVersion.Major, oldVersion.Minor, oldVersion.Build, oldVersion.Fix + 1, newSuffix, 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.WriteLine("Missing project version, left unchanged"); - return; + var old_color = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(exp.Message); + Console.WriteLine(exp.StackTrace); + Console.ForegroundColor = old_color; } - var suffix = version.EndsWith("-*"); - if (suffix) + }); + } + + /// + /// 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 () => + { + //Check if csproj file is provided, give precedence to it. + FileInfo csprojFI = cfov as FileInfo; + if (csprojFI != null) { - version = version.Substring(0, version.Length - 2); + if (csprojFI != null) + { + await UpdateProjectVersionAsync(pov, csprojFI, sfxov); + } } - var oldVersion = new NuGetVersion(version); - NuGetVersion newVersion; - switch (part) + else { - case "major": - newVersion = new NuGetVersion(oldVersion.Major + 1, oldVersion.Minor, oldVersion.Patch, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); - break; - case "minor": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor + 1, oldVersion.Patch, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); - break; - case "patch": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor, oldVersion.Patch + 1, oldVersion.Revision, oldVersion.ReleaseLabels, oldVersion.Metadata); - break; - case "revision": - newVersion = new NuGetVersion(oldVersion.Major, oldVersion.Minor, oldVersion.Patch, oldVersion.Revision + 1, oldVersion.ReleaseLabels, oldVersion.Metadata); - break; - default: - throw new InvalidOperationException(); + //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 projectsInSolution = sfData.ProjectsInOrder; + foreach (var project in projectsInSolution) + { + 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; + } + } + } + } } - Console.WriteLine($"Changing version from \"{oldVersion.ToString()}\" to \"{newVersion.ToString()}\""); - version = newVersion.ToString(); - if (suffix) - version = version + "-*"; - projectFile.version = version; - Console.WriteLine($"Saving project...."); - File.WriteAllText(projectFilePath, JsonConvert.SerializeObject(projectFile, Formatting.Indented)); - Console.WriteLine($"Project saved."); - } - - private static void InvalidArgs() - { - throw new ArgumentException("Usage: dotnet bump [major | minor | patch | revision] [--configuration ] [--target-configuration ]"); - } + }); } } +} \ No newline at end of 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/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 new file mode 100644 index 0000000..b8ecf1e --- /dev/null +++ b/src/dotnet-bump/dotnet-bump.csproj @@ -0,0 +1,31 @@ + + + + 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 + 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 + 2.0.2 + DotnetBump.Program + 2.0.2 + 2.0.2 + Linux + ..\.. + 10 + + + + + + + + + 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