-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement a bitbucket link builder (#39)
* feat: implement a bitbucket link builder * chore: correct domain for test * fix: support com and org domains for bitbucket
- Loading branch information
1 parent
28b67ec
commit 60df2da
Showing
3 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
198 changes: 198 additions & 0 deletions
198
Versionize.Tests/Changelog/BitbucketLinkBuilderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
using System; | ||
using System.Data; | ||
using System.Linq; | ||
using LibGit2Sharp; | ||
using NuGet.Versioning; | ||
using Shouldly; | ||
using Versionize.Tests.TestSupport; | ||
using Xunit; | ||
|
||
namespace Versionize.Changelog.Tests | ||
{ | ||
public class BitBucketLinkBuilderTests | ||
{ | ||
private readonly string sshOrgPushUrl = "git@bitbucket.org:mobiloitteinc/dotnet-codebase.git"; | ||
private readonly string sshComPushUrl = "git@bitbucket.com:mobiloitteinc/dotnet-codebase.git"; | ||
private readonly string httpsOrgPushUrl = "https://saintedlama@bitbucket.org/mobiloitteinc/dotnet-codebase.git"; | ||
private readonly string httpsComPushUrl = "https://saintedlama@bitbucket.com/mobiloitteinc/dotnet-codebase.git"; | ||
|
||
[Fact] | ||
public void ShouldThrowIfUrlIsNoRecognizedSshOrHttpsUrl() | ||
{ | ||
Should.Throw<InvalidOperationException>(() => new BitbucketLinkBuilder("bitbucket.org")); | ||
} | ||
|
||
[Fact] | ||
public void ShouldThrowIfUrlIsNoValidHttpsCloneUrl() | ||
{ | ||
Should.Throw<InvalidOperationException>(() => new BitbucketLinkBuilder("https://saintedlama@bitbucket.org/")); | ||
} | ||
|
||
[Fact] | ||
public void ShouldThrowIfUrlIsNoValidSshCloneUrl() | ||
{ | ||
Should.Throw<InvalidOperationException>(() => new BitbucketLinkBuilder("git@bitbucket.org:mobiloitteinc")); | ||
} | ||
|
||
[Fact] | ||
public void ShouldCreateAnOrgBitbucketUrlBuilderForHTTPSPushUrls() | ||
{ | ||
var repo = SetupRepositoryWithRemote("origin", httpsOrgPushUrl); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<BitbucketLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldCreateAComBitbucketUrlBuilderForHTTPSPushUrls() | ||
{ | ||
var repo = SetupRepositoryWithRemote("origin", httpsComPushUrl); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<BitbucketLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldCreateAnOrgBitbucketUrlBuilderForSSHPushUrls() | ||
{ | ||
var repo = SetupRepositoryWithRemote("origin", sshOrgPushUrl); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<BitbucketLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldCreateAComBitbucketUrlBuilderForSSHPushUrls() | ||
{ | ||
var repo = SetupRepositoryWithRemote("origin", sshComPushUrl); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<BitbucketLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldPickFirstRemoteInCaseNoOriginWasFound() | ||
{ | ||
var repo = SetupRepositoryWithRemote("some", sshOrgPushUrl); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<BitbucketLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldFallbackToNoopInCaseNoBitbucketPushUrlWasDefined() | ||
{ | ||
var repo = SetupRepositoryWithRemote("origin", "https://hostmeister.com/saintedlama/versionize.git"); | ||
var linkBuilder = LinkBuilderFactory.CreateFor(repo); | ||
|
||
linkBuilder.ShouldBeAssignableTo<PlainLinkBuilder>(); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAnOrgSSHCommitLink() | ||
{ | ||
var commit = new ConventionalCommit | ||
{ | ||
Sha = "734713bc047d87bf7eac9674765ae793478c50d3" | ||
}; | ||
|
||
var linkBuilder = new BitbucketLinkBuilder(sshOrgPushUrl); | ||
var link = linkBuilder.BuildCommitLink(commit); | ||
|
||
link.ShouldBe("https://bitbucket.org/mobiloitteinc/dotnet-codebase/commits/734713bc047d87bf7eac9674765ae793478c50d3"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAComSSHCommitLink() | ||
{ | ||
var commit = new ConventionalCommit | ||
{ | ||
Sha = "734713bc047d87bf7eac9674765ae793478c50d3" | ||
}; | ||
|
||
var linkBuilder = new BitbucketLinkBuilder(sshComPushUrl); | ||
var link = linkBuilder.BuildCommitLink(commit); | ||
|
||
link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/commits/734713bc047d87bf7eac9674765ae793478c50d3"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAnOrgHTTPSCommitLink() | ||
{ | ||
var commit = new ConventionalCommit | ||
{ | ||
Sha = "734713bc047d87bf7eac9674765ae793478c50d3" | ||
}; | ||
|
||
var linkBuilder = new BitbucketLinkBuilder(httpsOrgPushUrl); | ||
var link = linkBuilder.BuildCommitLink(commit); | ||
|
||
link.ShouldBe("https://bitbucket.org/mobiloitteinc/dotnet-codebase/commits/734713bc047d87bf7eac9674765ae793478c50d3"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAComHTTPSCommitLink() | ||
{ | ||
var commit = new ConventionalCommit | ||
{ | ||
Sha = "734713bc047d87bf7eac9674765ae793478c50d3" | ||
}; | ||
|
||
var linkBuilder = new BitbucketLinkBuilder(httpsComPushUrl); | ||
var link = linkBuilder.BuildCommitLink(commit); | ||
|
||
link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/commits/734713bc047d87bf7eac9674765ae793478c50d3"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAnOrgSSHTagLink() | ||
{ | ||
var linkBuilder = new BitbucketLinkBuilder(sshOrgPushUrl); | ||
var link = linkBuilder.BuildVersionTagLink(new SemanticVersion(1, 0, 0)); | ||
|
||
link.ShouldBe("https://bitbucket.org/mobiloitteinc/dotnet-codebase/src/v1.0.0"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAComSSHTagLink() | ||
{ | ||
var linkBuilder = new BitbucketLinkBuilder(sshComPushUrl); | ||
var link = linkBuilder.BuildVersionTagLink(new SemanticVersion(1, 0, 0)); | ||
|
||
link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/src/v1.0.0"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAnOrgHTTPSTagLink() | ||
{ | ||
var linkBuilder = new BitbucketLinkBuilder(httpsOrgPushUrl); | ||
var link = linkBuilder.BuildVersionTagLink(new SemanticVersion(1, 0, 0)); | ||
|
||
link.ShouldBe("https://bitbucket.org/mobiloitteinc/dotnet-codebase/src/v1.0.0"); | ||
} | ||
|
||
[Fact] | ||
public void ShouldBuildAComHTTPSTagLink() | ||
{ | ||
var linkBuilder = new BitbucketLinkBuilder(httpsComPushUrl); | ||
var link = linkBuilder.BuildVersionTagLink(new SemanticVersion(1, 0, 0)); | ||
|
||
link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/src/v1.0.0"); | ||
} | ||
|
||
private static Repository SetupRepositoryWithRemote(string remoteName, string pushUrl) | ||
{ | ||
var workingDirectory = TempDir.Create(); | ||
var repo = TempRepository.Create(workingDirectory); | ||
|
||
foreach (var existingRemoteName in repo.Network.Remotes.Select(remote => remote.Name)) | ||
{ | ||
repo.Network.Remotes.Remove(existingRemoteName); | ||
} | ||
|
||
repo.Network.Remotes.Add(remoteName, pushUrl); | ||
|
||
return repo; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System; | ||
using System.Text.RegularExpressions; | ||
using Version = NuGet.Versioning.SemanticVersion; | ||
|
||
namespace Versionize.Changelog | ||
{ | ||
// TODO: Accept both .org and .com extensions | ||
public class BitbucketLinkBuilder : IChangelogLinkBuilder | ||
{ | ||
private const string OrgSshPrefix = "git@bitbucket.org:"; | ||
private const string ComSshPrefix = "git@bitbucket.com:"; | ||
|
||
private readonly string _organization; | ||
private readonly string _repository; | ||
private readonly string _domain; | ||
|
||
public BitbucketLinkBuilder(string pushUrl) | ||
{ | ||
if (pushUrl.StartsWith(OrgSshPrefix) || pushUrl.StartsWith(ComSshPrefix)) | ||
{ | ||
var httpsPattern = new Regex("^git@bitbucket\\.(?<domain>org|com):(?<organization>.*?)/(?<repository>.*?)(?:\\.git)?$"); | ||
var matches = httpsPattern.Match(pushUrl); | ||
|
||
if (!matches.Success) | ||
{ | ||
throw new InvalidOperationException($"Remote url {pushUrl} is not recognized as valid Bitbucket SSH pattern"); | ||
} | ||
|
||
_organization = matches.Groups["organization"].Value; | ||
_repository = matches.Groups["repository"].Value; | ||
_domain = matches.Groups["domain"].Value; | ||
} | ||
else if (IsHttpsPushUrl(pushUrl)) | ||
{ | ||
var httpsPattern = new Regex("^https://.*?bitbucket\\.(?<domain>org|com)/(?<organization>.*?)/(?<repository>.*?)(?:\\.git)?$"); | ||
var matches = httpsPattern.Match(pushUrl); | ||
|
||
if (!matches.Success) | ||
{ | ||
throw new InvalidOperationException($"Remote url {pushUrl} is not recognized as valid Bitbucket HTTPS pattern"); | ||
} | ||
|
||
_organization = matches.Groups["organization"].Value; | ||
_repository = matches.Groups["repository"].Value; | ||
_domain = matches.Groups["domain"].Value; | ||
} | ||
else | ||
{ | ||
throw new InvalidOperationException($"Remote url {pushUrl} is not recognized as Bitbucket SSH or HTTPS url"); | ||
} | ||
} | ||
|
||
public static bool IsPushUrl(string pushUrl) | ||
{ | ||
return pushUrl.StartsWith(ComSshPrefix) || pushUrl.StartsWith(OrgSshPrefix) || IsHttpsPushUrl(pushUrl); | ||
} | ||
|
||
public string BuildVersionTagLink(Version version) | ||
{ | ||
return $"https://bitbucket.{_domain}/{_organization}/{_repository}/src/v{version}"; | ||
} | ||
|
||
public string BuildCommitLink(ConventionalCommit commit) | ||
{ | ||
return $"https://bitbucket.{_domain}/{_organization}/{_repository}/commits/{commit.Sha}"; | ||
} | ||
|
||
private static bool IsHttpsPushUrl(string pushUrl) | ||
{ | ||
return new Regex("^https://.*?@bitbucket\\.(org|com)/.*$").IsMatch(pushUrl); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters