Skip to content

Commit 05381af

Browse files
gep13JakeGinnivan
authored andcommitted
Potential fix for #173
First attempt at adding support for Stash Pull Requests. NOTE: While all the tests are passing, I haven't actually tested this on an actual Stash Server, as I don't currently have one of those :-)
1 parent 58d7af2 commit 05381af

File tree

7 files changed

+63
-71
lines changed

7 files changed

+63
-71
lines changed

AcceptanceTests/PullRequestInTeamCityTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class PullRequestInTeamCityTest
1212
const string TaggedVersion = "1.0.3";
1313

1414
[Theory]
15-
//TODO Stash support [InlineData("refs/pull-requests/5/merge-clean")]
15+
[InlineData("refs/pull-requests/5/merge-clean")]
1616
[InlineData("refs/pull/5/merge")]
1717
public void GivenARemoteWithATagOnMaster_AndAPullRequestWithTwoCommits_AndBuildIsRunningInTeamCity_VersionIsCalculatedProperly(string pullRequestRef)
1818
{

GitVersionCore/BuildServers/GitHelper.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
namespace GitVersion
22
{
3+
using LibGit2Sharp;
34
using System.Collections.Generic;
45
using System.Linq;
5-
using LibGit2Sharp;
6+
using System.Text.RegularExpressions;
67

78
public static class GitHelper
89
{
@@ -42,6 +43,42 @@ public static void NormalizeGitDirectory(string gitDirectory, Authentication aut
4243
}
4344
}
4445

46+
public static bool LooksLikeAValidPullRequestNumber(string issueNumber)
47+
{
48+
if (string.IsNullOrEmpty(issueNumber))
49+
{
50+
return false;
51+
}
52+
53+
uint res;
54+
if (!uint.TryParse(issueNumber, out res))
55+
{
56+
return false;
57+
}
58+
59+
return true;
60+
}
61+
62+
public static string ExtractIssueNumber(string mergeMessage)
63+
{
64+
// Github Message: refs/heads/pull/5/merge
65+
// Stash Message: refs/heads/pull-requests/5/merge-clean
66+
67+
string pattern = "refs/heads/pull(-requests)?/(?<issuenumber>[0-9]*)/merge(-clean)?";
68+
69+
var regex = new Regex(pattern);
70+
var match = regex.Match(mergeMessage);
71+
72+
string issueNumber = null;
73+
74+
if (match != null)
75+
{
76+
issueNumber = match.Groups["issuenumber"].Value;
77+
}
78+
79+
return issueNumber;
80+
}
81+
4582
static void AddMissingRefSpecs(Repository repo, Remote remote)
4683
{
4784
if (remote.FetchRefSpecs.Any(r => r.Source == "refs/heads/*"))
@@ -99,13 +136,13 @@ static void CreateFakeBranchPointingAtThePullRequestTip(Repository repo, Authent
99136
var canonicalName = refs[0].CanonicalName;
100137
Logger.WriteInfo(string.Format("Found remote tip '{0}' pointing at the commit '{1}'.", canonicalName, headTipSha));
101138

102-
if (!canonicalName.StartsWith("refs/pull/"))
139+
if (!canonicalName.StartsWith("refs/pull/") && !canonicalName.StartsWith("refs/pull-requests/"))
103140
{
104141
var message = string.Format("Remote tip '{0}' from remote '{1}' doesn't look like a valid pull request.", canonicalName, remote.Url);
105142
throw new WarningException(message);
106143
}
107144

108-
var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/");
145+
var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/").Replace("refs/pull-requests/", "refs/heads/pull-requests/");
109146

110147
Logger.WriteInfo(string.Format("Creating fake local branch '{0}'.", fakeBranchName));
111148
repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha));

GitVersionCore/GitFlow/BranchClassifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public static bool IsMaster(this Branch branch)
6464

6565
public static bool IsPullRequest(this Branch branch)
6666
{
67-
return branch.CanonicalName.Contains("/pull/");
67+
return branch.CanonicalName.Contains("/pull/") || branch.CanonicalName.Contains("/pull-requests/");
6868
}
6969

7070
public static bool IsSupport(this Branch branch)

GitVersionCore/GitFlow/BranchFinders/PullVersionFinder.cs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,14 @@ public SemanticVersion FindVersion(GitVersionContext context)
1414

1515
string ExtractIssueNumber(GitVersionContext context)
1616
{
17-
const string prefix = "/pull/";
18-
var pullRequestBranch = context.CurrentBranch;
17+
var issueNumber = GitHelper.ExtractIssueNumber(context.CurrentBranch.CanonicalName);
1918

20-
var start = pullRequestBranch.CanonicalName.IndexOf(prefix, System.StringComparison.Ordinal);
21-
var end = pullRequestBranch.CanonicalName.LastIndexOf("/merge", pullRequestBranch.CanonicalName.Length - 1,
22-
System.StringComparison.Ordinal);
23-
24-
string issueNumber = null;
25-
26-
if (start != -1 && end != -1 && start + prefix.Length <= end)
19+
if (!GitHelper.LooksLikeAValidPullRequestNumber(issueNumber))
2720
{
28-
start += prefix.Length;
29-
issueNumber = pullRequestBranch.CanonicalName.Substring(start, end - start);
30-
}
31-
32-
if (!LooksLikeAValidPullRequestNumber(issueNumber))
33-
{
34-
throw new WarningException(string.Format("Unable to extract pull request number from '{0}'.",
35-
pullRequestBranch.CanonicalName));
21+
throw new WarningException(string.Format("Unable to extract pull request number from '{0}'.", context.CurrentBranch.CanonicalName));
3622
}
3723

3824
return issueNumber;
3925
}
40-
41-
bool LooksLikeAValidPullRequestNumber(string issueNumber)
42-
{
43-
if (string.IsNullOrEmpty(issueNumber))
44-
{
45-
return false;
46-
}
47-
48-
uint res;
49-
if (!uint.TryParse(issueNumber, out res))
50-
{
51-
return false;
52-
}
53-
54-
return true;
55-
}
5626
}
5727
}

GitVersionCore/GitHubFlow/BuildNumberCalculator.cs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -66,47 +66,17 @@ void EnsurePullBranchShareACommonAncestorWithMaster(IRepository repository, Bran
6666
throw new Exception(message);
6767
}
6868

69-
// TODO refactor to remove duplication
7069
string ExtractIssueNumber(GitVersionContext context)
7170
{
72-
const string prefix = "/pull/";
73-
var pullRequestBranch = context.CurrentBranch;
71+
var issueNumber = GitHelper.ExtractIssueNumber(context.CurrentBranch.CanonicalName);
7472

75-
var start = pullRequestBranch.CanonicalName.IndexOf(prefix, StringComparison.Ordinal);
76-
var end = pullRequestBranch.CanonicalName.LastIndexOf("/merge", pullRequestBranch.CanonicalName.Length - 1,
77-
StringComparison.Ordinal);
78-
79-
string issueNumber = null;
80-
81-
if (start != -1 && end != -1 && start + prefix.Length <= end)
73+
if (!GitHelper.LooksLikeAValidPullRequestNumber(issueNumber))
8274
{
83-
start += prefix.Length;
84-
issueNumber = pullRequestBranch.CanonicalName.Substring(start, end - start);
85-
}
86-
87-
if (!LooksLikeAValidPullRequestNumber(issueNumber))
88-
{
89-
var message = string.Format("Unable to extract pull request number from '{0}'.", pullRequestBranch.CanonicalName);
75+
var message = string.Format("Unable to extract pull request number from '{0}'.", context.CurrentBranch.CanonicalName);
9076
throw new WarningException(message);
9177
}
9278

9379
return issueNumber;
9480
}
95-
96-
bool LooksLikeAValidPullRequestNumber(string issueNumber)
97-
{
98-
if (string.IsNullOrEmpty(issueNumber))
99-
{
100-
return false;
101-
}
102-
103-
uint res;
104-
if (!uint.TryParse(issueNumber, out res))
105-
{
106-
return false;
107-
}
108-
109-
return true;
110-
}
11181
}
11282
}

GitVersionCore/MergeMessageParser.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ public static bool TryParse(Commit mergeCommit, out string versionPart)
4747
versionPart = lastBranchPart;
4848
return true;
4949
}
50+
else if (Regex.IsMatch(message, "Merge pull request #\\d+ in "))
51+
{
52+
var branch = Regex.Match(message, "in (?<branch>.*)").Groups["branch"].Value;
53+
var lastBranchPart = branch.Split('/', '-').Last();
54+
55+
if (!char.IsNumber(lastBranchPart.First()) || !lastBranchPart.Contains("."))
56+
{
57+
return false;
58+
}
59+
60+
versionPart = lastBranchPart;
61+
return true;
62+
}
5063
else if (message.StartsWith("Merge branch '"))
5164
{
5265
trimmed = message.Replace("Merge branch '", "");

Tests/MergeMessageParserTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class MergeMessageParserTests
2020
[TestCase("Merge branch 'alpha-0.1.5'", true, "0.1.5")]
2121
[TestCase("Merge pull request #165 from Particular/release-1.0.0", true, "1.0.0")]
2222
[TestCase("Merge pull request #95 from Particular/issue-94", false, null)]
23+
[TestCase("Merge pull request #165 in Particular/release-1.0.0", true, "1.0.0")]
24+
[TestCase("Merge pull request #95 in Particular/issue-94", false, null)]
2325
public void AssertMergeMessage(string message, bool isMergeCommit, string expectedVersion)
2426
{
2527
var c = new MockCommit

0 commit comments

Comments
 (0)