diff --git a/GitVersion.sln.DotSettings b/GitVersion.sln.DotSettings index 3d44c2079e..74fd05fb95 100644 --- a/GitVersion.sln.DotSettings +++ b/GitVersion.sln.DotSettings @@ -141,6 +141,167 @@ CHOP_ALWAYS True True + <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> + <TypePattern DisplayName="COM interfaces or structs"> + <TypePattern.Match> + <Or> + <And> + <Kind Is="Interface" /> + <Or> + <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> + <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> + </Or> + </And> + <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" /> + </Or> + </TypePattern.Match> + </TypePattern> + + <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> + <TypePattern.Match> + <And> + <Kind Is="Class" /> + <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.TestCaseFixtureAttribute" Inherited="true" /> + </And> + </TypePattern.Match> + + <Entry DisplayName="Setup/Teardown Methods"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <Or> + <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="true" /> + </Or> + </And> + </Entry.Match> + </Entry> + + <Entry DisplayName="All other members" /> + + <Entry DisplayName="Test Methods" Priority="100"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <HasAttribute Name="NUnit.Framework.TestAttribute" Inherited="false" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </TypePattern> + + <TypePattern DisplayName="Default Pattern"> + <Entry DisplayName="Public Delegates" Priority="100"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Delegate" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Public Enums" Priority="100"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Enum" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Static Fields and Constants"> + <Entry.Match> + <Or> + <Kind Is="Constant" /> + <And> + <Kind Is="Field" /> + <Static /> + </And> + </Or> + </Entry.Match> + + <Entry.SortBy> + <Kind> + <Kind.Order> + <DeclarationKind>Constant</DeclarationKind> + <DeclarationKind>Field</DeclarationKind> + </Kind.Order> + </Kind> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Fields"> + <Entry.Match> + <And> + <Kind Is="Field" /> + <Not> + <Static /> + </Not> + </And> + </Entry.Match> + + <Entry.SortBy> + <Readonly /> + <Name /> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Constructors"> + <Entry.Match> + <Kind Is="Constructor" /> + </Entry.Match> + + <Entry.SortBy> + <Static/> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Properties, Indexers"> + <Entry.Match> + <Or> + <Kind Is="Property" /> + <Kind Is="Indexer" /> + </Or> + </Entry.Match> + </Entry> + + <Entry DisplayName="Interface Implementations" Priority="100"> + <Entry.Match> + <And> + <Kind Is="Member" /> + <ImplementsInterface /> + </And> + </Entry.Match> + + <Entry.SortBy> + <ImplementsInterface Immediate="true" /> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="All other members" /> + + <Entry DisplayName="Nested Types"> + <Entry.Match> + <Kind Is="Type" /> + </Entry.Match> + </Entry> + </TypePattern> +</Patterns> + <?xml version="1.0" encoding="utf-8" ?> <!-- @@ -405,7 +566,9 @@ II.2.12 <HandlesEvent /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True True + True True True False diff --git a/GitVersionCore.Tests/GitVersionCore.Tests.csproj b/GitVersionCore.Tests/GitVersionCore.Tests.csproj index 3ac0dd7621..847367eaa5 100644 --- a/GitVersionCore.Tests/GitVersionCore.Tests.csproj +++ b/GitVersionCore.Tests/GitVersionCore.Tests.csproj @@ -74,12 +74,14 @@ + + diff --git a/GitVersionCore.Tests/IntegrationTests/GitFlow/FeatureBranchTests.cs b/GitVersionCore.Tests/IntegrationTests/GitFlow/FeatureBranchTests.cs new file mode 100644 index 0000000000..2ddfc6106c --- /dev/null +++ b/GitVersionCore.Tests/IntegrationTests/GitFlow/FeatureBranchTests.cs @@ -0,0 +1,23 @@ +using GitVersion; +using LibGit2Sharp; +using NUnit.Framework; + +[TestFixture] +public class FeatureBranchTests +{ + [Test] + public void ShouldNotUseNumberInFeatureBranchAsPreReleaseNumber() + { + using (var fixture = new EmptyRepositoryFixture(new Config())) + { + fixture.Repository.MakeATaggedCommit("1.0.0"); + fixture.Repository.CreateBranch("develop"); + fixture.Repository.Checkout("develop"); + fixture.Repository.CreateBranch("feature/JIRA-123"); + fixture.Repository.Checkout("feature/JIRA-123"); + fixture.Repository.MakeCommits(5); + + fixture.AssertFullSemver("1.1.0-JIRA-123+5"); + } + } +} \ No newline at end of file diff --git a/GitVersionCore.Tests/IntegrationTests/GitHubFlow/FeatureBranchTests.cs b/GitVersionCore.Tests/IntegrationTests/GitHubFlow/FeatureBranchTests.cs new file mode 100644 index 0000000000..89ed765c93 --- /dev/null +++ b/GitVersionCore.Tests/IntegrationTests/GitHubFlow/FeatureBranchTests.cs @@ -0,0 +1,38 @@ +using GitVersion; +using LibGit2Sharp; +using NUnit.Framework; + +namespace GitVersionCore.Tests.IntegrationTests.GitHubFlow +{ + [TestFixture] + public class FeatureBranchTests + { + [Test] + public void ShouldNotUseNumberInFeatureBranchAsPreReleaseNumber() + { + using (var fixture = new EmptyRepositoryFixture(new Config())) + { + fixture.Repository.MakeATaggedCommit("1.0.0"); + fixture.Repository.CreateBranch("feature/JIRA-123"); + fixture.Repository.Checkout("feature/JIRA-123"); + fixture.Repository.MakeCommits(5); + + fixture.AssertFullSemver("1.0.1-JIRA-123+5"); + } + } + + [Test] + public void TestFeatureBranch() + { + using (var fixture = new EmptyRepositoryFixture(new Config())) + { + fixture.Repository.MakeATaggedCommit("1.0.0"); + fixture.Repository.CreateBranch("feature-test"); + fixture.Repository.Checkout("feature-test"); + fixture.Repository.MakeCommits(5); + + fixture.AssertFullSemver("1.0.1-feature-test+5"); + } + } + } +} \ No newline at end of file diff --git a/GitVersionCore.Tests/SemanticVersionTests.cs b/GitVersionCore.Tests/SemanticVersionTests.cs index 2561ced7a2..e9b674b7d9 100644 --- a/GitVersionCore.Tests/SemanticVersionTests.cs +++ b/GitVersionCore.Tests/SemanticVersionTests.cs @@ -10,6 +10,8 @@ public class SemanticVersionTests [TestCase("1.2", 1, 2, 0, null, null, null, null, null, null, "1.2.0")] [TestCase("1.2.3-beta", 1, 2, 3, "beta", null, null, null, null, null, null)] [TestCase("1.2.3-beta3", 1, 2, 3, "beta", 3, null, null, null, null, "1.2.3-beta.3")] + [TestCase("1.2.3-beta.3", 1, 2, 3, "beta", 3, null, null, null, null, "1.2.3-beta.3")] + [TestCase("1.2.3-beta-3", 1, 2, 3, "beta-3", null, null, null, null, null, "1.2.3-beta-3")] [TestCase("1.2.3-alpha", 1, 2, 3, "alpha", null, null, null, null, null, null)] [TestCase("1.2-alpha4", 1, 2, 0, "alpha", 4, null, null, null, null, "1.2.0-alpha.4")] [TestCase("1.2.3-rc", 1, 2, 3, "rc", null, null, null, null, null, null)] diff --git a/GitVersionCore/GitHubFlow/NextSemverCalculator.cs b/GitVersionCore/GitHubFlow/NextSemverCalculator.cs index 9be2747f5a..0ef2409bea 100644 --- a/GitVersionCore/GitHubFlow/NextSemverCalculator.cs +++ b/GitVersionCore/GitHubFlow/NextSemverCalculator.cs @@ -26,20 +26,17 @@ public NextSemverCalculator( public SemanticVersion NextVersion() { - var versions = GetPossibleVersions().ToList(); - - if (versions.Any()) - { - return versions.Max(); - } - return new SemanticVersion - { - Minor = 1 - }; + return GetPossibleVersions().Max(); } public IEnumerable GetPossibleVersions() { + // always provide a minimum fallback version for other strategies + var defaultNextVersion = new SemanticVersion + { + Minor = 1 + }; + yield return defaultNextVersion; VersionTaggedCommit lastTaggedRelease; if (lastTaggedReleaseFinder.GetVersion(out lastTaggedRelease)) @@ -50,12 +47,13 @@ public IEnumerable GetPossibleVersions() yield return lastTaggedRelease.SemVer; yield break; } - yield return new SemanticVersion - { - Major = lastTaggedRelease.SemVer.Major, - Minor = lastTaggedRelease.SemVer.Minor, - Patch = lastTaggedRelease.SemVer.Patch + 1 - }; + defaultNextVersion = new SemanticVersion + { + Major = lastTaggedRelease.SemVer.Major, + Minor = lastTaggedRelease.SemVer.Minor, + Patch = lastTaggedRelease.SemVer.Patch + 1 + }; + yield return defaultNextVersion; } SemanticVersion fileVersion; @@ -82,7 +80,7 @@ public IEnumerable GetPossibleVersions() } SemanticVersion otherBranchVersion; - if (unknownBranchFinder.FindVersion(context, out otherBranchVersion)) + if (unknownBranchFinder.FindVersion(context, defaultNextVersion, out otherBranchVersion)) { yield return otherBranchVersion; } diff --git a/GitVersionCore/GitHubFlow/OtherBranchVersionFinder.cs b/GitVersionCore/GitHubFlow/OtherBranchVersionFinder.cs index b2af983173..0fd3c92709 100644 --- a/GitVersionCore/GitHubFlow/OtherBranchVersionFinder.cs +++ b/GitVersionCore/GitHubFlow/OtherBranchVersionFinder.cs @@ -1,24 +1,25 @@ namespace GitVersion { + using System; using System.Linq; - using LibGit2Sharp; class OtherBranchVersionFinder { - public bool FindVersion(GitVersionContext context, out SemanticVersion semanticVersion) + public bool FindVersion(GitVersionContext context, SemanticVersion defaultNextVersion, out SemanticVersion semanticVersion) { - var versionString = GetUnknownBranchSuffix(context.CurrentBranch); - if (!versionString.Contains(".")) + var versionInBranch = GetVersionInBranch(context); + if (versionInBranch == null) { + if (!context.CurrentBranch.IsMaster()) + defaultNextVersion.PreReleaseTag = context.CurrentBranch.Name.Split('/').Last(); semanticVersion = null; + return false; } - var shortVersion = SemanticVersion.Parse(versionString, context.Configuration.TagPrefix); - - var applicableTagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(context.Configuration, shortVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name, context.Configuration.TagPrefix)).ToList(); + var applicableTagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(context.Configuration, versionInBranch.Item2).OrderByDescending(tag => SemanticVersion.Parse(tag.Name, context.Configuration.TagPrefix)).ToList(); var nbHotfixCommits = BranchCommitDifferenceFinder.NumberOfCommitsSinceLastTagOrBranchPoint(context, applicableTagsInDescendingOrder, BranchType.Unknown, "master"); - var semanticVersionPreReleaseTag = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, applicableTagsInDescendingOrder) ?? CreateDefaultPreReleaseTag(context, versionString); + var semanticVersionPreReleaseTag = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, applicableTagsInDescendingOrder) ?? CreateDefaultPreReleaseTag(context, versionInBranch.Item1); if (semanticVersionPreReleaseTag.Name == "release") @@ -28,28 +29,35 @@ public bool FindVersion(GitVersionContext context, out SemanticVersion semanticV semanticVersion = new SemanticVersion { - Major = shortVersion.Major, - Minor = shortVersion.Minor, - Patch = shortVersion.Patch, + Major = versionInBranch.Item2.Major, + Minor = versionInBranch.Item2.Minor, + Patch = versionInBranch.Item2.Patch, PreReleaseTag = semanticVersionPreReleaseTag, BuildMetaData = new SemanticVersionBuildMetaData(nbHotfixCommits, context.CurrentBranch.Name, context.CurrentCommit.Sha, context.CurrentCommit.When()) }; return true; } - SemanticVersionPreReleaseTag CreateDefaultPreReleaseTag(GitVersionContext context, string versionString) + Tuple GetVersionInBranch(GitVersionContext context) { - return context.CurrentBranch.Name - .Replace("-" + versionString, string.Empty) - .Replace("/" + versionString, string.Empty) + ".1"; + var branchParts = context.CurrentBranch.Name.Split('/', '-'); + foreach (var part in branchParts) + { + SemanticVersion semanticVersion; + if (SemanticVersion.TryParse(part, context.Configuration.TagPrefix, out semanticVersion)) + { + return Tuple.Create(part, semanticVersion); + } + } + + return null; } - static string GetUnknownBranchSuffix(Branch branch) + SemanticVersionPreReleaseTag CreateDefaultPreReleaseTag(GitVersionContext context, string versionString) { - var unknownBranchSuffix = branch.Name.Split('-', '/'); - if (unknownBranchSuffix.Length == 1) - return branch.Name; - return unknownBranchSuffix[1]; + return context.CurrentBranch.Name + .Replace("/" + versionString, string.Empty) + .Replace("-" + versionString, string.Empty) + ".1"; } } diff --git a/GitVersionCore/SemanticVersionPreReleaseTag.cs b/GitVersionCore/SemanticVersionPreReleaseTag.cs index c6cb4b2d19..f24b0a13f9 100644 --- a/GitVersionCore/SemanticVersionPreReleaseTag.cs +++ b/GitVersionCore/SemanticVersionPreReleaseTag.cs @@ -6,9 +6,6 @@ namespace GitVersion public class SemanticVersionPreReleaseTag : IFormattable, IComparable, IEquatable { - public string Name; - public int? Number; - static LambdaEqualityHelper equalityHelper = new LambdaEqualityHelper(x => x.Name, x => x.Number); @@ -21,6 +18,8 @@ public SemanticVersionPreReleaseTag(string name, int? number) Name = name; Number = number; } + public string Name { get; set; } + public int? Number { get; set; } public override bool Equals(object obj) { @@ -91,8 +90,12 @@ public static SemanticVersionPreReleaseTag Parse(string preReleaseTag) return new SemanticVersionPreReleaseTag(); } - return new SemanticVersionPreReleaseTag(match.Groups["name"].Value, - match.Groups["number"].Success ? int.Parse(match.Groups["number"].Value) : (int?) null); + var value = match.Groups["name"].Value; + var number = match.Groups["number"].Success ? int.Parse(match.Groups["number"].Value) : (int?) null; + if (value.EndsWith("-")) + return new SemanticVersionPreReleaseTag(preReleaseTag, null); + + return new SemanticVersionPreReleaseTag(value, number); } public int CompareTo(SemanticVersionPreReleaseTag other)