diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..078295e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contribution Guidelines + +This repository uses [GitFlow] with default configuration. +Development is happening on `develop` branch. + +To contribute: + +* Fork this repository. +* Create a feature branch from `develop`. +* Implement your changes. +* Push your feature branch. +* Create a pull request. + +## Build + +To build this package we are using Cake. + +On Windows PowerShell run: + +```powershell +./build +``` + +On OSX/Linux run: + +```bash +./build.sh +``` + +## Release + +See [Cake.Recipe documentation] how to create a new release of this addin. + +[GitFlow]: (http://nvie.com/posts/a-successful-git-branching-model/) +[Cake.Recipe documentation]: https://cake-contrib.github.io/Cake.Recipe/docs/usage/creating-release \ No newline at end of file diff --git a/README.md b/README.md index 148e634..9f28123 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ More about Cake at http://cakebuild.net |Develop|Master| |:--:|:--:| -|[![Build status](https://ci.appveyor.com/api/projects/status/xxx/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-prca-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/xxx/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-prca-pullrequests-tfs/branch/master)| +|[![Build status](https://ci.appveyor.com/api/projects/status/dkrcp7kxms885j3m/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-prca-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/dkrcp7kxms885j3m/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-prca-pullrequests-tfs/branch/master)| ## Code Coverage @@ -34,19 +34,9 @@ Come join in the conversation about Cake Pull Request Code Analysis in our Gitte [![Join the chat at https://gitter.im/cake-contrib/Lobby](https://badges.gitter.im/cake-contrib/Lobby.svg)](https://gitter.im/cake-contrib/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -## Build +## Contributing -To build this package we are using Cake. - -On Windows PowerShell run: - -```powershell -./build -``` - -On OSX/Linux run: - -```bash -./build.sh -``` +Contributions are welcome. See [Contribution Guidelines]. +[Cake Pull Request Code Analysis Addin]: https://github.com/cake-contrib/Cake.Prca +[Contribution Guidelines]: CONTRIBUTING.md \ No newline at end of file diff --git a/nuspec/nuget/Cake.Prca.PullRequests.Tfs.nuspec b/nuspec/nuget/Cake.Prca.PullRequests.Tfs.nuspec index ffff462..20d239f 100644 --- a/nuspec/nuget/Cake.Prca.PullRequests.Tfs.nuspec +++ b/nuspec/nuget/Cake.Prca.PullRequests.Tfs.nuspec @@ -2,7 +2,7 @@ Cake.Prca.PullRequests.Tfs - TFS and VSTS support for Cake Pull Request Code Analysis + Cake.Prca.PullRequests.Tfs 0.0.0 BBT Software AG bbtsoftware, pascalberger, cake-contrib @@ -14,9 +14,9 @@ false Copyright © 2017 BBT Software AG, Root/Zermatt, Switzerland Cake Script PullRequest CodeAnalysis Cake-Prca-PullRequestSystem TFS VSTS Linting - https://github.com/cake-contrib/Cake.Prca.PullRequests.Tfs/releases/tag/0.2.2 + https://github.com/cake-contrib/Cake.Prca.PullRequests.Tfs/releases/tag/0.3.0 - + diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/AuthenticationProviderTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/AuthenticationProviderTests.cs index 87b3d86..f6da863 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/AuthenticationProviderTests.cs +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/AuthenticationProviderTests.cs @@ -15,7 +15,7 @@ public void Should_Return_PrcaNtlmCredentials_Object() var credentials = AuthenticationProvider.AuthenticationNtlm(); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } } @@ -88,7 +88,7 @@ public void Should_Return_PrcaBasicCredentials_Object() var credentials = AuthenticationProvider.AuthenticationBasic("foo", "bar"); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } [Fact] @@ -101,8 +101,8 @@ public void Should_Set_User_Name() var credentials = AuthenticationProvider.AuthenticationBasic(userName, "bar"); // Then - credentials.ShouldBeOfType(); - ((PrcaBasicCredentials)credentials).UserName.ShouldBe(userName); + credentials.ShouldBeOfType(); + ((TfsBasicCredentials)credentials).UserName.ShouldBe(userName); } [Fact] @@ -115,8 +115,8 @@ public void Should_Set_Password() var credentials = AuthenticationProvider.AuthenticationBasic("foo", password); // Then - credentials.ShouldBeOfType(); - ((PrcaBasicCredentials)credentials).Password.ShouldBe(password); + credentials.ShouldBeOfType(); + ((TfsBasicCredentials)credentials).Password.ShouldBe(password); } } @@ -159,7 +159,7 @@ public void Should_Return_PrcaBasicCredentials_Object() var credentials = AuthenticationProvider.AuthenticationPersonalAccessToken("foo"); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } [Fact] @@ -172,9 +172,9 @@ public void Should_Set_Personal_Access_Token() var credentials = AuthenticationProvider.AuthenticationPersonalAccessToken(personalAccessToken); // Then - credentials.ShouldBeOfType(); - ((PrcaBasicCredentials)credentials).UserName.ShouldBe(string.Empty); - ((PrcaBasicCredentials)credentials).Password.ShouldBe(personalAccessToken); + credentials.ShouldBeOfType(); + ((TfsBasicCredentials)credentials).UserName.ShouldBe(string.Empty); + ((TfsBasicCredentials)credentials).Password.ShouldBe(personalAccessToken); } } @@ -217,7 +217,7 @@ public void Should_Return_PrcaOAuthCredentials_Object() var credentials = AuthenticationProvider.AuthenticationOAuth("foo"); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } [Fact] @@ -230,8 +230,8 @@ public void Should_Set_Access_Token() var credentials = AuthenticationProvider.AuthenticationOAuth(accessToken); // Then - credentials.ShouldBeOfType(); - ((PrcaOAuthCredentials)credentials).AccessToken.ShouldBe(accessToken); + credentials.ShouldBeOfType(); + ((TfsOAuthCredentials)credentials).AccessToken.ShouldBe(accessToken); } } @@ -304,7 +304,7 @@ public void Should_Return_PrcaAadCredentials_Object() var credentials = AuthenticationProvider.AuthenticationAzureActiveDirectory("foo", "bar"); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } [Fact] @@ -317,8 +317,8 @@ public void Should_Set_User_Name() var credentials = AuthenticationProvider.AuthenticationAzureActiveDirectory(userName, "bar"); // Then - credentials.ShouldBeOfType(); - ((PrcaAadCredentials)credentials).UserName.ShouldBe(userName); + credentials.ShouldBeOfType(); + ((TfsAadCredentials)credentials).UserName.ShouldBe(userName); } [Fact] @@ -331,8 +331,8 @@ public void Should_Set_Password() var credentials = AuthenticationProvider.AuthenticationAzureActiveDirectory("foo", password); // Then - credentials.ShouldBeOfType(); - ((PrcaAadCredentials)credentials).Password.ShouldBe(password); + credentials.ShouldBeOfType(); + ((TfsAadCredentials)credentials).Password.ShouldBe(password); } } } diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaAadCredentialsTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaAadCredentialsTests.cs index 394852e..80abe1b 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaAadCredentialsTests.cs +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaAadCredentialsTests.cs @@ -16,7 +16,7 @@ public sealed class ThePrcaAadCredentialsCtor public void Should_Set_User_Name(string userName) { // When - var credentials = new PrcaAadCredentials(userName, "bar"); + var credentials = new TfsAadCredentials(userName, "bar"); // Then credentials.UserName.ShouldBe(userName); @@ -30,7 +30,7 @@ public void Should_Set_User_Name(string userName) public void Should_Set_Password_Name(string password) { // When - var credentials = new PrcaAadCredentials("foo", password); + var credentials = new TfsAadCredentials("foo", password); // Then credentials.Password.ShouldBe(password); diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaBasicCredentialsTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaBasicCredentialsTests.cs index 8e8ab91..519b24e 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaBasicCredentialsTests.cs +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaBasicCredentialsTests.cs @@ -16,7 +16,7 @@ public sealed class ThePrcaBasicCredentialsCtor public void Should_Set_User_Name(string userName) { // When - var credentials = new PrcaBasicCredentials(userName, "bar"); + var credentials = new TfsBasicCredentials(userName, "bar"); // Then credentials.UserName.ShouldBe(userName); @@ -30,7 +30,7 @@ public void Should_Set_User_Name(string userName) public void Should_Set_Password_Name(string password) { // When - var credentials = new PrcaBasicCredentials("foo", password); + var credentials = new TfsBasicCredentials("foo", password); // Then credentials.Password.ShouldBe(password); diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaNtlmCredentialsTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaNtlmCredentialsTests.cs index 32f217f..0a5079e 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaNtlmCredentialsTests.cs +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaNtlmCredentialsTests.cs @@ -12,10 +12,10 @@ public sealed class ThePrcaNtlmCredentialsCtor public void Should_Not_Throw() { // Given / When - var credentials = new PrcaNtlmCredentials(); + var credentials = new TfsNtlmCredentials(); // Then - credentials.ShouldBeOfType(); + credentials.ShouldBeOfType(); } } } diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaOAuthCredentialsTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaOAuthCredentialsTests.cs index e02afed..b9b0b11 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaOAuthCredentialsTests.cs +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Authentication/PrcaOAuthCredentialsTests.cs @@ -12,7 +12,7 @@ public sealed class ThePrcaOAuthCredentialsCtor public void Should_Throw_If_Access_Token_Is_Null() { // Given / When - var result = Record.Exception(() => new PrcaOAuthCredentials(null)); + var result = Record.Exception(() => new TfsOAuthCredentials(null)); // Then result.IsArgumentNullException("accessToken"); @@ -22,7 +22,7 @@ public void Should_Throw_If_Access_Token_Is_Null() public void Should_Throw_If_Access_Token_Is_Empty() { // Given / When - var result = Record.Exception(() => new PrcaOAuthCredentials(string.Empty)); + var result = Record.Exception(() => new TfsOAuthCredentials(string.Empty)); // Then result.IsArgumentOutOfRangeException("accessToken"); @@ -32,7 +32,7 @@ public void Should_Throw_If_Access_Token_Is_Empty() public void Should_Throw_If_Access_Token_Is_WhiteSpace() { // Given / When - var result = Record.Exception(() => new PrcaOAuthCredentials(" ")); + var result = Record.Exception(() => new TfsOAuthCredentials(" ")); // Then result.IsArgumentOutOfRangeException("accessToken"); @@ -45,7 +45,7 @@ public void Should_Set_Access_Token() const string accessToken = "foo"; // When - var credentials = new PrcaOAuthCredentials(accessToken); + var credentials = new TfsOAuthCredentials(accessToken); // Then credentials.AccessToken.ShouldBe(accessToken); diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/Cake.Prca.PullRequests.Tfs.Tests.csproj b/src/Cake.Prca.PullRequests.Tfs.Tests/Cake.Prca.PullRequests.Tfs.Tests.csproj index ebb13f5..a0764c5 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/Cake.Prca.PullRequests.Tfs.Tests.csproj +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/Cake.Prca.PullRequests.Tfs.Tests.csproj @@ -39,6 +39,10 @@ ..\packages\Cake.Core.0.16.2\lib\net45\Cake.Core.dll True + + ..\packages\Cake.Prca.0.3.0\lib\net45\Cake.Prca.dll + True + ..\packages\Cake.Testing.0.16.2\lib\net45\Cake.Testing.dll True @@ -78,9 +82,9 @@ + - diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/ContentProviderTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/ContentProviderTests.cs new file mode 100644 index 0000000..25ccdac --- /dev/null +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/ContentProviderTests.cs @@ -0,0 +1,71 @@ +namespace Cake.Prca.PullRequests.Tfs.Tests +{ + using System; + using Issues; + using Shouldly; + using Xunit; + + public class ContentProviderTests + { + public sealed class TheGetContentClass + { + [Theory] + [InlineData( + @"foo.cs", + 123, + "Some message", + 1, + "foo", + null, + "foo: Some message")] + [InlineData( + @"foo.cs", + 123, + "Some message", + 1, + "", + null, + "Some message")] + [InlineData( + @"foo.cs", + 123, + "Some message", + 1, + " ", + null, + "Some message")] + [InlineData( + @"foo.cs", + 123, + "Some message", + 1, + "foo", + "http://google.com", + "[foo](http://google.com/): Some message")] + public void Should_Return_Correct_Value( + string filePath, + int? line, + string message, + int priority, + string rule, + string ruleUrl, + string expectedResult) + { + // Given + Uri ruleUri = null; + if (!string.IsNullOrWhiteSpace(ruleUrl)) + { + ruleUri = new Uri(ruleUrl); + } + + var issue = new CodeAnalysisIssue(filePath, line, message, priority, rule, ruleUri, "Foo"); + + // When + var result = ContentProvider.GetContent(issue); + + // Then + result.ShouldBe(expectedResult); + } + } + } +} diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/RepositoryDescriptionTests.cs b/src/Cake.Prca.PullRequests.Tfs.Tests/RepositoryDescriptionTests.cs deleted file mode 100644 index ed825d1..0000000 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/RepositoryDescriptionTests.cs +++ /dev/null @@ -1,140 +0,0 @@ -namespace Cake.Prca.PullRequests.Tfs.Tests -{ - using System; - using Shouldly; - using Xunit; - - public class RepositoryDescriptionTests - { - [Theory] - [InlineData( - @"http://myserver:8080/tfs/defaultcollection/myproject/", - "No valid Git repository URL.")] - [InlineData( - @"http://myserver:8080/tfs/defaultcollection/myproject/_git", - "No valid Git repository URL.")] - [InlineData( - @"http://myserver:8080/_git/myrepository", - "No valid Git repository URL containing default collection and project name.")] - [InlineData( - @"http://myserver:8080/defaultcollection/_git/myrepository", - "No valid Git repository URL containing default collection and project name.")] - public void Should_Throw_If_No_Valid_Url(string repoUrl, string expectedMessage) - { - // Given / When - var result = Record.Exception(() => new RepositoryDescription(new Uri(repoUrl))); - - // Then - result.IsUriFormatExceptionException(expectedMessage); - } - - [Theory] - [InlineData( - @"http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"http://myserver:8080/tfs/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"http://tfs.myserver/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"http://tfs.myserver/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"http://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"http://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"http://tfs.foo.com/foo/foo/_git/foo", - "foo", - @"http://tfs.foo.com/foo", - "foo", - "foo")] - [InlineData( - @"http://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository/somethingelse", - "defaultcollection", - @"http://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"https://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://myserver:8080/tfs/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"https://tfs.myserver/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://tfs.myserver/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"https://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"https://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository/somethingelse", - "defaultcollection", - @"https://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"https://tfs.foo.com/foo/foo/_git/foo", - "foo", - @"https://tfs.foo.com/foo", - "foo", - "foo")] - [InlineData( - @"ssh://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://myserver:8080/tfs/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"ssh://tfs.myserver/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://tfs.myserver/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"ssh://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"ssh://mytenant.visualstudio.com/defaultcollection/myproject/_git/myrepository/somethingelse", - "defaultcollection", - @"https://mytenant.visualstudio.com/defaultcollection", - "myproject", - "myrepository")] - [InlineData( - @"ssh://tfs.foo.com/foo/foo/_git/foo", - "foo", - @"https://tfs.foo.com/foo", - "foo", - "foo")] - [InlineData( - @"ssh://foo:bar@myserver:8080/tfs/defaultcollection/myproject/_git/myrepository", - "defaultcollection", - @"https://myserver:8080/tfs/defaultcollection", - "myproject", - "myrepository")] - public void Should_Parse_Repo_Url(string repoUrl, string collectionName, string collectionurl, string projectName, string repositoryName) - { - // Given / When - var repositoryDescription = new RepositoryDescription(new Uri(repoUrl)); - - // Then - repositoryDescription.CollectionName.ShouldBe(collectionName); - repositoryDescription.CollectionUrl.ShouldBe(new Uri(collectionurl)); - repositoryDescription.ProjectName.ShouldBe(projectName); - repositoryDescription.RepositoryName.ShouldBe(repositoryName); - } - } -} diff --git a/src/Cake.Prca.PullRequests.Tfs.Tests/packages.config b/src/Cake.Prca.PullRequests.Tfs.Tests/packages.config index f91d5fc..dc8ca5d 100644 --- a/src/Cake.Prca.PullRequests.Tfs.Tests/packages.config +++ b/src/Cake.Prca.PullRequests.Tfs.Tests/packages.config @@ -1,6 +1,7 @@  + diff --git a/src/Cake.Prca.PullRequests.Tfs/Authentication/AuthenticationProvider.cs b/src/Cake.Prca.PullRequests.Tfs/Authentication/AuthenticationProvider.cs index 112e980..f7c7199 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Authentication/AuthenticationProvider.cs +++ b/src/Cake.Prca.PullRequests.Tfs/Authentication/AuthenticationProvider.cs @@ -12,7 +12,7 @@ internal static class AuthenticationProvider /// Credentials for integrated / NTLM authentication. public static IPrcaCredentials AuthenticationNtlm() { - return new PrcaNtlmCredentials(); + return new TfsNtlmCredentials(); } /// @@ -30,7 +30,7 @@ public static IPrcaCredentials AuthenticationNtlm() userName.NotNullOrWhiteSpace(nameof(userName)); password.NotNullOrWhiteSpace(nameof(password)); - return new PrcaBasicCredentials(userName, password); + return new TfsBasicCredentials(userName, password); } /// @@ -44,7 +44,7 @@ public static IPrcaCredentials AuthenticationNtlm() { personalAccessToken.NotNullOrWhiteSpace(nameof(personalAccessToken)); - return new PrcaBasicCredentials(string.Empty, personalAccessToken); + return new TfsBasicCredentials(string.Empty, personalAccessToken); } /// @@ -58,7 +58,7 @@ public static IPrcaCredentials AuthenticationNtlm() { accessToken.NotNullOrWhiteSpace(nameof(accessToken)); - return new PrcaOAuthCredentials(accessToken); + return new TfsOAuthCredentials(accessToken); } /// @@ -74,7 +74,7 @@ public static IPrcaCredentials AuthenticationNtlm() userName.NotNullOrWhiteSpace(nameof(userName)); password.NotNullOrWhiteSpace(nameof(password)); - return new PrcaAadCredentials(userName, password); + return new TfsAadCredentials(userName, password); } } } diff --git a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaAadCredentials.cs b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsAadCredentials.cs similarity index 64% rename from src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaAadCredentials.cs rename to src/Cake.Prca.PullRequests.Tfs/Authentication/TfsAadCredentials.cs index a8e3179..e8dd6b8 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaAadCredentials.cs +++ b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsAadCredentials.cs @@ -3,14 +3,14 @@ /// /// Credentials for authentication with an Azure Active Directory. /// - public class PrcaAadCredentials : PrcaBasicCredentials + public class TfsAadCredentials : TfsBasicCredentials { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// User name. /// Password. - public PrcaAadCredentials(string userName, string password) + public TfsAadCredentials(string userName, string password) : base(userName, password) { } diff --git a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaBasicCredentials.cs b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsBasicCredentials.cs similarity index 75% rename from src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaBasicCredentials.cs rename to src/Cake.Prca.PullRequests.Tfs/Authentication/TfsBasicCredentials.cs index 73ed0c6..32aeb00 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaBasicCredentials.cs +++ b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsBasicCredentials.cs @@ -3,14 +3,14 @@ /// /// Credentials for basic authentication. /// - public class PrcaBasicCredentials : IPrcaCredentials + public class TfsBasicCredentials : IPrcaCredentials { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// User name. /// Password. - public PrcaBasicCredentials(string userName, string password) + public TfsBasicCredentials(string userName, string password) { this.UserName = userName; this.Password = password; diff --git a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaNtlmCredentials.cs b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsNtlmCredentials.cs similarity index 74% rename from src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaNtlmCredentials.cs rename to src/Cake.Prca.PullRequests.Tfs/Authentication/TfsNtlmCredentials.cs index 145eb07..5957556 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaNtlmCredentials.cs +++ b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsNtlmCredentials.cs @@ -3,7 +3,7 @@ /// /// Credentials for integrated / NTLM authentication. /// - public class PrcaNtlmCredentials : IPrcaCredentials + public class TfsNtlmCredentials : IPrcaCredentials { } } diff --git a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaOAuthCredentials.cs b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsOAuthCredentials.cs similarity index 72% rename from src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaOAuthCredentials.cs rename to src/Cake.Prca.PullRequests.Tfs/Authentication/TfsOAuthCredentials.cs index 485e534..d4fcb90 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Authentication/PrcaOAuthCredentials.cs +++ b/src/Cake.Prca.PullRequests.Tfs/Authentication/TfsOAuthCredentials.cs @@ -3,13 +3,13 @@ /// /// Credentials for OAuth authentication. /// - public class PrcaOAuthCredentials : IPrcaCredentials + public class TfsOAuthCredentials : IPrcaCredentials { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// OAuth access token. - public PrcaOAuthCredentials(string accessToken) + public TfsOAuthCredentials(string accessToken) { accessToken.NotNullOrWhiteSpace(nameof(accessToken)); diff --git a/src/Cake.Prca.PullRequests.Tfs/Cake.Prca.PullRequests.Tfs.csproj b/src/Cake.Prca.PullRequests.Tfs/Cake.Prca.PullRequests.Tfs.csproj index e625a03..ab61eac 100644 --- a/src/Cake.Prca.PullRequests.Tfs/Cake.Prca.PullRequests.Tfs.csproj +++ b/src/Cake.Prca.PullRequests.Tfs/Cake.Prca.PullRequests.Tfs.csproj @@ -42,7 +42,7 @@ True - ..\packages\Cake.Prca.0.2.1\lib\net45\Cake.Prca.dll + ..\packages\Cake.Prca.0.3.0\lib\net45\Cake.Prca.dll True @@ -147,20 +147,24 @@ + + ..\packages\TfsUrlParser.1.0.0\lib\net40\TfsUrlParser.dll + True + - - - + + + + - + - diff --git a/src/Cake.Prca.PullRequests.Tfs/ContentProvider.cs b/src/Cake.Prca.PullRequests.Tfs/ContentProvider.cs new file mode 100644 index 0000000..9f43ebf --- /dev/null +++ b/src/Cake.Prca.PullRequests.Tfs/ContentProvider.cs @@ -0,0 +1,34 @@ +namespace Cake.Prca.PullRequests.Tfs +{ + using Issues; + + /// + /// Class for providing the content for a pull request comment. + /// + internal static class ContentProvider + { + /// + /// Returns the content for an issue. + /// + /// Issue for which the content should be returned. + /// Comment content for the issue. + public static string GetContent(ICodeAnalysisIssue issue) + { + var result = issue.Message; + if (string.IsNullOrWhiteSpace(issue.Rule)) + { + return result; + } + + var ruleContent = issue.Rule; + if (issue.RuleUrl != null) + { + ruleContent = $"[{issue.Rule}]({issue.RuleUrl})"; + } + + result = $"{ruleContent}: {result}"; + + return result; + } + } +} diff --git a/src/Cake.Prca.PullRequests.Tfs/GitPullRequestCommentThreadExtensions.cs b/src/Cake.Prca.PullRequests.Tfs/GitPullRequestCommentThreadExtensions.cs index 483b137..d38bebc 100644 --- a/src/Cake.Prca.PullRequests.Tfs/GitPullRequestCommentThreadExtensions.cs +++ b/src/Cake.Prca.PullRequests.Tfs/GitPullRequestCommentThreadExtensions.cs @@ -10,7 +10,8 @@ /// internal static class GitPullRequestCommentThreadExtensions { - private const string CommentSourcePropertyName = "CommentSource"; + private const string CommentSourcePropertyName = "CakePrcaCommentSource"; + private const string IssueMessagePropertyName = "CakePrcaIssueMessage"; /// /// Converts a from TFS to a as used in this addin. @@ -52,19 +53,7 @@ public static void SetCommentSource(this GitPullRequestCommentThread thread, str { thread.NotNull(nameof(thread)); - if (thread.Properties == null) - { - throw new InvalidOperationException("Properties collection is not created."); - } - - if (thread.Properties.ContainsKey(CommentSourcePropertyName)) - { - thread.Properties[CommentSourcePropertyName] = value; - } - else - { - thread.Properties.Add(CommentSourcePropertyName, value); - } + thread.SetValue(CommentSourcePropertyName, value); } /// @@ -80,5 +69,57 @@ public static bool IsCommentSource(this GitPullRequestCommentThread thread, stri return thread.GetCommentSource() == value; } + + /// + /// Gets the original message of the issue as provided by Cake.Prca, + /// without any formatting done by this addin. + /// + /// Thread to get the value from. + /// Original message of the issue. + public static string GetIssueMessage(this GitPullRequestCommentThread thread) + { + thread.NotNull(nameof(thread)); + + return thread.Properties.GetValue(IssueMessagePropertyName, string.Empty); + } + + /// + /// Sets the original message of the issue as provided by Cake.Prca. + /// + /// Thread for which the value should be set. + /// Value to set as the original message. + public static void SetIssueMessage(this GitPullRequestCommentThread thread, string value) + { + thread.NotNull(nameof(thread)); + + thread.SetValue(IssueMessagePropertyName, value); + } + + /// + /// Sets a value in the thread properties. + /// + /// Type of the value. + /// Thread for which the value should be set. + /// Name of the property. + /// Value to set. + private static void SetValue(this GitPullRequestCommentThread thread, string propertyName, T value) + { + thread.NotNull(nameof(thread)); + propertyName.NotNullOrWhiteSpace(nameof(propertyName)); + + if (thread.Properties == null) + { + throw new InvalidOperationException("Properties collection is not created."); + } + + if (thread.Properties.ContainsKey(propertyName)) + { + thread.Properties[propertyName] = value; + } + else + { + thread.Properties.Add(propertyName, value); + } + } } } diff --git a/src/Cake.Prca.PullRequests.Tfs/PrcaCredentialsExtensions.cs b/src/Cake.Prca.PullRequests.Tfs/PrcaCredentialsExtensions.cs index 0c2d7f3..3e295f1 100644 --- a/src/Cake.Prca.PullRequests.Tfs/PrcaCredentialsExtensions.cs +++ b/src/Cake.Prca.PullRequests.Tfs/PrcaCredentialsExtensions.cs @@ -21,19 +21,19 @@ public static VssCredentials ToVssCredentials(this IPrcaCredentials credentials) switch (credentials.GetType().Name) { - case nameof(PrcaNtlmCredentials): + case nameof(TfsNtlmCredentials): return new VssCredentials(); - case nameof(PrcaBasicCredentials): - var basicCredentials = (PrcaBasicCredentials)credentials; + case nameof(TfsBasicCredentials): + var basicCredentials = (TfsBasicCredentials)credentials; return new VssBasicCredential(basicCredentials.UserName, basicCredentials.Password); - case nameof(PrcaOAuthCredentials): - var oAuthCredentials = (PrcaOAuthCredentials)credentials; + case nameof(TfsOAuthCredentials): + var oAuthCredentials = (TfsOAuthCredentials)credentials; return new VssOAuthAccessTokenCredential(oAuthCredentials.AccessToken); - case nameof(PrcaAadCredentials): - var aadCredentials = (PrcaAadCredentials)credentials; + case nameof(TfsAadCredentials): + var aadCredentials = (TfsAadCredentials)credentials; return new VssAadCredential(aadCredentials.UserName, aadCredentials.Password); default: diff --git a/src/Cake.Prca.PullRequests.Tfs/RepositoryDescription.cs b/src/Cake.Prca.PullRequests.Tfs/RepositoryDescription.cs deleted file mode 100644 index 757c48c..0000000 --- a/src/Cake.Prca.PullRequests.Tfs/RepositoryDescription.cs +++ /dev/null @@ -1,96 +0,0 @@ -namespace Cake.Prca.PullRequests.Tfs -{ - using System; - using System.Linq; - - /// - /// Describes the different parts of a repository URL. - /// - internal class RepositoryDescription - { - /// - /// Initializes a new instance of the class. - /// - /// Full URL of the repository, - /// eg. http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository. - /// Supported URL schemes are HTTP, HTTPS and SSH. - /// URLs using SSH scheme are converted to HTTPS. - public RepositoryDescription(Uri repoUrl) - { - repoUrl.NotNull(nameof(repoUrl)); - - var repoUrlString = ConvertToSupportedUriScheme(repoUrl).ToString(); - var gitSeparator = new[] { "/_git/" }; - var splitPath = repoUrl.AbsolutePath.Split(gitSeparator, StringSplitOptions.None); - if (splitPath.Length < 2) - { - throw new UriFormatException("No valid Git repository URL."); - } - - var splitFirstPart = splitPath[0].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - if (splitFirstPart.Length < 2) - { - throw new UriFormatException("No valid Git repository URL containing default collection and project name."); - } - - var splitLastPart = splitPath[1].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - this.CollectionName = splitFirstPart.Reverse().Skip(1).Take(1).Single(); - this.CollectionUrl = - new Uri( - repoUrlString.Substring( - 0, - repoUrlString.IndexOf("/" + this.CollectionName + "/", StringComparison.OrdinalIgnoreCase) + this.CollectionName.Length + 1)); - this.ProjectName = splitFirstPart.Last(); - this.RepositoryName = splitLastPart.First(); - } - - /// - /// Gets the name of the Team Foundation Server collection. - /// - public string CollectionName { get; } - - /// - /// Gets the URL of the Team Foundation Server collection. - /// - public Uri CollectionUrl { get; private set; } - - /// - /// Gets the name of the Team Foundation Server project. - /// - public string ProjectName { get; private set; } - - /// - /// Gets the name of the Git repository. - /// - public string RepositoryName { get; private set; } - - /// - /// Converts the repository URL to a supported scheme if possible. - /// - /// Repository URL. - /// Repository URL with a supported scheme. - private static Uri ConvertToSupportedUriScheme(Uri repoUrl) - { - if (repoUrl.Scheme == Uri.UriSchemeHttp || repoUrl.Scheme == Uri.UriSchemeHttps) - { - return repoUrl; - } - - // Convert SSH url to HTTPS - if (repoUrl.Scheme == "ssh") - { - var uriBuilder = new UriBuilder(repoUrl) - { - Scheme = Uri.UriSchemeHttps, - UserName = string.Empty, - Password = string.Empty - }; - return uriBuilder.Uri; - } - - throw new UriFormatException( - $"Invalid scheme in URI {repoUrl}. Only HTTP, HTTPS and SSH are supported"); - } - } -} diff --git a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSettings.cs b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSettings.cs index d15430c..50ae310 100644 --- a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSettings.cs +++ b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSettings.cs @@ -73,6 +73,6 @@ public TfsPullRequestSettings(Uri repositoryUrl, int pullRequestId, IPrcaCredent /// Gets or sets a value indicating whether an exception should be thrown if no /// pull request exists or not. /// - public bool ThrowExceptionIfPulLRequestDoesNotExist { get; set; } = true; + public bool ThrowExceptionIfPullRequestDoesNotExist { get; set; } = true; } } diff --git a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystem.cs b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystem.cs index 49931f4..edffc21 100644 --- a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystem.cs +++ b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystem.cs @@ -9,6 +9,7 @@ using Issues; using Microsoft.TeamFoundation.SourceControl.WebApi; using Microsoft.VisualStudio.Services.WebApi; + using TfsUrlParser; /// /// Class for writing issues to Team Foundation Server or Visual Studio Team Services pull requests. @@ -80,7 +81,7 @@ public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSettings settings) if (this.pullRequest == null) { - if (this.settings.ThrowExceptionIfPulLRequestDoesNotExist) + if (this.settings.ThrowExceptionIfPullRequestDoesNotExist) { throw new PrcaException("Could not find pull request"); } @@ -98,7 +99,13 @@ public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSettings settings) } /// - public override IEnumerable FetchActiveDiscussionThreads(string commentSource) + public override PrcaCommentFormat GetPreferredCommentFormat() + { + return PrcaCommentFormat.Markdown; + } + + /// + protected override IEnumerable InternalFetchActiveDiscussionThreads(string commentSource) { if (!this.ValidatePullRequest()) { @@ -121,10 +128,19 @@ public override IEnumerable FetchActiveDiscussionThreads( var threadList = new List(); foreach (var thread in threads) { - if (thread.IsCommentSource(commentSource) && thread.Status == CommentThreadStatus.Active) + if (!thread.IsCommentSource(commentSource) || thread.Status != CommentThreadStatus.Active) { - threadList.Add(thread.ToPrcaDiscussionThread()); + continue; } + + var prcaThread = thread.ToPrcaDiscussionThread(); + + // Assuming that the first comment is the one written by this addin, we replace the content + // containing additional formatting done by this addin with the original issue message to + // allow Cake.Prca to do a proper comparison to find out which issues already were posted. + prcaThread.Comments.First().Content = thread.GetIssueMessage(); + + threadList.Add(prcaThread); } this.Log.Verbose("Found {0} discussion thread(s)", threadList.Count); @@ -133,7 +149,7 @@ public override IEnumerable FetchActiveDiscussionThreads( } /// - public override IEnumerable GetModifiedFilesInPullRequest() + protected override IEnumerable InternalGetModifiedFilesInPullRequest() { if (!this.ValidatePullRequest()) { @@ -187,7 +203,7 @@ public override IEnumerable GetModifiedFilesInPullRequest() } /// - public override void MarkThreadsAsFixed(IEnumerable threads) + protected override void InternalMarkThreadsAsFixed(IEnumerable threads) { // ReSharper disable once PossibleMultipleEnumeration threads.NotNull(nameof(threads)); @@ -219,7 +235,7 @@ public override void MarkThreadsAsFixed(IEnumerable threa } /// - public override void PostDiscussionThreads(IEnumerable issues, string commentSource) + protected override void InternalPostDiscussionThreads(IEnumerable issues, string commentSource) { // ReSharper disable once PossibleMultipleEnumeration issues.NotNull(nameof(issues)); @@ -275,7 +291,7 @@ public override void PostDiscussionThreads(IEnumerable issue /// /// Validates if a pull request could be found. - /// Depending on + /// Depending on /// the pull request instance can be null for subsequent calls. /// /// True if a valid pull request instance exists. @@ -346,7 +362,7 @@ private GitHttpClient CreateGitClient() { CommentType = CommentType.System, IsDeleted = false, - Content = issue.Message + Content = ContentProvider.GetContent(issue) }; if (!this.AddThreadProperties(newThread, changes, issue, iterationId, commentSource)) @@ -399,6 +415,10 @@ private GitHttpClient CreateGitClient() // Add a custom property to be able to distinguish all comments created this way. thread.SetCommentSource(commentSource); + // Add a custom property to be able to return issue message from existing threads, + // without any formatting done by this addin, back to Cake.Prca. + thread.SetIssueMessage(issue.Message); + return true; } diff --git a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystemAliases.cs b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystemAliases.cs index ee4708a..d91c60e 100644 --- a/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystemAliases.cs +++ b/src/Cake.Prca.PullRequests.Tfs/TfsPullRequestSystemAliases.cs @@ -21,7 +21,7 @@ public static class TfsPullRequestSystemAliases /// Credentials for integrated / NTLM authentication [CakeMethodAlias] [CakeAliasCategory(CakeAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPrcaCredentials PrcaAuthenticationNtlm( + public static IPrcaCredentials TfsAuthenticationNtlm( this ICakeContext context) { context.NotNull(nameof(context)); @@ -40,7 +40,7 @@ public static class TfsPullRequestSystemAliases /// Credentials for basic authentication. [CakeMethodAlias] [CakeAliasCategory(CakeAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPrcaCredentials PrcaAuthenticationBasic( + public static IPrcaCredentials TfsAuthenticationBasic( this ICakeContext context, string userName, string password) @@ -61,7 +61,7 @@ public static class TfsPullRequestSystemAliases /// Credentials for authentication with a personal access token. [CakeMethodAlias] [CakeAliasCategory(CakeAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPrcaCredentials PrcaAuthenticationPersonalAccessToken( + public static IPrcaCredentials TfsAuthenticationPersonalAccessToken( this ICakeContext context, string personalAccessToken) { @@ -80,7 +80,7 @@ public static class TfsPullRequestSystemAliases /// Credentials for OAuth authentication. [CakeMethodAlias] [CakeAliasCategory(CakeAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPrcaCredentials PrcaAuthenticationOAuth( + public static IPrcaCredentials TfsAuthenticationOAuth( this ICakeContext context, string accessToken) { @@ -99,7 +99,7 @@ public static class TfsPullRequestSystemAliases /// Credentials for authentication with an Azure Active Directory. [CakeMethodAlias] [CakeAliasCategory(CakeAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPrcaCredentials PrcaAuthenticationAzureActiveDirectory( + public static IPrcaCredentials TfsAuthenticationAzureActiveDirectory( this ICakeContext context, string userName, string password) @@ -132,12 +132,11 @@ public static class TfsPullRequestSystemAliases /// ReportCodeAnalysisIssuesToPullRequest( /// MsBuildCodeAnalysis( /// @"C:\build\msbuild.log", - /// MsBuildXmlFileLoggerFormat, - /// repoRoot), + /// MsBuildXmlFileLoggerFormat), /// TfsPullRequests( /// new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), /// "refs/heads/feature/myfeature", - /// PrcaAuthenticationNtlm()), + /// TfsAuthenticationNtlm()), /// repoRoot); /// ]]> /// @@ -179,12 +178,11 @@ public static class TfsPullRequestSystemAliases /// ReportCodeAnalysisIssuesToPullRequest( /// MsBuildCodeAnalysis( /// @"C:\build\msbuild.log", - /// MsBuildXmlFileLoggerFormat, - /// repoRoot), + /// MsBuildXmlFileLoggerFormat), /// TfsPullRequests( /// new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), /// 5, - /// PrcaAuthenticationNtlm()), + /// TfsAuthenticationNtlm()), /// repoRoot); /// ]]> /// @@ -220,13 +218,12 @@ public static class TfsPullRequestSystemAliases /// new TfsPullRequestSettings( /// new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), /// "refs/heads/feature/myfeature", - /// PrcaAuthenticationNtlm()); + /// TfsAuthenticationNtlm()); /// /// ReportCodeAnalysisIssuesToPullRequest( /// MsBuildCodeAnalysis( /// @"C:\build\msbuild.log", - /// MsBuildXmlFileLoggerFormat, - /// repoRoot), + /// MsBuildXmlFileLoggerFormat), /// TfsPullRequests(pullRequestSettings), /// repoRoot); /// ]]> diff --git a/src/Cake.Prca.PullRequests.Tfs/packages.config b/src/Cake.Prca.PullRequests.Tfs/packages.config index f3bc03e..5559781 100644 --- a/src/Cake.Prca.PullRequests.Tfs/packages.config +++ b/src/Cake.Prca.PullRequests.Tfs/packages.config @@ -1,7 +1,7 @@  - + @@ -21,5 +21,6 @@ + \ No newline at end of file