From f009722d0990419a98c64ed94f4ce29b3357e4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20J=C3=B8rgen=20Skogstad?= Date: Thu, 14 Nov 2024 22:05:23 +0100 Subject: [PATCH 1/2] --wip-- [skip ci] --- Digdir.Domain.Dialogporten.sln | 7 +++ Directory.Build.props | 4 ++ .../Extensions/ClaimsPrincipalExtensions.cs | 5 +- .../Common/IUserRegistry.cs | 7 ++- .../Dialogs/Queries/Get/GetDialogQuery.cs | 4 +- .../Commands/Update/UpdateDialogCommand.cs | 4 +- .../Checkpoints/CheckpointSynchronizer.cs | 3 +- .../Checkpoints/ICheckpointRepository.cs | 3 +- .../ICdcSink.cs | 6 ++- .../Outboxes/OutboxMessage.cs | 3 +- .../Authorization/DecisionRequestHelper.cs | 2 +- .../AnalyzerReleases.Shipped.md | 7 +++ .../AnalyzerReleases.Unshipped.md | 0 .../Digdir.Library.Analyzers/AssemblyInfo.cs | 3 ++ .../Digdir.Library.Analyzers.csproj | 23 +++++++++ .../Properties/launchSettings.json | 9 ++++ .../TodoCommentAnalyzer.cs | 49 +++++++++++++++++++ .../AspNetUtilitiesExtensions.cs | 2 +- 18 files changed, 125 insertions(+), 16 deletions(-) create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Shipped.md create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Unshipped.md create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AssemblyInfo.cs create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Digdir.Library.Analyzers.csproj create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Properties/launchSettings.json create mode 100644 src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs diff --git a/Digdir.Domain.Dialogporten.sln b/Digdir.Domain.Dialogporten.sln index 04d95ab2f..af4d515db 100644 --- a/Digdir.Domain.Dialogporten.sln +++ b/Digdir.Domain.Dialogporten.sln @@ -67,6 +67,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Digdir.Library.Utils.AspNet EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Digdir.Tool.Dialogporten.SlackNotifier.Tests", "tests\Digdir.Tool.Dialogporten.SlackNotifier.Tests\Digdir.Tool.Dialogporten.SlackNotifier.Tests.csproj", "{F7DF2792-9C83-49F7-B7DD-556E8EC577DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Digdir.Library.Analyzers", "src\Digdir.Library.Analyzers\Digdir.Library.Analyzers\Digdir.Library.Analyzers.csproj", "{88783EA8-EE64-490B-9C1E-E2365E861A88}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -165,6 +167,10 @@ Global {F7DF2792-9C83-49F7-B7DD-556E8EC577DB}.Debug|Any CPU.Build.0 = Debug|Any CPU {F7DF2792-9C83-49F7-B7DD-556E8EC577DB}.Release|Any CPU.ActiveCfg = Release|Any CPU {F7DF2792-9C83-49F7-B7DD-556E8EC577DB}.Release|Any CPU.Build.0 = Release|Any CPU + {88783EA8-EE64-490B-9C1E-E2365E861A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88783EA8-EE64-490B-9C1E-E2365E861A88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88783EA8-EE64-490B-9C1E-E2365E861A88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88783EA8-EE64-490B-9C1E-E2365E861A88}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -196,6 +202,7 @@ Global {E389C7C8-9610-40AC-86DC-769B1B7DC78E} = {CADB8189-4AA1-4732-844A-C41DBF3EC8B7} {6A485C65-3613-4A49-A16F-2789119F6F38} = {096E9B69-6783-4446-A895-0B6D7729A0D9} {F7DF2792-9C83-49F7-B7DD-556E8EC577DB} = {CADB8189-4AA1-4732-844A-C41DBF3EC8B7} + {88783EA8-EE64-490B-9C1E-E2365E861A88} = {096E9B69-6783-4446-A895-0B6D7729A0D9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B2FE67FF-7622-4AFB-AD8E-961B6A39D888} diff --git a/Directory.Build.props b/Directory.Build.props index 53097d9cb..afd687852 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,4 +15,8 @@ 8 + + + diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs index 0ebda5a25..f4691fb49 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs @@ -28,9 +28,8 @@ public static class ClaimsPrincipalExtensions private const char ScopeClaimSeparator = ' '; private const string PidClaim = "pid"; - - // TODO: This scope is also defined in WebAPI/GQL. Can this be fetched from a common auth lib? - // https://github.com/digdir/dialogporten/issues/647 + // TODO: https://github.com/digdir/dialogporten/issues/647 + // This scope is also defined in WebAPI/GQL. Can this be fetched from a common auth lib? // This could be done for all claims/scopes/prefixes etc, there are duplicates public const string ServiceProviderScope = "digdir:dialogporten.serviceprovider"; diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/IUserRegistry.cs b/src/Digdir.Domain.Dialogporten.Application/Common/IUserRegistry.cs index 1b3fa2512..ef459f90a 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/IUserRegistry.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/IUserRegistry.cs @@ -62,8 +62,11 @@ public async Task GetCurrentUserInformation(CancellationToken c var userId = GetCurrentUserId(); var name = userId.Type switch { - UserIdType.Person or UserIdType.ServiceOwnerOnBehalfOfPerson => await _partyNameRegistry.GetName(userId.ExternalIdWithPrefix, cancellationToken), - UserIdType.SystemUser => "System User",// TODO: Implement when SystemUsers are introduced? + UserIdType.Person or UserIdType.ServiceOwnerOnBehalfOfPerson => + await _partyNameRegistry.GetName(userId.ExternalIdWithPrefix, cancellationToken), + // TODO: https://github.com/digdir/dialogporten/issues/ + // Implement when SystemUsers are introduced? + UserIdType.SystemUser => "System User", UserIdType.Unknown => throw new UnreachableException(), UserIdType.ServiceOwner => throw new UnreachableException(), _ => throw new UnreachableException() diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs index e3c9d64e5..ded15eb1a 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs @@ -118,8 +118,8 @@ public async Task Handle(GetDialogQuery request, CancellationTo return new EntityDeleted(request.DialogId); } - // TODO: What if name lookup fails - // https://github.com/digdir/dialogporten/issues/387 + // TODO: https://github.com/digdir/dialogporten/issues/387 + // What if name lookup fails? dialog.UpdateSeenAt( currentUserInformation.UserId.ExternalIdWithPrefix, currentUserInformation.UserId.Type, diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs index e00af78a3..85114a36d 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs @@ -93,8 +93,8 @@ public async Task Handle(UpdateDialogCommand request, Cancel if (dialog.Deleted) { - // TODO: When restoration is implemented, add a hint to the error message. - // https://github.com/digdir/dialogporten/pull/406 + // TODO: https://github.com/digdir/dialogporten/issues/... + // When restoration is implemented, add a hint to the error message. return new BadRequest($"Entity '{nameof(DialogEntity)}' with key '{request.Id}' is removed, and cannot be updated."); } diff --git a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/CheckpointSynchronizer.cs b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/CheckpointSynchronizer.cs index 201d0ffc1..e5188b5ad 100644 --- a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/CheckpointSynchronizer.cs +++ b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/CheckpointSynchronizer.cs @@ -33,7 +33,8 @@ public override async Task StartAsync(CancellationToken cancellationToken) // This method will block the application from starting until // snapshots are loaded and permissions are verified - // TODO: Remove when checkpoint migration exists + // TODO: https://github.com/digdir/dialogporten/issues/... + // Remove when checkpoint migration exists // Ensure table exists await _snapshotRepository.EnsureCheckpointTableExists(cancellationToken); diff --git a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/ICheckpointRepository.cs b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/ICheckpointRepository.cs index 15d4f6dbc..881543c38 100644 --- a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/ICheckpointRepository.cs +++ b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ChangeDataCapture/Checkpoints/ICheckpointRepository.cs @@ -25,7 +25,8 @@ public CheckpointRepository( public async Task EnsureCheckpointTableExists(CancellationToken ct = default) { - // TODO: Dette burde ligge sammen med OutboxMessage opprettelsen i infrastruktur via EF + // TODO: https://github.com/digdir/dialogporten/issues/... + // This should be located together with the OutboxMessage creation in the infrastructure via EF await using var command = _dataSource.CreateCommand( $""" CREATE TABLE IF NOT EXISTS cdc_checkpoint ( diff --git a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ICdcSink.cs b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ICdcSink.cs index 8478bf5d8..353755325 100644 --- a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ICdcSink.cs +++ b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/ICdcSink.cs @@ -40,8 +40,10 @@ public MassTransitSink(ISendEndpointProvider sender) public async Task Send(IReadOnlyCollection outboxMessages, CancellationToken cancellationToken) { - // TODO: Configure uri - // TODO: Configure transaction + // TODO: https://github.com/digdir/dialogporten/issues/... + // Configure uri + // TODO: https://github.com/digdir/dialogporten/issues/... + // Configure transaction var endpoint = await _sender.GetSendEndpoint(new Uri("exchange:Digdir.Domain.Dialogporten.Service")); await endpoint.SendBatch( outboxMessages, diff --git a/src/Digdir.Domain.Dialogporten.Domain/Outboxes/OutboxMessage.cs b/src/Digdir.Domain.Dialogporten.Domain/Outboxes/OutboxMessage.cs index 18934a8ed..99598ee99 100644 --- a/src/Digdir.Domain.Dialogporten.Domain/Outboxes/OutboxMessage.cs +++ b/src/Digdir.Domain.Dialogporten.Domain/Outboxes/OutboxMessage.cs @@ -23,7 +23,8 @@ public static OutboxMessage Create(TDomainEvent domainEvent) CreatedAt = domainEvent.OccuredAt, EventType = eventType.FullName!, EventPayload = JsonSerializer.Serialize(domainEvent, eventType), - // TODO: Set correlation id + // TODO: https://github.com/digdir/dialogporten/issues/... + // Set correlation id CorrelationId = Guid.NewGuid().ToString() }; } diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs index 92648cc79..83f624f97 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs @@ -191,7 +191,7 @@ private static XacmlJsonCategory CreateResourceCategory(string id, string servic } else if (ns == AttributeIdAppInstance) { - // TODO! + // TODO: https://github.com/digdir/dialogporten/issues/... // For app instances, we the syntax of the value is "{partyID}/{instanceID}". // We do not have Altinn partyID in the request, so we cannot support this. // This means we cannot easily support instance specific authorizations for apps. diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Shipped.md b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Shipped.md new file mode 100644 index 000000000..b8228327a --- /dev/null +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Shipped.md @@ -0,0 +1,7 @@ +## Release 1.0 + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +TODO001 | Documentation | Error | TodoCommentAnalyzer diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Unshipped.md b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AnalyzerReleases.Unshipped.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AssemblyInfo.cs b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AssemblyInfo.cs new file mode 100644 index 000000000..d839acb3d --- /dev/null +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Resources; + +[assembly: NeutralResourcesLanguage("en")] diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Digdir.Library.Analyzers.csproj b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Digdir.Library.Analyzers.csproj new file mode 100644 index 000000000..e45ce58a3 --- /dev/null +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Digdir.Library.Analyzers.csproj @@ -0,0 +1,23 @@ + + + + false + latest + + true + true + + Digdir.Library.Analyzers + Digdir.Library.Analyzers + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Properties/launchSettings.json b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Properties/launchSettings.json new file mode 100644 index 000000000..dbf130ef7 --- /dev/null +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "DebugRoslynAnalyzers": { + "commandName": "DebugRoslynComponent", + "targetProject": "../Digdir.Domain.Dialogporten.Application/Digdir.Domain.Dialogporten.Application.csproj", + } + } +} diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs new file mode 100644 index 000000000..cb34e4c39 --- /dev/null +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs @@ -0,0 +1,49 @@ +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Digdir.Library.Analyzers; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public class TodoCommentAnalyzer : DiagnosticAnalyzer +{ + public const string DiagnosticId = "TODO001"; + private static readonly LocalizableString Title = "TODO comment must have a GitHub issue URL"; + private static readonly LocalizableString MessageFormat = "TODO comment must be followed by a GitHub issue URL (on the same line)"; + private static readonly LocalizableString Description = "TODO comments should be followed by a GitHub issue URL (on the same line)."; + + private const string Category = "Documentation"; + + private static readonly DiagnosticDescriptor Rule = new(DiagnosticId, Title, MessageFormat, Category, + DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + context.RegisterSyntaxTreeAction(AnalyzeSyntaxTree); + } + private static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) + { + var trivia = context + .Tree + .GetRoot(context.CancellationToken) + .DescendantTrivia() + .Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia)); + + foreach (var comment in trivia) + { + var commentText = comment.ToString(); + + if (!commentText.Contains("TODO")) continue; + + if (commentText.Contains("https://github.com/digdir/dialogporten/issues")) continue; + + var diagnostic = Diagnostic.Create(Rule, comment.GetLocation()); + context.ReportDiagnostic(diagnostic); + } + } +} diff --git a/src/Digdir.Library.Utils.AspNet/AspNetUtilitiesExtensions.cs b/src/Digdir.Library.Utils.AspNet/AspNetUtilitiesExtensions.cs index 0728a0bee..c47413c8f 100644 --- a/src/Digdir.Library.Utils.AspNet/AspNetUtilitiesExtensions.cs +++ b/src/Digdir.Library.Utils.AspNet/AspNetUtilitiesExtensions.cs @@ -63,7 +63,7 @@ public static WebApplicationBuilder ConfigureTelemetry(this WebApplicationBuilde tracing.AddAspNetCoreInstrumentation(options => { - options.Filter = (httpContext) => + options.Filter = httpContext => !httpContext.Request.Path.StartsWithSegments("/health"); }); From 955760306b7d8efbcbae9dcc9a0fa129f76cb314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20J=C3=B8rgen=20Skogstad?= Date: Tue, 19 Nov 2024 16:43:30 +0100 Subject: [PATCH 2/2] configure todo issue url in .editorconfig --- .editorconfig | 3 +++ .../TodoCommentAnalyzer.cs | 20 +++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.editorconfig b/.editorconfig index 241b4c6a8..cb796a5e9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,6 +14,9 @@ indent_size = 4 insert_final_newline = true [*.cs] +// TODO comments should have an associated issue URL +dotnet_diagnostic.TODO001.issueRegex = https://github.com/digdir/dialogporten/issues/\d+ + # Attributes should be on a line above the item they are associated with place_attribute_on_same_line = false diff --git a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs index cb34e4c39..e17330d15 100644 --- a/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs +++ b/src/Digdir.Library.Analyzers/Digdir.Library.Analyzers/TodoCommentAnalyzer.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; +using static System.Text.RegularExpressions.Regex; namespace Digdir.Library.Analyzers; @@ -9,16 +10,17 @@ namespace Digdir.Library.Analyzers; public class TodoCommentAnalyzer : DiagnosticAnalyzer { public const string DiagnosticId = "TODO001"; - private static readonly LocalizableString Title = "TODO comment must have a GitHub issue URL"; - private static readonly LocalizableString MessageFormat = "TODO comment must be followed by a GitHub issue URL (on the same line)"; - private static readonly LocalizableString Description = "TODO comments should be followed by a GitHub issue URL (on the same line)."; + private static readonly LocalizableString Title = "TODO comment must have an issue URL"; + private static readonly LocalizableString MessageFormat = "TODO comment must be followed by an issue URL (on the same line)"; + private static readonly LocalizableString Description = "TODO comments should be followed by an issue URL (on the same line)."; private const string Category = "Documentation"; + private const string IssueRegexOptionKey = "dotnet_diagnostic.TODO001.issueRegex"; private static readonly DiagnosticDescriptor Rule = new(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description); - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + public override ImmutableArray SupportedDiagnostics => [Rule]; public override void Initialize(AnalysisContext context) { @@ -28,6 +30,12 @@ public override void Initialize(AnalysisContext context) } private static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) { + var options = context.Options.AnalyzerConfigOptionsProvider.GetOptions(context.Tree); + if (!options.TryGetValue(IssueRegexOptionKey, out var issueRegex) || string.IsNullOrEmpty(issueRegex)) + { + return; + } + var trivia = context .Tree .GetRoot(context.CancellationToken) @@ -40,10 +48,10 @@ private static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) if (!commentText.Contains("TODO")) continue; - if (commentText.Contains("https://github.com/digdir/dialogporten/issues")) continue; + if (IsMatch(commentText, issueRegex)) continue; var diagnostic = Diagnostic.Create(Rule, comment.GetLocation()); context.ReportDiagnostic(diagnostic); } } -} +} \ No newline at end of file