diff --git a/nuspec/nuget/Cake.Prca.Issues.EsLint.nuspec b/nuspec/nuget/Cake.Prca.Issues.EsLint.nuspec
new file mode 100644
index 0000000..6adfde6
--- /dev/null
+++ b/nuspec/nuget/Cake.Prca.Issues.EsLint.nuspec
@@ -0,0 +1,23 @@
+
+
+
+ Cake.Prca.Issues.EsLint
+ Cake.Prca.Issues.EsLint
+ 0.0.0
+ BBT Software AG
+ bbtsoftware, pascalberger, cake-contrib
+ ESLint support for the Pull Request Code Analysis Addin for Cake Build Automation System
+ The ESLint support for the Pull Request Code Analysis Addin for Cake allows you to write any issues logged by ESLint as comments to a pull request.
+ https://github.com/cake-contrib/Cake.Prca.Issues.EsLint/blob/develop/LICENSE
+ https://github.com/cake-contrib/Cake.Prca.Issues.EsLint
+ https://raw.githubusercontent.com/cake-build/graphics/aba74fb4cb5fe9454381af2cc70c870088229d5c/png/cake-medium.png
+ false
+ Copyright © 2017 BBT Software AG, Root/Zermatt, Switzerland
+ Cake Script PullRequest CodeAnalysis Cake-Prca-IssueProvider JavaScript Linting ESLint
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.Tests.ruleset b/src/Cake.Prca.Issues.EsLint.Tests.ruleset
new file mode 100644
index 0000000..4ac6775
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests.ruleset
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/Cake.Prca.Issues.EsLint.Tests.csproj b/src/Cake.Prca.Issues.EsLint.Tests/Cake.Prca.Issues.EsLint.Tests.csproj
new file mode 100644
index 0000000..966d688
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/Cake.Prca.Issues.EsLint.Tests.csproj
@@ -0,0 +1,120 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {B1625322-FDA2-4E90-A403-8CE8C0748D09}
+ Library
+ Properties
+ Cake.Prca.Issues.EsLint.Tests
+ Cake.Prca.Issues.EsLint.Tests
+ v4.5.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Cake.Prca.Issues.EsLint.Tests.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Cake.Prca.Issues.EsLint.Tests.ruleset
+
+
+
+ ..\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
+
+
+ ..\packages\Shouldly.2.8.2\lib\net451\Shouldly.dll
+ True
+
+
+
+
+
+
+
+
+
+
+ ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll
+ True
+
+
+ ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll
+ True
+
+
+ ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll
+ True
+
+
+ ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {c6e0bc8d-6bd8-475e-a69f-ced3ffb86362}
+ Cake.Prca.Issues.EsLint
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderFixture.cs b/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderFixture.cs
new file mode 100644
index 0000000..ac007eb
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderFixture.cs
@@ -0,0 +1,48 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System.Collections.Generic;
+ using System.IO;
+ using Core.Diagnostics;
+ using Testing;
+
+ public class EsLintProviderFixture
+ {
+ public EsLintProviderFixture(string fileResourceName)
+ {
+ this.Log = new FakeLog { Verbosity = Verbosity.Normal };
+
+ using (var stream = this.GetType().Assembly.GetManifestResourceStream("Cake.Prca.Issues.EsLint.Tests.Testfiles." + fileResourceName))
+ {
+ using (var sr = new StreamReader(stream))
+ {
+ this.Settings =
+ EsLintSettings.FromContent(
+ sr.ReadToEnd(),
+ new JsonFormat(this.Log));
+ }
+ }
+
+ this.PrcaSettings =
+ new ReportCodeAnalysisIssuesToPullRequestSettings(@"c:\Source\Cake.Prca");
+ }
+
+ public FakeLog Log { get; set; }
+
+ public EsLintSettings Settings { get; set; }
+
+ public ReportCodeAnalysisIssuesToPullRequestSettings PrcaSettings { get; set; }
+
+ internal EsLintProvider Create()
+ {
+ var provider = new EsLintProvider(this.Log, this.Settings);
+ provider.Initialize(this.PrcaSettings);
+ return provider;
+ }
+
+ internal IEnumerable ReadIssues()
+ {
+ var codeAnalysisProvider = this.Create();
+ return codeAnalysisProvider.ReadIssues(PrcaCommentFormat.PlainText);
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderTests.cs b/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderTests.cs
new file mode 100644
index 0000000..4e16d7c
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/EsLintProviderTests.cs
@@ -0,0 +1,41 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System.Linq;
+ using Core.IO;
+ using Shouldly;
+ using Testing;
+ using Xunit;
+
+ public class EsLintProviderTests
+ {
+ public sealed class TheMsBuildCodeAnalysisProviderCtor
+ {
+ [Fact]
+ public void Should_Throw_If_Log_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ new EsLintProvider(
+ null,
+ EsLintSettings.FromContent(
+ "Foo",
+ new JsonFormat(new FakeLog()))));
+
+ // Then
+ result.IsArgumentNullException("log");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Settings_Are_Null()
+ {
+ var result = Record.Exception(() =>
+ new EsLintProvider(
+ new FakeLog(),
+ null));
+
+ // Then
+ result.IsArgumentNullException("settings");
+ }
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/EsLintRuleUrlResolverTests.cs b/src/Cake.Prca.Issues.EsLint.Tests/EsLintRuleUrlResolverTests.cs
new file mode 100644
index 0000000..6630c3a
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/EsLintRuleUrlResolverTests.cs
@@ -0,0 +1,78 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System;
+ using Shouldly;
+ using Xunit;
+
+ public class EsLintRuleUrlResolverTests
+ {
+ public sealed class TheResolveRuleUrlMethod
+ {
+ [Fact]
+ public void Should_Throw_If_Rule_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() => EsLintRuleUrlResolver.Instance.ResolveRuleUrl(null));
+
+ // Then
+ result.IsArgumentNullException("rule");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Rule_Is_Empty()
+ {
+ // Given / When
+ var result = Record.Exception(() => EsLintRuleUrlResolver.Instance.ResolveRuleUrl(string.Empty));
+
+ // Then
+ result.IsArgumentOutOfRangeException("rule");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Rule_Is_WhiteSpace()
+ {
+ // Given / When
+ var result = Record.Exception(() => EsLintRuleUrlResolver.Instance.ResolveRuleUrl(" "));
+
+ // Then
+ result.IsArgumentOutOfRangeException("rule");
+ }
+
+ [Theory]
+ [InlineData("no-unused-vars", "http://eslint.org/docs/rules/no-unused-vars")]
+ [InlineData("no-await-in-loop", "http://eslint.org/docs/rules/no-await-in-loop")]
+ public void Should_Resolve_Url(string rule, string expectedUrl)
+ {
+ // Given
+ var urlResolver = EsLintRuleUrlResolver.Instance;
+
+ // When
+ var ruleUrl = urlResolver.ResolveRuleUrl(rule);
+
+ // Then
+ ruleUrl.ToString().ShouldBe(expectedUrl);
+ }
+
+ [Fact]
+ public void Should_Resolve_Url_From_Custom_Resolvers()
+ {
+ // Given
+ const string foo = "FOO123";
+ const string fooUrl = "http://foo.com/";
+ const string bar = "BAR123";
+ const string barUrl = "http://bar.com/";
+ var urlResolver = EsLintRuleUrlResolver.Instance;
+ urlResolver.AddUrlResolver(x => x.Rule == foo ? new Uri(fooUrl) : null, 1);
+ urlResolver.AddUrlResolver(x => x.Rule == bar ? new Uri(barUrl) : null, 1);
+
+ // When
+ var fooRuleUrl = urlResolver.ResolveRuleUrl(foo);
+ var barRuleUrl = urlResolver.ResolveRuleUrl(bar);
+
+ // Then
+ fooRuleUrl.ToString().ShouldBe(fooUrl);
+ barRuleUrl.ToString().ShouldBe(barUrl);
+ }
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/EsLintSettingsTests.cs b/src/Cake.Prca.Issues.EsLint.Tests/EsLintSettingsTests.cs
new file mode 100644
index 0000000..80e3a79
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/EsLintSettingsTests.cs
@@ -0,0 +1,162 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using Shouldly;
+ using Testing;
+ using Xunit;
+
+ public class EsLintSettingsTests
+ {
+ public sealed class TheEsLintSettingsCtor
+ {
+ [Fact]
+ public void Should_Throw_If_LogFilePath_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromFilePath(
+ null,
+ new JsonFormat(new FakeLog())));
+
+ // Then
+ result.IsArgumentNullException("logFilePath");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Format_For_LogFilePath_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromFilePath(
+ @"C:\foo.log",
+ null));
+
+ // Then
+ result.IsArgumentNullException("format");
+ }
+
+ [Fact]
+ public void Should_Throw_If_LogFileContent_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromContent(
+ null,
+ new JsonFormat(new FakeLog())));
+
+ // Then
+ result.IsArgumentNullException("logFileContent");
+ }
+
+ [Fact]
+ public void Should_Throw_If_LogFileContent_Is_Empty()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromContent(
+ string.Empty,
+ new JsonFormat(new FakeLog())));
+
+ // Then
+ result.IsArgumentOutOfRangeException("logFileContent");
+ }
+
+ [Fact]
+ public void Should_Throw_If_LogFileContent_Is_WhiteSpace()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromContent(
+ " ",
+ new JsonFormat(new FakeLog())));
+
+ // Then
+ result.IsArgumentOutOfRangeException("logFileContent");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Format_For_LogFileContent_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() =>
+ EsLintSettings.FromContent(
+ "foo",
+ null));
+
+ // Then
+ result.IsArgumentNullException("format");
+ }
+
+ [Fact]
+ public void Should_Set_Property_Values_Passed_To_Constructor()
+ {
+ // Given
+ const string logFileContent = "foo";
+ var format = new JsonFormat(new FakeLog());
+
+ // When
+ var settings = EsLintSettings.FromContent(logFileContent, format);
+
+ // Then
+ settings.LogFileContent.ShouldBe(logFileContent);
+ settings.Format.ShouldBe(format);
+ }
+
+ [Fact]
+ public void Should_Read_File_From_Disk()
+ {
+ var fileName = Path.GetTempFileName();
+ try
+ {
+ // Given
+ string expected;
+ using (var ms = new MemoryStream())
+ using (var stream = this.GetType().Assembly.GetManifestResourceStream("Cake.Prca.Issues.EsLint.Tests.Testfiles.jsonFormatWindows.json"))
+ {
+ stream.CopyTo(ms);
+ var data = ms.ToArray();
+
+ using (var file = new FileStream(fileName, FileMode.Create, FileAccess.Write))
+ {
+ file.Write(data, 0, data.Length);
+ }
+
+ expected = ConvertFromUtf8(data);
+ }
+
+ // When
+ var settings =
+ EsLintSettings.FromFilePath(
+ fileName,
+ new JsonFormat(new FakeLog()));
+
+ // Then
+ settings.LogFileContent.ShouldBe(expected);
+ }
+ finally
+ {
+ if (File.Exists(fileName))
+ {
+ File.Delete(fileName);
+ }
+ }
+ }
+
+ private static string ConvertFromUtf8(byte[] bytes)
+ {
+ var enc = new UTF8Encoding(true);
+ var preamble = enc.GetPreamble();
+
+ if (preamble.Where((p, i) => p != bytes[i]).Any())
+ {
+ throw new ArgumentException("Not utf8-BOM");
+ }
+
+ return enc.GetString(bytes.Skip(preamble.Length).ToArray());
+ }
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/ExceptionAssertExtensions.cs b/src/Cake.Prca.Issues.EsLint.Tests/ExceptionAssertExtensions.cs
new file mode 100644
index 0000000..a09e148
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/ExceptionAssertExtensions.cs
@@ -0,0 +1,20 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System;
+ using Xunit;
+
+ public static class ExceptionAssertExtensions
+ {
+ public static void IsArgumentNullException(this Exception exception, string parameterName)
+ {
+ Assert.IsType(exception);
+ Assert.Equal(parameterName, ((ArgumentNullException)exception).ParamName);
+ }
+
+ public static void IsArgumentOutOfRangeException(this Exception exception, string parameterName)
+ {
+ Assert.IsType(exception);
+ Assert.Equal(parameterName, ((ArgumentOutOfRangeException)exception).ParamName);
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/JsonFormatTests.cs b/src/Cake.Prca.Issues.EsLint.Tests/JsonFormatTests.cs
new file mode 100644
index 0000000..ee4d280
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/JsonFormatTests.cs
@@ -0,0 +1,146 @@
+namespace Cake.Prca.Issues.EsLint.Tests
+{
+ using System.Linq;
+ using Core.IO;
+ using Shouldly;
+ using Xunit;
+
+ public class JsonFormatTests
+ {
+ public sealed class TheJsonFormatCtor
+ {
+ [Fact]
+ public void Should_Throw_If_Log_Is_Null()
+ {
+ // Given / When
+ var result = Record.Exception(() => new JsonFormat(null));
+
+ // Then
+ result.IsArgumentNullException("log");
+ }
+ }
+
+ public sealed class TheReadIssuesMethod
+ {
+ [Fact]
+ public void Should_Read_Issue_Correct()
+ {
+ // Given
+ var fixture = new EsLintProviderFixture("jsonFormatWindows.json");
+
+ // When
+ var issues = fixture.ReadIssues().ToList();
+
+ // Then
+ issues.Count.ShouldBe(9);
+ CheckIssue(
+ issues[0],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 1,
+ "no-unused-vars",
+ "http://eslint.org/docs/rules/no-unused-vars",
+ 2,
+ "'addOne' is defined but never used.");
+ CheckIssue(
+ issues[1],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 2,
+ "use-isnan",
+ "http://eslint.org/docs/rules/use-isnan",
+ 2,
+ "Use the isNaN function to compare with NaN.");
+ CheckIssue(
+ issues[2],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 3,
+ "space-unary-ops",
+ "http://eslint.org/docs/rules/space-unary-ops",
+ 2,
+ "Unexpected space before unary operator '++'.");
+ CheckIssue(
+ issues[3],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 3,
+ "semi",
+ "http://eslint.org/docs/rules/semi",
+ 1,
+ "Missing semicolon.");
+ CheckIssue(
+ issues[4],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 4,
+ "no-else-return",
+ "http://eslint.org/docs/rules/no-else-return",
+ 1,
+ "Unnecessary 'else' after 'return'.");
+ CheckIssue(
+ issues[5],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 5,
+ "indent",
+ "http://eslint.org/docs/rules/indent",
+ 1,
+ "Expected indentation of 8 spaces but found 6.");
+ CheckIssue(
+ issues[6],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 5,
+ "consistent-return",
+ "http://eslint.org/docs/rules/consistent-return",
+ 2,
+ "Function 'addOne' expected a return value.");
+ CheckIssue(
+ issues[7],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 5,
+ "semi",
+ "http://eslint.org/docs/rules/semi",
+ 1,
+ "Missing semicolon.");
+ CheckIssue(
+ issues[8],
+ @"src\Cake.Prca.Issues.EsLint.Tests\Testfiles\fullOfProblems.js",
+ 7,
+ "no-extra-semi",
+ "http://eslint.org/docs/rules/no-extra-semi",
+ 2,
+ "Unnecessary semicolon.");
+ }
+
+ private static void CheckIssue(
+ ICodeAnalysisIssue issue,
+ string affectedFileRelativePath,
+ int? line,
+ string rule,
+ string ruleUrl,
+ int priority,
+ string message)
+ {
+ if (issue.AffectedFileRelativePath == null)
+ {
+ affectedFileRelativePath.ShouldBeNull();
+ }
+ else
+ {
+ issue.AffectedFileRelativePath.ToString().ShouldBe(new FilePath(affectedFileRelativePath).ToString());
+ issue.AffectedFileRelativePath.IsRelative.ShouldBe(true, "Issue path is not relative");
+ }
+
+ issue.Line.ShouldBe(line);
+ issue.Rule.ShouldBe(rule);
+
+ if (issue.RuleUrl == null)
+ {
+ ruleUrl.ShouldBeNull();
+ }
+ else
+ {
+ issue.RuleUrl.ToString().ShouldBe(ruleUrl);
+ }
+
+ issue.Priority.ShouldBe(priority);
+ issue.Message.ShouldBe(message);
+ }
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/Properties/AssemblyInfo.cs b/src/Cake.Prca.Issues.EsLint.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..32dedc7
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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: AssemblyTitle("ESLint support for Cake Pull Request Code Analysis Testcases")]
+[assembly: AssemblyDescription("ESLint support for the Pull Request Code Analysis Addin for Cake Build Automation System")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("BBT Software AG")]
+[assembly: AssemblyProduct("Cake Pull Request Code Analysis Addin")]
+[assembly: AssemblyCopyright("Copyright © 2017 BBT Software AG, Root/Zermatt, Switzerland")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 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("b1625322-fda2-4e90-a403-8ce8c0748d09")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/Testfiles/jsonFormatWindows.json b/src/Cake.Prca.Issues.EsLint.Tests/Testfiles/jsonFormatWindows.json
new file mode 100644
index 0000000..6291fcb
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/Testfiles/jsonFormatWindows.json
@@ -0,0 +1,119 @@
+[
+ {
+ "filePath": "c:\\Source\\Cake.Prca\\src\\Cake.Prca.Issues.EsLint.Tests\\Testfiles\\fullOfProblems.js",
+ "messages": [
+ {
+ "ruleId": "no-unused-vars",
+ "severity": 2,
+ "message": "'addOne' is defined but never used.",
+ "line": 1,
+ "column": 10,
+ "nodeType": "Identifier",
+ "source": "function addOne(i) {"
+ },
+ {
+ "ruleId": "use-isnan",
+ "severity": 2,
+ "message": "Use the isNaN function to compare with NaN.",
+ "line": 2,
+ "column": 9,
+ "nodeType": "BinaryExpression",
+ "source": " if (i != NaN) {"
+ },
+ {
+ "ruleId": "space-unary-ops",
+ "severity": 2,
+ "message": "Unexpected space before unary operator '++'.",
+ "line": 3,
+ "column": 16,
+ "nodeType": "UpdateExpression",
+ "source": " return i ++",
+ "fix": {
+ "range": [ 57, 58 ],
+ "text": ""
+ }
+ },
+ {
+ "ruleId": "semi",
+ "severity": 1,
+ "message": "Missing semicolon.",
+ "line": 3,
+ "column": 20,
+ "nodeType": "ReturnStatement",
+ "source": " return i ++",
+ "fix": {
+ "range": [ 60, 60 ],
+ "text": ";"
+ }
+ },
+ {
+ "ruleId": "no-else-return",
+ "severity": 1,
+ "message": "Unnecessary 'else' after 'return'.",
+ "line": 4,
+ "column": 12,
+ "nodeType": "BlockStatement",
+ "source": " } else {",
+ "fix": {
+ "range": [ 0, 94 ],
+ "text": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"
+ }
+ },
+ {
+ "ruleId": "indent",
+ "severity": 1,
+ "message": "Expected indentation of 8 spaces but found 6.",
+ "line": 5,
+ "column": 1,
+ "nodeType": "Keyword",
+ "source": " return",
+ "endLine": 5,
+ "endColumn": 7,
+ "fix": {
+ "range": [ 74, 80 ],
+ "text": " "
+ }
+ },
+ {
+ "ruleId": "consistent-return",
+ "severity": 2,
+ "message": "Function 'addOne' expected a return value.",
+ "line": 5,
+ "column": 7,
+ "nodeType": "ReturnStatement",
+ "source": " return"
+ },
+ {
+ "ruleId": "semi",
+ "severity": 1,
+ "message": "Missing semicolon.",
+ "line": 5,
+ "column": 13,
+ "nodeType": "ReturnStatement",
+ "source": " return",
+ "fix": {
+ "range": [ 86, 86 ],
+ "text": ";"
+ }
+ },
+ {
+ "ruleId": "no-extra-semi",
+ "severity": 2,
+ "message": "Unnecessary semicolon.",
+ "line": 7,
+ "column": 2,
+ "nodeType": "EmptyStatement",
+ "source": "};",
+ "fix": {
+ "range": [ 93, 95 ],
+ "text": "}"
+ }
+ }
+ ],
+ "errorCount": 5,
+ "warningCount": 4,
+ "fixableErrorCount": 2,
+ "fixableWarningCount": 4,
+ "source": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"
+ }
+]
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.Tests/packages.config b/src/Cake.Prca.Issues.EsLint.Tests/packages.config
new file mode 100644
index 0000000..dc8ca5d
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.Tests/packages.config
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.ruleset b/src/Cake.Prca.Issues.EsLint.ruleset
new file mode 100644
index 0000000..f8d6df1
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.ruleset
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint.sln b/src/Cake.Prca.Issues.EsLint.sln
new file mode 100644
index 0000000..f0afb9c
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Prca.Issues.EsLint", "Cake.Prca.Issues.EsLint\Cake.Prca.Issues.EsLint.csproj", "{C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Prca.Issues.EsLint.Tests", "Cake.Prca.Issues.EsLint.Tests\Cake.Prca.Issues.EsLint.Tests.csproj", "{B1625322-FDA2-4E90-A403-8CE8C0748D09}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{0C2D356A-09A1-4502-89D9-65C675803DCD}"
+ ProjectSection(SolutionItems) = preProject
+ ..\build.ps1 = ..\build.ps1
+ ..\build.sh = ..\build.sh
+ ..\setup.cake = ..\setup.cake
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuspec", "nuspec", "{B4C4F0ED-9268-41C7-A936-AF34D83DB404}"
+ ProjectSection(SolutionItems) = preProject
+ ..\nuspec\nuget\Cake.Prca.Issues.EsLint.nuspec = ..\nuspec\nuget\Cake.Prca.Issues.EsLint.nuspec
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1625322-FDA2-4E90-A403-8CE8C0748D09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1625322-FDA2-4E90-A403-8CE8C0748D09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1625322-FDA2-4E90-A403-8CE8C0748D09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1625322-FDA2-4E90-A403-8CE8C0748D09}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B4C4F0ED-9268-41C7-A936-AF34D83DB404} = {0C2D356A-09A1-4502-89D9-65C675803DCD}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Cake.Prca.Issues.EsLint.sln.DotSettings b/src/Cake.Prca.Issues.EsLint.sln.DotSettings
new file mode 100644
index 0000000..7cc51a4
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint.sln.DotSettings
@@ -0,0 +1,3 @@
+
+ DO_NOT_SHOW
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint/Cake.Prca.Issues.EsLint.csproj b/src/Cake.Prca.Issues.EsLint/Cake.Prca.Issues.EsLint.csproj
new file mode 100644
index 0000000..75f9f54
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/Cake.Prca.Issues.EsLint.csproj
@@ -0,0 +1,106 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {C6E0BC8D-6BD8-475E-A69F-CED3FFB86362}
+ Library
+ Properties
+ Cake.Prca.Issues.EsLint
+ Cake.Prca.Issues.EsLint
+ v4.5.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Cake.Prca.Issues.EsLint.ruleset
+ bin\Debug\Cake.Prca.Issues.EsLint.XML
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Cake.Prca.Issues.EsLint.ruleset
+ bin\Release\Cake.Prca.Issues.EsLint.XML
+
+
+
+ ..\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\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint/EsLintProvider.cs b/src/Cake.Prca.Issues.EsLint/EsLintProvider.cs
new file mode 100644
index 0000000..818afeb
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/EsLintProvider.cs
@@ -0,0 +1,32 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System.Collections.Generic;
+ using Core.Diagnostics;
+
+ ///
+ /// Provider for code analysis issues reported by ESLint.
+ ///
+ internal class EsLintProvider : CodeAnalysisProvider
+ {
+ private readonly EsLintSettings settings;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Cake log context.
+ /// Settings for reading the log file.
+ public EsLintProvider(ICakeLog log, EsLintSettings settings)
+ : base(log)
+ {
+ settings.NotNull(nameof(settings));
+
+ this.settings = settings;
+ }
+
+ ///
+ protected override IEnumerable InternalReadIssues(PrcaCommentFormat format)
+ {
+ return this.settings.Format.ReadIssues(this.PrcaSettings, this.settings);
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/EsLintProviderAliases.cs b/src/Cake.Prca.Issues.EsLint/EsLintProviderAliases.cs
new file mode 100644
index 0000000..49af2b4
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/EsLintProviderAliases.cs
@@ -0,0 +1,208 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System;
+ using Core;
+ using Core.Annotations;
+ using Core.IO;
+
+ ///
+ /// Contains functionality related to importing code analysis issues from ESLint
+ /// to write them to pull requests.
+ ///
+ [CakeAliasCategory(CakeAliasConstants.MainCakeAliasCategory)]
+ [CakeNamespaceImport("Cake.Prca.Issues.EsLint")]
+ public static class EsLintProviderAliases
+ {
+ ///
+ /// Registers a new URL resolver with default priority of 0.
+ ///
+ /// The context.
+ /// Resolver which returns an linking to a site
+ /// containing help for a specific .
+ ///
+ /// Adds a provider with default priority of 0 returning a link for all rules starting
+ /// with the string Foo to search with Google for the rule:
+ ///
+ ///
+ /// x.Rule.StartsWith("Foo") ?
+ /// new Uri("https://www.google.com/search?q=%22" + x.Rule + "%22") :
+ /// null)
+ /// ]]>
+ ///
+ ///
+ [CakeMethodAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static void EsLintAddRuleUrlResolver(
+ this ICakeContext context,
+ Func resolver)
+ {
+ context.NotNull(nameof(context));
+ resolver.NotNull(nameof(resolver));
+
+ EsLintRuleUrlResolver.Instance.AddUrlResolver(resolver);
+ }
+
+ ///
+ /// Registers a new URL resolver with a specific priority.
+ ///
+ /// The context.
+ /// Resolver which returns an linking to a site
+ /// containing help for a specific .
+ /// Priority of the resolver. Resolver with a higher priority are considered
+ /// first during resolving of the URL.
+ ///
+ /// Adds a provider of priority 5 returning a link for all rules starting with the string
+ /// Foo to search with Google for the rule:
+ ///
+ ///
+ /// x.Rule.StartsWith("Foo") ?
+ /// new Uri("https://www.google.com/search?q=%22" + x.Rule + "%22") :
+ /// null,
+ /// 5)
+ /// ]]>
+ ///
+ ///
+ [CakeMethodAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static void EsLintAddRuleUrlResolver(
+ this ICakeContext context,
+ Func resolver,
+ int priority)
+ {
+ context.NotNull(nameof(context));
+ resolver.NotNull(nameof(resolver));
+
+ EsLintRuleUrlResolver.Instance.AddUrlResolver(resolver, priority);
+ }
+
+ ///
+ /// Gets an instance for the ESLint JSON log format as written by the JSON formatter
+ ///
+ /// The context.
+ /// Instance for the ESLint JSON log format.
+ [CakePropertyAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static ILogFileFormat EsLintJsonFormat(
+ this ICakeContext context)
+ {
+ context.NotNull(nameof(context));
+
+ return new JsonFormat(context.Log);
+ }
+
+ ///
+ /// Gets an instance of a provider for code analysis issues reported by ESLint using a log file from disk.
+ ///
+ /// The context.
+ /// Path to the the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ /// Instance of a provider for code analysis issues reported by ESLint.
+ ///
+ /// Report code analysis issues reported by ESLint to a TFS pull request:
+ ///
+ ///
+ ///
+ ///
+ [CakeMethodAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static ICodeAnalysisProvider EsLintFromFilePath(
+ this ICakeContext context,
+ FilePath logFilePath,
+ ILogFileFormat format)
+ {
+ context.NotNull(nameof(context));
+ logFilePath.NotNull(nameof(logFilePath));
+ format.NotNull(nameof(format));
+
+ return context.EsLint(EsLintSettings.FromFilePath(logFilePath, format));
+ }
+
+ ///
+ /// Gets an instance of a provider for code analysis issues reported by ESLint using log file content.
+ ///
+ /// The context.
+ /// Content of the the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ /// Instance of a provider for code analysis issues reported by ESLint.
+ ///
+ /// Report code analysis issues reported by ESLint to a TFS pull request:
+ ///
+ ///
+ ///
+ ///
+ [CakeMethodAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static ICodeAnalysisProvider EsLintFromContent(
+ this ICakeContext context,
+ string logFileContent,
+ ILogFileFormat format)
+ {
+ context.NotNull(nameof(context));
+ logFileContent.NotNullOrWhiteSpace(nameof(logFileContent));
+ format.NotNull(nameof(format));
+
+ return context.EsLint(EsLintSettings.FromContent(logFileContent, format));
+ }
+
+ ///
+ /// Gets an instance of a provider for code analysis issues reported by ESLint using specified settings.
+ ///
+ /// The context.
+ /// Settings for reading the ESLint log.
+ /// Instance of a provider for code analysis issues reported by ESLint.
+ ///
+ /// Report code analysis issues reported by ESLint to a TFS pull request:
+ ///
+ ///
+ ///
+ ///
+ [CakeMethodAlias]
+ [CakeAliasCategory(CakeAliasConstants.CodeAnalysisProviderCakeAliasCategory)]
+ public static ICodeAnalysisProvider EsLint(
+ this ICakeContext context,
+ EsLintSettings settings)
+ {
+ context.NotNull(nameof(context));
+ settings.NotNull(nameof(settings));
+
+ return new EsLintProvider(context.Log, settings);
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/EsLintRuleUrlResolver.cs b/src/Cake.Prca.Issues.EsLint/EsLintRuleUrlResolver.cs
new file mode 100644
index 0000000..a62c5a3
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/EsLintRuleUrlResolver.cs
@@ -0,0 +1,33 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System;
+
+ ///
+ /// Class for retrieving an URL linking to a site describing a rule.
+ ///
+ internal class EsLintRuleUrlResolver : BaseRuleUrlResolver
+ {
+ private static readonly Lazy InstanceValue =
+ new Lazy(() => new EsLintRuleUrlResolver());
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ private EsLintRuleUrlResolver()
+ {
+ this.AddUrlResolver(x =>
+ new Uri("http://eslint.org/docs/rules/" + x.Rule));
+ }
+
+ ///
+ /// Gets the instance of the rule resolver.
+ ///
+ public static EsLintRuleUrlResolver Instance => InstanceValue.Value;
+
+ ///
+ protected override bool TryGetRuleDescription(string rule, BaseRuleDescription ruleDescription)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint/EsLintSettings.cs b/src/Cake.Prca.Issues.EsLint/EsLintSettings.cs
new file mode 100644
index 0000000..a6eed76
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/EsLintSettings.cs
@@ -0,0 +1,83 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System.IO;
+ using Core.IO;
+
+ ///
+ /// Settings for .
+ ///
+ public class EsLintSettings
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Path to the the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ protected EsLintSettings(FilePath logFilePath, ILogFileFormat format)
+ {
+ logFilePath.NotNull(nameof(logFilePath));
+ format.NotNull(nameof(format));
+
+ this.Format = format;
+
+ using (var stream = new FileStream(logFilePath.FullPath, FileMode.Open, FileAccess.Read))
+ {
+ using (var sr = new StreamReader(stream))
+ {
+ this.LogFileContent = sr.ReadToEnd();
+ }
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Content of the the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ protected EsLintSettings(string logFileContent, ILogFileFormat format)
+ {
+ logFileContent.NotNullOrWhiteSpace(nameof(logFileContent));
+ format.NotNull(nameof(format));
+
+ this.LogFileContent = logFileContent;
+ this.Format = format;
+ }
+
+ ///
+ /// Gets the format of the MsBuild log file.
+ ///
+ public ILogFileFormat Format { get; private set; }
+
+ ///
+ /// Gets the content of the log file.
+ ///
+ public string LogFileContent { get; private set; }
+
+ ///
+ /// Returns a new instance of the class from a log file on disk.
+ ///
+ /// Path to the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ /// Instance of the class.
+ public static EsLintSettings FromFilePath(FilePath logFilePath, ILogFileFormat format)
+ {
+ return new EsLintSettings(logFilePath, format);
+ }
+
+ ///
+ /// Returns a new instance of the class from the content
+ /// of a ESLint log file.
+ ///
+ /// Content of the ESLint log file.
+ /// The log file needs to be in the format as defined by the parameter.
+ /// Format of the provided ESLint log file.
+ /// Instance of the class.
+ public static EsLintSettings FromContent(string logFileContent, ILogFileFormat format)
+ {
+ return new EsLintSettings(logFileContent, format);
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/FodyWeavers.xml b/src/Cake.Prca.Issues.EsLint/FodyWeavers.xml
new file mode 100644
index 0000000..e0a35bd
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/FodyWeavers.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/Cake.Prca.Issues.EsLint/ILogFileFormat.cs b/src/Cake.Prca.Issues.EsLint/ILogFileFormat.cs
new file mode 100644
index 0000000..230d3ab
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/ILogFileFormat.cs
@@ -0,0 +1,20 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Definition of a ESLint log file format.
+ ///
+ public interface ILogFileFormat
+ {
+ ///
+ /// Gets all code analysis issues.
+ ///
+ /// General settings to use.
+ /// Settings for code analysis provider to use.
+ /// List of code analysis issues
+ IEnumerable ReadIssues(
+ ReportCodeAnalysisIssuesToPullRequestSettings prcaSettings,
+ EsLintSettings settings);
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/JsonFormat.cs b/src/Cake.Prca.Issues.EsLint/JsonFormat.cs
new file mode 100644
index 0000000..fe74003
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/JsonFormat.cs
@@ -0,0 +1,66 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using Core.Diagnostics;
+ using Newtonsoft.Json;
+ using Newtonsoft.Json.Linq;
+
+ ///
+ /// ESLint Json format.
+ ///
+ internal class JsonFormat : LogFileFormat
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Cake log instance.
+ public JsonFormat(ICakeLog log)
+ : base(log)
+ {
+ }
+
+ ///
+ public override IEnumerable ReadIssues(
+ ReportCodeAnalysisIssuesToPullRequestSettings prcaSettings,
+ EsLintSettings settings)
+ {
+ prcaSettings.NotNull(nameof(prcaSettings));
+ settings.NotNull(nameof(settings));
+
+ var logFileEntries =
+ JsonConvert.DeserializeObject>(settings.LogFileContent);
+
+ return
+ from file in logFileEntries
+ from message in file.SelectToken("messages")
+ let
+ rule = (string)message.SelectToken("ruleId")
+ select
+ new CodeAnalysisIssue(
+ GetRelativeFilePath((string)file.SelectToken("filePath"), prcaSettings),
+ (int)message.SelectToken("line"),
+ (string)message.SelectToken("message"),
+ (int)message.SelectToken("severity"),
+ rule,
+ EsLintRuleUrlResolver.Instance.ResolveRuleUrl(rule));
+ }
+
+ private static string GetRelativeFilePath(
+ string absoluteFilePath,
+ ReportCodeAnalysisIssuesToPullRequestSettings prcaSettings)
+ {
+ // Make path relative to repository root.
+ var relativeFilePath = absoluteFilePath.Substring(prcaSettings.RepositoryRoot.FullPath.Length);
+
+ // Remove leading directory separator.
+ if (relativeFilePath.StartsWith(Path.DirectorySeparatorChar.ToString()))
+ {
+ relativeFilePath = relativeFilePath.Substring(1);
+ }
+
+ return relativeFilePath;
+ }
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/LogFileFormat.cs b/src/Cake.Prca.Issues.EsLint/LogFileFormat.cs
new file mode 100644
index 0000000..fd7a7a7
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/LogFileFormat.cs
@@ -0,0 +1,32 @@
+namespace Cake.Prca.Issues.EsLint
+{
+ using System.Collections.Generic;
+ using Core.Diagnostics;
+
+ ///
+ /// Base class for all ESLint log file format implementations.
+ ///
+ public abstract class LogFileFormat : ILogFileFormat
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Cake log instance.
+ protected LogFileFormat(ICakeLog log)
+ {
+ log.NotNull(nameof(log));
+
+ this.Log = log;
+ }
+
+ ///
+ /// Gets the Cake log instance.
+ ///
+ protected ICakeLog Log { get; private set; }
+
+ ///
+ public abstract IEnumerable ReadIssues(
+ ReportCodeAnalysisIssuesToPullRequestSettings prcaSettings,
+ EsLintSettings settings);
+ }
+}
diff --git a/src/Cake.Prca.Issues.EsLint/Properties/AssemblyInfo.cs b/src/Cake.Prca.Issues.EsLint/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a09160f
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+using System;
+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: AssemblyTitle("ESLint support for Cake Pull Request Code Analysis")]
+[assembly: AssemblyDescription("ESLint support for the Pull Request Code Analysis Addin for Cake Build Automation System")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("BBT Software AG")]
+[assembly: AssemblyProduct("Cake Pull Request Code Analysis Addin")]
+[assembly: AssemblyCopyright("Copyright © 2017 BBT Software AG, Root/Zermatt, Switzerland")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 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("c6e0bc8d-6bd8-475e-a69f-ced3ffb86362")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: CLSCompliant(true)]
+[assembly: InternalsVisibleTo("Cake.Prca.Issues.EsLint.Tests")]
diff --git a/src/Cake.Prca.Issues.EsLint/packages.config b/src/Cake.Prca.Issues.EsLint/packages.config
new file mode 100644
index 0000000..2097df5
--- /dev/null
+++ b/src/Cake.Prca.Issues.EsLint/packages.config
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file