public void Should_Read_Basic_Issues_Correct()
            {
                // Given
                var fixture = new TerraformProviderFixture("basic.json", @"./");

                // When
                var issues = fixture.ReadIssues().ToList();

                // Then
                issues.Count.ShouldBe(2);
                IssueChecker.Check(
                    issues[0],
                    IssueBuilder.NewIssue(
                        "\"anonymous\": [DEPRECATED] For versions later than 3.0.0, absence of a token enables this mode",
                        "Cake.Issues.Terraform.TerraformIssuesProvider",
                        "Terraform")
                    .WithPriority(IssuePriority.Warning));
                IssueChecker.Check(
                    issues[1],
                    IssueBuilder.NewIssue(
                        "The argument \"name\" is required, but no definition was found.",
                        "Cake.Issues.Terraform.TerraformIssuesProvider",
                        "Terraform")
                    .InFile("main.tf", 14, 14, 37, 37)
                    .OfRule("Missing required argument")
                    .WithPriority(IssuePriority.Error));
            }
        /// <inheritdoc />
        public override IEnumerable <IIssue> ReadIssues(
            MarkdownlintIssuesProvider issueProvider,
            IRepositorySettings repositorySettings,
            MarkdownlintIssuesSettings markdownlintIssuesSettings)
        {
            issueProvider.NotNull(nameof(issueProvider));
            repositorySettings.NotNull(nameof(repositorySettings));
            markdownlintIssuesSettings.NotNull(nameof(markdownlintIssuesSettings));

            Dictionary <string, IEnumerable <Issue> > logFileEntries;

            using (var ms = new MemoryStream(markdownlintIssuesSettings.LogFileContent.RemovePreamble()))
            {
                var jsonSerializer = new DataContractJsonSerializer(
                    typeof(Dictionary <string, IEnumerable <Issue> >),
                    settings: new DataContractJsonSerializerSettings {
                    UseSimpleDictionaryFormat = true
                });

                logFileEntries = jsonSerializer.ReadObject(ms) as Dictionary <string, IEnumerable <Issue> >;
            }

            return
                (from file in logFileEntries
                 from entry in file.Value
                 let
                 rule = entry.ruleName
                        select
                        IssueBuilder
                        .NewIssue(entry.ruleDescription, issueProvider)
                        .InFile(file.Key, entry.lineNumber)
                        .WithPriority(IssuePriority.Warning)
                        .OfRule(rule, MarkdownlintRuleUrlResolver.Instance.ResolveRuleUrl(rule))
                        .Create());
        }
예제 #3
0
            public void Should_Read_Both_Warnings_And_Errors()
            {
                // Given
                var fixture = new MsBuildIssuesProviderFixture <XmlFileLoggerLogFileFormat>("IssueWithBothWarningAndErrors.xml");

                // When
                var issues = fixture.ReadIssues().ToList();

                // Then
                issues.Count.ShouldBe(2);
                IssueChecker.Check(
                    issues[0],
                    IssueBuilder.NewIssue(
                        @"Microsoft.Usage : 'ConfigurationManager.GetSortedConfigFiles(String)' creates an exception of type 'ApplicationException', an exception type that is not sufficiently specific and should never be raised by user code. If this exception instance might be thrown, use a different exception type.",
                        "Cake.Issues.MsBuild.MsBuildIssuesProvider",
                        "MSBuild")
                    .InProjectOfName(string.Empty)
                    .InFile(@"src\Cake.Issues.MsBuild.Tests\MsBuildIssuesProviderTests.cs", 1311)
                    .OfRule("CA2201", new Uri("https://www.google.com/search?q=\"CA2201:\"+site:docs.microsoft.com"))
                    .WithPriority(IssuePriority.Warning));
                IssueChecker.Check(
                    issues[1],
                    IssueBuilder.NewIssue(
                        @"'ConfigurationManager.GetSortedConfigFiles(String)': not all code paths return a value",
                        "Cake.Issues.MsBuild.MsBuildIssuesProvider",
                        "MSBuild")
                    .InProjectOfName(string.Empty)
                    .InFile(@"src\Cake.Issues.MsBuild.Tests\MsBuildIssuesProviderTests.cs", 1311)
                    .OfRule("CS0161", null)
                    .WithPriority(IssuePriority.Error));
            }
            public void Should_Throw_If_Modified_Files_Contain_Absolute_Path()
            {
                // Given
                var fixture =
                    new PullRequestsFixture(
                        (builder, settings) => builder
                        .WithFilteringByModifiedFilesCapability(
                            new List <FilePath>
                {
                    new FilePath(@"c:\FakeIssueProvider.cs")
                }));

                // When
                var result = Record.Exception(() =>
                                              fixture.FilterIssues(
                                                  new List <IIssue>
                {
                    IssueBuilder
                    .NewIssue("Message", "ProviderType", "ProviderName")
                    .InFile(@"src\Cake.Issues.Tests\FakeIssueProvider.cs", 10)
                    .OfRule("Rule")
                    .WithPriority(IssuePriority.Warning)
                    .Create()
                },
                                                  new Dictionary <IIssue, IssueCommentInfo>()));

                // Then
                result.IsPullRequestIssuesException(@"Absolute file paths are not suported for modified files. Path: c:/FakeIssueProvider.cs");
            }
        /// <inheritdoc />
        public override IEnumerable <IIssue> ReadIssues(
            MarkdownlintIssuesProvider issueProvider,
            IssueCommentFormat format,
            RepositorySettings repositorySettings,
            MarkdownlintIssuesSettings markdownlintIssuesSettings)
        {
            issueProvider.NotNull(nameof(issueProvider));
            repositorySettings.NotNull(nameof(repositorySettings));
            markdownlintIssuesSettings.NotNull(nameof(markdownlintIssuesSettings));

            var regex = new Regex(@"(.*): (\d*): (MD\d*)/((?:\w*-*/*)*) (.*)");

            foreach (var line in markdownlintIssuesSettings.LogFileContent.ToStringUsingEncoding().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None).ToList().Where(s => !string.IsNullOrEmpty(s)))
            {
                var groups = regex.Match(line).Groups;

                // Read affected file from the line.
                if (!this.TryGetFile(groups, repositorySettings, out string fileName))
                {
                    continue;
                }

                var lineNumber      = int.Parse(groups[2].Value);
                var rule            = groups[3].Value;
                var ruleDescription = groups[5].Value;

                yield return
                    (IssueBuilder
                     .NewIssue(ruleDescription, issueProvider)
                     .InFile(fileName, lineNumber)
                     .WithPriority(IssuePriority.Warning)
                     .OfRule(rule, MarkdownlintRuleUrlResolver.Instance.ResolveRuleUrl(rule))
                     .Create());
            }
        }
예제 #6
0
        /// <inheritdoc />
        protected override IEnumerable <IIssue> InternalReadIssues()
        {
            // Determine path of the doc root.
            var terraformRootPath = this.IssueProviderSettings.TerraformRootPath;

            if (terraformRootPath.IsRelative)
            {
                terraformRootPath = terraformRootPath.MakeAbsolute(this.Settings.RepositoryRoot);
            }

            ValidateFile validateFile = null;

            var logFileContent = this.IssueProviderSettings.LogFileContent.ToStringUsingEncoding(true);

            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(logFileContent)))
            {
                var jsonSerializer = new DataContractJsonSerializer(typeof(ValidateFile));
                validateFile = jsonSerializer.ReadObject(ms) as ValidateFile;
            }

            return
                (from diagnostic in validateFile.diagnostics
                 select
                 IssueBuilder
                 .NewIssue(GetMessage(diagnostic.summary, diagnostic.detail), this)
                 .InFile(
                     this.TryGetFile(diagnostic.range?.filename, terraformRootPath),
                     diagnostic.range?.start?.line,
                     diagnostic.range?.end?.line,
                     diagnostic.range?.start?.column,
                     diagnostic.range?.end?.column)
                 .OfRule(GetRule(diagnostic.summary, diagnostic.detail))
                 .WithPriority(GetPriority(diagnostic.severity))
                 .Create());
        }
        /// <summary>
        /// Returns the issue for a message from the log file.
        /// </summary>
        /// <param name="logFileEntry">Issue reported by markdownlint.</param>
        /// <param name="issueProvider">Issue provider instance.</param>
        /// <param name="repositorySettings">Repository settings.</param>
        /// <returns>Issue instance.</returns>
        private static IIssue GetIssue(
            LogFileEntry logFileEntry,
            MarkdownlintIssuesProvider issueProvider,
            IRepositorySettings repositorySettings)
        {
            var message = logFileEntry.ruleDescription;

            if (!string.IsNullOrEmpty(logFileEntry.errorDetail))
            {
                message += $": {logFileEntry.errorDetail}";
            }

            return
                (IssueBuilder
                 .NewIssue(message, issueProvider)
                 .InFile(
                     GetFilePath(logFileEntry.fileName, repositorySettings),
                     logFileEntry.lineNumber,
                     logFileEntry.errorRange != null ? logFileEntry.lineNumber : null,
                     logFileEntry.errorRange != null ? logFileEntry.errorRange[0] : null,
                     logFileEntry.errorRange != null ? logFileEntry.errorRange[0] + logFileEntry.errorRange[1] : null)
                 .WithPriority(IssuePriority.Warning)
                 .OfRule(logFileEntry.ruleNames.First(), new Uri(logFileEntry.ruleInformation))
                 .Create());
        }
        /// <inheritdoc />
        public override IEnumerable <IIssue> ReadIssues(
            MarkdownlintIssuesProvider issueProvider,
            IRepositorySettings repositorySettings,
            MarkdownlintIssuesSettings markdownlintIssuesSettings)
        {
            issueProvider.NotNull(nameof(issueProvider));
            repositorySettings.NotNull(nameof(repositorySettings));
            markdownlintIssuesSettings.NotNull(nameof(markdownlintIssuesSettings));

            var regex = new Regex(@"(?<filePath>.*[^:\d+]): ?(?<lineNumber>\d+):?(?<columnNumber>\d+)? (?<ruleId>MD\d+)/(?<ruleName>(?:\w*-*/*)*) (?<message>.*)");

            foreach (var line in markdownlintIssuesSettings.LogFileContent.ToStringUsingEncoding().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None).ToList().Where(s => !string.IsNullOrEmpty(s)))
            {
                var groups = regex.Match(line).Groups;

                // Read affected file from the line.
                if (!this.TryGetFile(groups, repositorySettings, out string fileName))
                {
                    continue;
                }

                var lineNumber = int.Parse(groups["lineNumber"].Value);
                var ruleId     = groups["ruleId"].Value;
                var message    = groups["message"].Value;

                yield return
                    (IssueBuilder
                     .NewIssue(message, issueProvider)
                     .InFile(fileName, lineNumber)
                     .WithPriority(IssuePriority.Warning)
                     .OfRule(ruleId, MarkdownlintRuleUrlResolver.Instance.ResolveRuleUrl(ruleId))
                     .Create());
            }
        }
예제 #9
0
            public void Should_Read_Correct_Number_Of_Issues_Not_Related_To_A_File()
            {
                // Given
                var issue1 =
                    IssueBuilder
                    .NewIssue("Foo", "ProviderTypeFoo", "ProviderNameFoo")
                    .OfRule("Foo")
                    .WithPriority(IssuePriority.Warning)
                    .Create();
                var issue2 =
                    IssueBuilder
                    .NewIssue("Bar", "ProviderTypeBar", "ProviderNameBar")
                    .OfRule("Bar")
                    .WithPriority(IssuePriority.Warning)
                    .Create();
                var fixture = new IssuesFixture();

                fixture.IssueProviders.Clear();
                fixture.IssueProviders.Add(
                    new FakeIssueProvider(
                        fixture.Log,
                        new List <IIssue>
                {
                    issue1,
                    issue2,
                }));

                // When
                var issues = fixture.ReadIssues().ToList();

                // Then
                issues.Count.ShouldBe(2);
                issues.ShouldContain(issue1);
                issues.ShouldContain(issue2);
            }
예제 #10
0
            public void Should_Serialize_Issues()
            {
                // Given
                var issues =
                    new List <IIssue>
                {
                    IssueBuilder
                    .NewIssue("message1", "providerType1", "providerName1")
                    .Create(),
                    IssueBuilder
                    .NewIssue("message2", "providerType2", "providerName2")
                    .Create(),
                };
                var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json");

                try
                {
                    // When
                    issues.SerializeToJsonFile(filePath);

                    // Then
                    System.IO.File.Exists(filePath.FullPath).ShouldBeTrue();
                }
                finally
                {
                    System.IO.File.Delete(filePath.FullPath);
                }
            }
            public void Should_Return_The_Correct_Link(
                string repositoryUrl,
                string filePath,
                int?line,
                int?endLine,
                string commitId,
                string expectedLink)
            {
                // Given
                var issue =
                    IssueBuilder
                    .NewIssue("Foo", "ProviderTypeFoo", "ProviderNameFoo")
                    .InFile(filePath, line, endLine, null, null)
                    .OfRule("Foo")
                    .WithPriority(IssuePriority.Warning)
                    .Create();

                // When
                var result =
                    new GitHubFileLinkSettingsBuilder(new Uri(repositoryUrl))
                    .Commit(commitId)
                    .GetFileLink(issue);

                // Then
                result.ToString().ShouldBe(expectedLink);
            }
예제 #12
0
            public void Should_Return_List_Of_IssuesV2()
            {
                // Given
                var filePath = new FilePath("Testfiles/issuesV2.json");

                // When
                var result = filePath.DeserializeToIssues().ToList();

                // Then
                result.Count.ShouldBe(2);
                IssueChecker.Check(
                    result[0],
                    IssueBuilder.NewIssue(
                        "Something went wrong.",
                        "TestProvider",
                        "Test Provider")
                    .WithMessageInHtmlFormat("Something went <b>wrong</b>.")
                    .WithMessageInMarkdownFormat("Something went **wrong**.")
                    .InProject(@"src\Foo\Bar.csproj", "Bar")
                    .InFile(@"src\Foo\Bar.cs", 42)
                    .OfRule("Rule", new Uri("https://google.com"))
                    .WithPriority(IssuePriority.Warning));
                IssueChecker.Check(
                    result[1],
                    IssueBuilder.NewIssue(
                        "Something went wrong again.",
                        "TestProvider",
                        "Test Provider")
                    .WithMessageInHtmlFormat("Something went <b>wrong</b> again.")
                    .WithMessageInMarkdownFormat("Something went **wrong** again.")
                    .InProject(@"src\Foo\Bar.csproj", "Bar")
                    .InFile(@"src\Foo\Bar2.cs")
                    .WithPriority(IssuePriority.Warning));
            }
            public void Should_Read_Issue_Correct()
            {
                // Given
                var fixture = new DupFinderIssuesProviderFixture("DupFinder.xml");

                // When
                var issues = fixture.ReadIssues().ToList();

                // Then
                issues.Count.ShouldBe(5);
                issues.Count(i =>
                             i.FilePath() == "Src/Foo.cs" &&
                             i.Line == 16 && i.EndLine == 232).ShouldBe(1);

                var issueToVerify = issues.Single(i =>
                                                  i.FilePath() == "Src/Foo.cs" &&
                                                  i.Line == 16 && i.EndLine == 232);

                IssueChecker.Check(
                    issueToVerify,
                    IssueBuilder.NewIssue(
                        ExpectedIssueIdentifier,
                        ExpectedIssueMessage,
                        "Cake.Issues.DupFinder.DupFinderIssuesProvider",
                        "DupFinder")
                    .WithMessageInMarkdownFormat(ExpectedIssueMarkdownMessage)
                    .WithMessageInHtmlFormat(ExpectedIssueHtmlMessage)
                    .InFile(@"Src\Foo.cs", 16, 232, null, null)
                    .OfRule("dupFinder")
                    .WithPriority(IssuePriority.Warning)
                    .Create());
            }
예제 #14
0
            public void Should_Return_Correct_Value(
                string filePath,
                int?line,
                string message,
                IssuePriority priority,
                string rule,
                string ruleUrl,
                string expectedResult)
            {
                // Given
                Uri ruleUri = null;

                if (!string.IsNullOrWhiteSpace(ruleUrl))
                {
                    ruleUri = new Uri(ruleUrl);
                }

                var issue =
                    IssueBuilder
                    .NewIssue(message, "ProviderType", "ProviderName")
                    .InFile(filePath, line)
                    .OfRule(rule, ruleUri)
                    .WithPriority(priority)
                    .Create();

                // When
                var result = ContentProvider.GetContent(issue);

                // Then
                result.ShouldBe(expectedResult);
            }
        /// <summary>
        /// Checks for binary files which are not tracked by LFS.
        /// </summary>
        /// <returns>List of issues for binary files which are not tracked by LFS.</returns>
        private IEnumerable <IIssue> CheckForBinaryFilesNotTrackedByLfs()
        {
            if (!this.allFiles.Value.Any())
            {
                return(new List <IIssue>());
            }

            if (!this.binaryFiles.Value.Any())
            {
                return(new List <IIssue>());
            }

            var lfsTrackedFiles            = this.GetLfsTrackedFilesFromRepository();
            var binaryFilesNotTrackedByLfs =
                this.DetermineBinaryFilesNotTrackedWithLfs(this.binaryFiles.Value, lfsTrackedFiles);

            var result = new List <IIssue>();

            foreach (var file in binaryFilesNotTrackedByLfs)
            {
                var ruleDescription = new BinaryFileNotTrackedByLfsRuleDescription();

                result.Add(
                    IssueBuilder
                    .NewIssue($"The binary file \"{file}\" is not tracked by Git LFS", this)
                    .WithMessageInHtmlFormat($"The binary file <code>{file}</code> is not tracked by Git LFS")
                    .WithMessageInMarkdownFormat($"The binary file `{file}` is not tracked by Git LFS")
                    .InFile(file)
                    .OfRule(ruleDescription)
                    .Create());
            }

            return(result);
        }
예제 #16
0
            public void Should_Give_Correct_Result_For_RuleUrl_After_Roundtrip()
            {
                // Given
                var ruleUrl = new Uri("https://rule.url");
                var issue   =
                    IssueBuilder
                    .NewIssue("message", "providerType", "providerName")
                    .OfRule("rule", ruleUrl)
                    .Create();
                var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json");

                try
                {
                    // When
                    issue.SerializeToJsonFile(filePath);
                    var result = filePath.DeserializeToIssue();

                    // Then
                    result.RuleUrl.ToString().ShouldBe(ruleUrl.ToString());
                }
                finally
                {
                    System.IO.File.Delete(filePath.FullPath);
                }
            }
        /// <inheritdoc />
        public override IEnumerable <IIssue> ReadIssues(
            EsLintIssuesProvider issueProvider,
            IRepositorySettings repositorySettings,
            EsLintIssuesSettings esLintsettings)
        {
            issueProvider.NotNull(nameof(issueProvider));
            repositorySettings.NotNull(nameof(repositorySettings));
            esLintsettings.NotNull(nameof(esLintsettings));

            IEnumerable <LogFile> logFileEntries = null;

            using (var ms = new MemoryStream(esLintsettings.LogFileContent.ToStringUsingEncoding(true).ToByteArray()))
            {
                var jsonSerializer = new DataContractJsonSerializer(typeof(LogFile[]));
                logFileEntries = jsonSerializer.ReadObject(ms) as LogFile[];
            }

            if (logFileEntries != null)
            {
                return
                    (from file in logFileEntries
                     from message in file.messages
                     let
                     rule = message.ruleId
                            select
                            IssueBuilder
                            .NewIssue(message.message, issueProvider)
                            .InFile(GetRelativeFilePath(file.filePath, repositorySettings), message.line, message.column)
                            .OfRule(rule, EsLintRuleUrlResolver.Instance.ResolveRuleUrl(rule))
                            .WithPriority(GetPriority(message.severity))
                            .Create());
            }

            return(new List <IIssue>());
        }
예제 #18
0
            public void Should_Give_Correct_Result_For_Line_After_Roundtrip()
            {
                // Given
                var line  = 42;
                var issue =
                    IssueBuilder
                    .NewIssue("message", "providerType", "providerName")
                    .InFile(@"src/foo.bar", line)
                    .Create();
                var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json");

                try
                {
                    // When
                    issue.SerializeToJsonFile(filePath);
                    var result = filePath.DeserializeToIssue();

                    // Then
                    result.Line.ShouldBe(line);
                }
                finally
                {
                    System.IO.File.Delete(filePath.FullPath);
                }
            }
예제 #19
0
            public void Should_Give_Correct_Result_For_PriorityName_After_Roundtrip()
            {
                // Given
                var priorityName = "priorityName";
                var issue        =
                    IssueBuilder
                    .NewIssue("message", "providerType", "providerName")
                    .WithPriority(42, priorityName)
                    .Create();
                var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json");

                try
                {
                    // When
                    issue.SerializeToJsonFile(filePath);
                    var result = filePath.DeserializeToIssue();

                    // Then
                    result.PriorityName.ShouldBe(priorityName);
                }
                finally
                {
                    System.IO.File.Delete(filePath.FullPath);
                }
            }
예제 #20
0
            public void Should_Order_By_FilePath()
            {
                // Given
                var issue1 =
                    IssueBuilder
                    .NewIssue("Message Foo", "ProviderType Foo", "ProviderName Foo")
                    .OfRule("Rule Foo")
                    .InFile(@"src\Cake.Issues.Tests\B.cs", 12)
                    .WithPriority(IssuePriority.Warning)
                    .Create();
                var issue2 =
                    IssueBuilder
                    .NewIssue("Message Bar", "ProviderType Bar", "ProviderName Bar")
                    .InFile(@"src\Cake.Issues.Tests\A.cs", 12)
                    .OfRule("Rule Bar")
                    .WithPriority(IssuePriority.Warning)
                    .Create();
                var issues =
                    new List <IIssue>
                {
                    issue1,
                    issue2,
                };

                // When
                var result = issues.SortWithDefaultPriorization();

                // Then
                result.First().ShouldBe(issue2);
                result.Last().ShouldBe(issue1);
            }
예제 #21
0
            public void Should_Generate_Report_From_Custom_Template()
            {
                // Given
                var fixture = new GenericIssueReportFixture("<ul>@foreach(var issue in Model){<li>@issue.MessageText</li>}</ul>");
                var issues  =
                    new List <IIssue>
                {
                    IssueBuilder
                    .NewIssue("Message Foo", "ProviderType Foo", "ProviderName Foo")
                    .InFile(@"src\Cake.Issues.Reporting.Generic.Tests\Foo.cs", 10)
                    .OfRule("Rule Foo")
                    .WithPriority(IssuePriority.Warning)
                    .Create(),
                    IssueBuilder
                    .NewIssue("Message Bar", "ProviderType Bar", "ProviderName Bar")
                    .InFile(@"src\Cake.Issues.Reporting.Generic.Tests\Foo.cs", 12)
                    .OfRule("Rule Bar")
                    .WithPriority(IssuePriority.Warning)
                    .Create(),
                };
                var expectedResult =
                    @"<ul><li>Message Foo</li><li>Message Bar</li></ul>";

                // When
                var result = fixture.CreateReport(issues);

                // Then
                result.ShouldBe(expectedResult);
            }
예제 #22
0
            public void Should_Generate_Report_From_Embedded_Template(GenericIssueReportTemplate template)
            {
                // Given
                var fixture = new GenericIssueReportFixture(template);
                var issues  =
                    new List <IIssue>
                {
                    IssueBuilder
                    .NewIssue("Message Foo", "ProviderType Foo", "ProviderName Foo")
                    .WithMessageInHtmlFormat("Message <b>Foo</b>")
                    .WithMessageInMarkdownFormat("Message **Foo**")
                    .InFile(@"src\Cake.Issues.Reporting.Generic.Tests\Foo.cs", 10)
                    .OfRule("Rule Foo")
                    .WithPriority(IssuePriority.Warning)
                    .Create(),
                    IssueBuilder
                    .NewIssue("Message Bar", "ProviderType Bar", "ProviderName Bar")
                    .InFile(@"src\Cake.Issues.Reporting.Generic.Tests\Foo.cs", 12)
                    .OfRule("Rule Bar")
                    .WithPriority(IssuePriority.Warning)
                    .Create(),
                };

                // When
                var result = fixture.CreateReport(issues);

                // Then
                // No additional tests. We only check if template can be compiled.
            }
            public void Should_Return_The_Correct_Link(
                string repositoryUrl,
                string filePath,
                int?line,
                int?endLine,
                int?column,
                int?endColumn,
                string commitId,
                string expectedLink)
            {
                // Given
                var issue =
                    IssueBuilder
                    .NewIssue("Foo", "ProviderTypeFoo", "ProviderNameFoo")
                    .InFile(filePath, line, endLine, column, endColumn)
                    .Create();

                // When
                var result =
                    new AzureDevOpsFileLinkSettingsBuilder(new Uri(repositoryUrl))
                    .Commit(commitId)
                    .GetFileLink(issue);

                // Then
                result.ToString().ShouldBe(expectedLink);
            }
        /// <summary>
        /// Checks for files path length.
        /// </summary>
        /// <returns>List of issues for repository files with paths exceeding the allowed maximum.</returns>
        private IEnumerable <IIssue> CheckForFilesPathLength()
        {
            if (!this.allFiles.Value.Any())
            {
                return(new List <IIssue>());
            }

            var result = new List <IIssue>();

            foreach (string file in this.allFiles.Value)
            {
                if (file.Length > this.IssueProviderSettings.MaxFilePathLength)
                {
                    var ruleDescription = new FilePathTooLongRuleDescription();

                    result.Add(
                        IssueBuilder
                        .NewIssue($"The path for the file \"{file}\" is too long. Maximum allowed path length is {this.IssueProviderSettings.MaxFilePathLength}, actual path length is {file.Length}.", this)
                        .WithMessageInHtmlFormat($"The path for the file <code>{file}</code> is too long. Maximum allowed path length is {this.IssueProviderSettings.MaxFilePathLength}, actual path length is {file.Length}.")
                        .WithMessageInMarkdownFormat($"The path for the file `{file}` is too long. Maximum allowed path length is {this.IssueProviderSettings.MaxFilePathLength}, actual path length is {file.Length}.")
                        .InFile(file)
                        .OfRule(ruleDescription)
                        .Create());
                }
            }

            return(result);
        }
        /// <inheritdoc/>
        public override IEnumerable <IIssue> ReadIssues(
            MsBuildIssuesProvider issueProvider,
            IssueCommentFormat format,
            RepositorySettings repositorySettings,
            MsBuildIssuesSettings issueProviderSettings)
        {
#pragma warning disable SA1123 // Do not place regions within elements
            #region DupFinder Exclusion
#pragma warning restore SA1123 // Do not place regions within elements

            issueProvider.NotNull(nameof(issueProvider));
            repositorySettings.NotNull(nameof(repositorySettings));
            issueProviderSettings.NotNull(nameof(issueProviderSettings));

            #endregion

            var result = new List <IIssue>();

            var binLogReader = new BinLogReader();
            foreach (var record in binLogReader.ReadRecords(issueProviderSettings.LogFileContent))
            {
                var buildEventArgs = record.Args;

                if (buildEventArgs is BuildWarningEventArgs buildWarning)
                {
                    var projectFileRelativePath = this.GetProject(buildWarning, repositorySettings);

                    // Read affected file from the warning.
                    if (!this.TryGetFile(buildWarning, repositorySettings, out string fileName))
                    {
                        continue;
                    }

                    var line = GetLine(buildWarning);
                    var rule = buildWarning.Code;

                    // Determine rule URL.
                    Uri ruleUrl = null;
                    if (!string.IsNullOrWhiteSpace(rule))
                    {
                        ruleUrl = MsBuildRuleUrlResolver.Instance.ResolveRuleUrl(rule);
                    }

                    // Build issue.
                    result.Add(
                        IssueBuilder
                        .NewIssue(buildWarning.Message, issueProvider)
                        .WithPriority(IssuePriority.Warning)
                        .InProject(projectFileRelativePath, System.IO.Path.GetFileNameWithoutExtension(projectFileRelativePath))
                        .InFile(fileName, line)
                        .OfRule(rule, ruleUrl)
                        .Create());
                }
            }

            return(result);
        }
        /// <summary>
        /// Returns an issue for values from an MsBuild log.
        /// </summary>
        /// <param name="priority">Priority of the issue.</param>
        /// <param name="message">Raw value from the MsBuild log containing the message.</param>
        /// <param name="projectFile">Raw value from the MsBuild log containing the project file.</param>
        /// <param name="file">Raw value from the MsBuild log containing the file.</param>
        /// <param name="lineNumber">Raw value from the MsBuild log containing the line number.</param>
        /// <param name="endLineNumber">Raw value from the MsBuild log containing the end of the line range.</param>
        /// <param name="columnNumber">Raw value from the MsBuild log containing the column.</param>
        /// <param name="endColumnNumber">Raw value from the MsBuild log containing the end of the column range.</param>
        /// <param name="code">Raw value from the MsBuild log containing the rule.</param>
        /// <param name="issueProvider">Issue provider instance.</param>
        /// <param name="repositorySettings">Repository settings to use.</param>
        /// <returns>Issue instance or null, if the values could not be parsed.</returns>
        private IIssue GetIssue(
            IssuePriority priority,
            string message,
            string projectFile,
            string file,
            int lineNumber,
            int endLineNumber,
            int columnNumber,
            int endColumnNumber,
            string code,
            MsBuildIssuesProvider issueProvider,
            IRepositorySettings repositorySettings)
        {
            // Ignore warnings or errors without a message.
            if (string.IsNullOrWhiteSpace(message))
            {
                this.Log.Verbose("Skip element since it doesn't contain a message");
                return(null);
            }

            var projectFileRelativePath = this.GetProject(projectFile, repositorySettings);

            // Read affected file from the warning or error.
            var(result, fileName) = this.TryGetFile(file, projectFile, repositorySettings);
            if (!result)
            {
                this.Log.Information("Skip element since file path could not be parsed");
                return(null);
            }

            var line      = GetLine(lineNumber);
            var endLine   = GetLine(endLineNumber);
            var column    = GetColumn(columnNumber);
            var endColumn = GetColumn(endColumnNumber);
            var rule      = code;

            // Determine rule URL.
            Uri ruleUrl = null;

            if (!string.IsNullOrWhiteSpace(rule))
            {
                ruleUrl = MsBuildRuleUrlResolver.Instance.ResolveRuleUrl(rule);
            }

            // Build issue.
            return
                (IssueBuilder
                 .NewIssue(message, issueProvider)
                 .WithPriority(priority)
                 .InProject(projectFileRelativePath, System.IO.Path.GetFileNameWithoutExtension(projectFileRelativePath))
                 .InFile(fileName, line, endLine, column, endColumn)
                 .OfRule(rule, ruleUrl)
                 .Create());
        }
예제 #27
0
            public void Should_Set_RuleUrl()
            {
                // Given
                var issueBuilder    = IssueBuilder.NewIssue("message", "providerType", "providerName");
                var ruleDescription = new BinaryFileNotTrackedByLfsRuleDescription();

                // When
                var result = issueBuilder.OfRule(ruleDescription);

                // Then
                result.Create().RuleUrl.ToString().ShouldBe("https://cakeissues.net/docs/issue-providers/gitrepository/rules/BinaryFileNotTrackedByLfs");
            }
예제 #28
0
            public void Should_Set_PriorityName()
            {
                // Given
                var issueBuilder    = IssueBuilder.NewIssue("message", "providerType", "providerName");
                var ruleDescription = new BinaryFileNotTrackedByLfsRuleDescription();

                // When
                var result = issueBuilder.OfRule(ruleDescription);

                // Then
                result.Create().PriorityName.ShouldBe(ruleDescription.Priority.ToString());
            }
예제 #29
0
            public void Should_Throw_If_RuleDescription_Is_Null()
            {
                // Given
                var issueBuilder = IssueBuilder.NewIssue("message", "providerType", "providerName");
                BaseGitRepositoryIssuesRuleDescription ruleDescription = null;

                // When
                var result = Record.Exception(() => issueBuilder.OfRule(ruleDescription));

                // Then
                result.IsArgumentNullException("ruleDescription");
            }
        /// <summary>
        /// Checks for binary files which are not tracked by LFS.
        /// </summary>
        /// <param name="format">Preferred format of the messages.</param>
        /// <returns>List of issues for binary files which are not tracked by LFS.</returns>
        private IEnumerable <IIssue> CheckForBinaryFilesNotTrackedByLfs(IssueCommentFormat format)
        {
            var allFiles = this.GetAllFilesFromRepository();

            if (!allFiles.Any())
            {
                return(new List <IIssue>());
            }

            var textFiles = this.GetTextFilesFromRepository();

            var binaryFiles = this.DetermineBinaryFiles(allFiles, textFiles);

            if (!binaryFiles.Any())
            {
                return(new List <IIssue>());
            }

            var lfsTrackedFiles            = this.GetLfsTrackedFilesFromRepository();
            var binaryFilesNotTrackedByLfs = this.DetermineBinaryFilesNotTrackedWithLfs(binaryFiles, lfsTrackedFiles);

            var result = new List <IIssue>();

            foreach (var file in binaryFilesNotTrackedByLfs)
            {
                string message = null;
                switch (format)
                {
                case IssueCommentFormat.Markdown:
                    message = $"The binary file `{file}` is not tracked by Git LFS";
                    break;

                case IssueCommentFormat.Html:
                    message = $"The binary file <pre>{file}</pre> is not tracked by Git LFS";
                    break;

                default:
                    message = $"The binary file \"{file}\" is not tracked by Git LFS";
                    break;
                }

                var ruleDescription = new BinaryFileNotTrackedByLfsRuleDescription();

                result.Add(
                    IssueBuilder
                    .NewIssue(message, this)
                    .InFile(file)
                    .OfRule(ruleDescription)
                    .Create());
            }

            return(result);
        }