diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3005d52..861dd0e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,12 +50,6 @@ jobs: - name: Build and verify plugin run: ./gradlew --stacktrace --warning-mode=all check buildPlugin -x traceRequirements - - name: OSSIndex audit - run: ./gradlew --stacktrace --warning-mode=all ossIndexAudit --info - env: - OSSINDEX_USERNAME: ${{ secrets.OSSINDEX_USERNAME }} - OSSINDEX_TOKEN: ${{ secrets.OSSINDEX_TOKEN }} - - name: Sonar analysis if: ${{ env.SONAR_TOKEN != null }} run: ./gradlew --stacktrace --warning-mode=all jacocoTestReport sonar -Dsonar.token=$SONAR_TOKEN diff --git a/build.gradle.kts b/build.gradle.kts index 8383bcf..be24caf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,15 +1,12 @@ -import org.gradle.api.Action -import org.gradle.api.Task import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.api.tasks.bundling.Zip import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.testing.jacoco.plugins.JacocoTaskExtension -import org.itsallcode.openfasttrace.intellijplugin.build.OssIndexHttp429Failure import org.jetbrains.intellij.platform.gradle.TestFrameworkType -import org.sonatype.gradle.plugins.scan.ossindex.OssIndexAuditTask // [bld->dsn~plugin-build-uses-intellij-platform-gradle-plugin~1] +// [bld->dsn~dependency-vulnerability-monitoring-uses-dependabot~1] plugins { id("java") id("jacoco") @@ -17,7 +14,6 @@ plugins { id("org.itsallcode.openfasttrace") version "3.1.1" id("org.jetbrains.intellij.platform") version "2.15.0" id("org.sonarqube") version "7.2.3.7755" - id("org.sonatype.gradle.plugins.scan") version "3.1.5" } group = providers.gradleProperty("group").get() @@ -44,40 +40,6 @@ sonar { } } -val ossIndexUsername = providers.gradleProperty("ossIndexUsername") - .orElse(providers.environmentVariable("OSSINDEX_USERNAME")) - .orNull -val ossIndexToken = providers.gradleProperty("ossIndexToken") - .orElse(providers.environmentVariable("OSSINDEX_TOKEN")) - .orNull - -fun Task.continueOnOssIndexHttp429() { - val auditActions = actions.toList() - val warningLogger = project.logger - actions = listOf(object : Action { - override fun execute(task: Task) { - try { - auditActions.forEach { it.execute(task) } - } catch (failure: RuntimeException) { - if (OssIndexHttp429Failure.matches(failure)) { - warningLogger.warn(OssIndexHttp429Failure.WARNING_MESSAGE) - } else { - throw failure - } - } - } - }) -} - -ossIndexAudit { - ossIndexUsername?.let { username = it } - ossIndexToken?.let { password = it } - isUseCache = true - isPrintBanner = false - isColorEnabled = false - isFailOnDetection = true -} - requirementTracing { failBuild = true inputDirectories = files("doc", "src/main/java", "src/test/java") @@ -157,11 +119,6 @@ intellijPlatformTesting { val instrumentedMainClasses = layout.buildDirectory.dir("instrumented/instrumentCode") tasks { - named("ossIndexAudit") { - // [bld->dsn~oss-index-audit-continues-on-http-429~1] - continueOnOssIndexHttp429() - } - withType().configureEach { options.release = 21 options.encoding = "UTF-8" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index 2e4b966..0000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -plugins { - java -} - -repositories { - mavenCentral() -} - -dependencies { - testImplementation(platform("org.junit:junit-bom:5.13.1")) - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.hamcrest:hamcrest:3.0") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") -} - -tasks.test { - useJUnitPlatform() -} diff --git a/buildSrc/src/main/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429Failure.java b/buildSrc/src/main/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429Failure.java deleted file mode 100644 index 1d87ea1..0000000 --- a/buildSrc/src/main/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429Failure.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.itsallcode.openfasttrace.intellijplugin.build; - -import java.util.regex.Pattern; - -/** - * Detects OSS Index audit failures caused by HTTP 429 quota or rate limiting. - */ -public final class OssIndexHttp429Failure { - public static final String WARNING_MESSAGE = "OSS Index returned HTTP 429. The configured OSS Index plan quota may " - + "be exceeded. Check the OSS Index plan and quota. Dependency security audit result is unavailable for " - + "this run; continuing build."; - - private static final Pattern OSS_INDEX = Pattern.compile("(?i)\\boss\\s*index\\b"); - private static final Pattern HTTP_429 = Pattern.compile( - "(?i)(\\bhttp/\\d+(?:\\.\\d+)?\\s+429\\b|\\bstatus\\s*:?\\s*[^\\r\\n]*\\b429\\b|\\b429\\s+too many requests\\b)"); - - private OssIndexHttp429Failure() { - // Utility class. - } - - /** - * Check whether a failure chain describes an OSS Index HTTP 429 response. - * - * @param failure exception thrown by the OSS Index audit task - * @return {@code true} if the chain mentions OSS Index and an HTTP 429 status - */ - public static boolean matches(final Throwable failure) { - boolean mentionsOssIndex = false; - boolean mentionsHttp429 = false; - Throwable current = failure; - while (current != null) { - final String message = current.getMessage(); - mentionsOssIndex |= containsOssIndex(message); - mentionsHttp429 |= containsHttp429(message); - current = current.getCause(); - } - return mentionsOssIndex && mentionsHttp429; - } - - private static boolean containsOssIndex(final String message) { - return message != null && OSS_INDEX.matcher(message).find(); - } - - private static boolean containsHttp429(final String message) { - return message != null && HTTP_429.matcher(message).find(); - } -} diff --git a/buildSrc/src/test/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429FailureTest.java b/buildSrc/src/test/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429FailureTest.java deleted file mode 100644 index 583a150..0000000 --- a/buildSrc/src/test/java/org/itsallcode/openfasttrace/intellijplugin/build/OssIndexHttp429FailureTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.itsallcode.openfasttrace.intellijplugin.build; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; - -import org.junit.jupiter.api.Test; - -class OssIndexHttp429FailureTest { - @Test - void givenWrappedOssIndexHttp429Failure_whenMatching_thenReturnsTrue() { - final RuntimeException failure = new RuntimeException( - "Could not audit the project: Connection to OSS Index failed, check your credentials: " - + "Unexpected response; status:HTTP/1.1 429 Too Many Requests", - new RuntimeException("Unexpected response; status:HTTP/1.1 429 Too Many Requests")); - - assertThat(OssIndexHttp429Failure.matches(failure), is(true)); - } - - @Test - void givenSeparatedOssIndexAndHttp429MessagesInCauseChain_whenMatching_thenReturnsTrue() { - final RuntimeException failure = new RuntimeException( - "Connection to OSS Index failed, check your credentials", - new RuntimeException("Unexpected response; status:HTTP/1.1 429 Too Many Requests")); - - assertThat(OssIndexHttp429Failure.matches(failure), is(true)); - } - - @Test - void givenVulnerabilityFailure_whenMatching_thenReturnsFalse() { - final RuntimeException failure = new RuntimeException( - "Vulnerabilities detected, check log output to review them"); - - assertThat(OssIndexHttp429Failure.matches(failure), is(false)); - } - - @Test - void givenOssIndexAuthenticationFailure_whenMatching_thenReturnsFalse() { - final RuntimeException failure = new RuntimeException( - "Connection to OSS Index failed, check your credentials: HTTP/1.1 401 Unauthorized"); - - assertThat(OssIndexHttp429Failure.matches(failure), is(false)); - } - - @Test - void givenOssIndexConnectionFailure_whenMatching_thenReturnsFalse() { - final RuntimeException failure = new RuntimeException( - "Connection to OSS Index failed, check your internet status: ossindex.sonatype.org"); - - assertThat(OssIndexHttp429Failure.matches(failure), is(false)); - } - - @Test - void givenOssIndexNon429HttpStatusFailure_whenMatching_thenReturnsFalse() { - final RuntimeException failure = new RuntimeException( - "Connection to OSS Index failed, check your credentials: " - + "Unexpected response; status:HTTP/1.1 500 Internal Server Error"); - - assertThat(OssIndexHttp429Failure.matches(failure), is(false)); - } - - @Test - void givenNonOssIndexHttp429Failure_whenMatching_thenReturnsFalse() { - final RuntimeException failure = new RuntimeException("Unexpected response; status:HTTP/1.1 429 Too Many Requests"); - - assertThat(OssIndexHttp429Failure.matches(failure), is(false)); - } - - @Test - void givenWarningMessage_whenReading_thenIncludesQuotaAndUnavailableResultGuidance() { - assertThat( - OssIndexHttp429Failure.WARNING_MESSAGE, - allOf( - containsString("OSS Index returned HTTP 429"), - containsString("plan quota"), - containsString("Dependency security audit result is unavailable"), - containsString("continuing build"))); - } -} diff --git a/doc/changesets/pr-fix-sonarcloud-open-findings.md b/doc/changesets/pr-fix-sonarcloud-open-findings.md new file mode 100644 index 0000000..600865b --- /dev/null +++ b/doc/changesets/pr-fix-sonarcloud-open-findings.md @@ -0,0 +1,177 @@ +# PR Fix SonarCloud Open Findings + +## Goal + +Close the 23 open or confirmed SonarCloud findings currently reported for the +`org.itsallcode.openfasttrace:openfasttrace-intellij-plugin` project without +adding user-visible plugin behavior. + +The pull request should keep the cleanup compact: fix straightforward code +smells directly, add only narrow analyzer suppressions when a finding conflicts +with IntelliJ Platform API requirements or the documented OpenFastTrace runtime +design, and leave unrelated refactoring for later. + +## Scope + +In scope: + +* fix the current SonarCloud findings from the open/confirmed issue view +* preserve existing completion, navigation, trace configuration, and trace + execution behavior +* add predictable Gradle dependency metadata accepted by SonarCloud +* remove hard-coded dependency versions from `buildSrc/build.gradle.kts` +* keep implementation changes covered by existing focused tests, extending tests + only where behavior-preserving refactoring needs protection +* avoid new third-party dependencies + +Out of scope: + +* changing SonarCloud quality profiles, quality gates, issue severities, or + project permissions +* adding new plugin features or changing end-user workflows +* broad package restructuring unrelated to the reported findings +* changing OpenFastTrace, IntelliJ Platform, or OSS Index policy beyond what the + findings require +* version or changelog updates unless implementation work introduces a + user-visible behavior change + +## Design References + +* [System Requirements](../system_requirements.md) +* [Building Block View](../design/building_block_view.md) +* [Runtime View](../design/runtime_view.md) +* [Quality Requirements](../design/quality_requirements.md) + +## Strategy + +Treat this as static-analysis and security-gate cleanup. The product +requirements and runtime design should remain unchanged unless a finding exposes +an actual behavior defect. + +Prefer small refactorings over suppressions. Use a suppression only when the +Sonar rule conflicts with a deliberate project or platform constraint, for +example IntelliJ's `Configurable.apply()` validation contract or the explicit +plugin class loader required for OpenFastTrace `ServiceLoader` discovery. Put +the reason next to the suppression so future cleanup does not need to rediscover +the context. + +## SonarCloud Findings To Close + +Build and dependency metadata: + +* `build.gradle.kts`: add Gradle dependency locking or verification metadata so + dependency versions are predictable (`text:S8569`) +* `buildSrc/build.gradle.kts`: move hard-coded test dependency versions out of + the build script (`kotlin:S6624`) + +Completion and navigation: + +* `OftSpecificationCompletionProvider`: split complex comment-marker detection + and finish the quote-state branching with an explicit default path + (`java:S1067`, `java:S126`) +* `OftTraceNavigationResolver`: make private helper methods static where they do + not access instance state (`java:S2325`) +* `OftDeclarationNavigationElement`: remove the unnecessary + `serialVersionUID` field (`java:S4926`) + +Trace configuration and input resolution: + +* `OftTraceProjectConfigurable`: preserve or log invalid-path exceptions and + resolve the checked `ConfigurationException` findings without weakening IDE + settings validation (`java:S1166`, `java:S1162`) +* `OftTraceInputResolver`: split long lines, reduce nested control flow when + resolving source folders, and preserve or log invalid-path exceptions + (`java:S103`, `java:S134`, `java:S1166`) +* `OftTraceSettingsSnapshot`: precompile the line-splitting pattern + (`java:S4248`) + +Trace execution: + +* `OftTraceService`: make `buildInputHeader` static and resolve the class-loader + finding in a way that keeps the documented OpenFastTrace `ServiceLoader` + behavior intact (`java:S2325`, `java:S3032`) + +Tests: + +* `OftTraceProjectConfigurableTest`: replace boolean literal assertions with + `assertTrue` and `assertFalse` (`java:S2701`) + +## Task List + +- [x] Create and checkout a new Git branch `quality/fix-sonarcloud-open-findings` + +### Requirements And Design + +- [x] Confirm no `doc/system_requirements.md` change is needed because the PR is + behavior-preserving cleanup +- [x] Update `doc/design/quality_requirements.md` so committed Gradle dependency + verification metadata is an ongoing dependency-policy requirement +- [x] Confirm no runtime design change is needed because implementation preserves + trace execution, trace configuration, completion, and navigation semantics + +### Implementation + +- [x] Add Gradle dependency locking or dependency verification metadata and keep + it committed +- [x] Move `buildSrc` dependency versions to project properties or equivalent + centralized Gradle metadata +- [x] Refactor completion-provider comment and quote detection to satisfy + complexity and branching rules without broadening completion activation +- [x] Refactor trace input resolution to reduce nesting, split long lines, and + preserve exception context +- [x] Keep trace configuration validation compatible with IntelliJ settings UI + while closing or narrowly suppressing checked-exception findings +- [x] Apply the small static-method, regex-pattern, serial-field, and assertion + cleanups +- [x] Keep OpenFastTrace coverage tags accurate for changed implementation and + test code + +### Verification + +- [x] Run `./gradlew test` +- [x] Run `./gradlew traceRequirements` +- [x] Run `./gradlew check` +- [x] Run `./gradlew buildPlugin` +- [x] Run `./gradlew verifyPlugin` and record any remaining pre-existing + verifier findings if it is not green +- [ ] Run `./gradlew --no-configuration-cache sonar` when a valid + Sonar token is available; otherwise rely on the SonarCloud PR analysis to + prove the findings are closed +- [ ] Keep OSS Index audit results clean when credentials and service quota are + available + +`./gradlew --warning-mode=all buildSrc:test` passes. + +`./gradlew test` passes. + +`./gradlew traceRequirements` passes. + +`./gradlew traceRequirements` passes after adding the dependency verification +metadata maintenance policy. + +`./gradlew check` passes, including `spotlessCheck`, `traceRequirements`, +tests, and path coverage verification. + +`./gradlew buildPlugin` passes. + +`./gradlew verifyPlugin` still fails because of pre-existing IntelliJ Platform +experimental API usage in `OftHighlightingPass` and internal API usage in +`OftTraceRunContentOutputPresenter`. The verifier reports the plugin as +compatible otherwise. + +`./gradlew sonarWholeProject -Dsonar.skip=true` was attempted but the task is +not available on this branch. + +`./gradlew --no-configuration-cache sonar -Dsonar.skip=true` passes and +confirms the existing Sonar task still prepares test and JaCoCo XML inputs +before the skipped analysis. + +A real Sonar upload was not run because this shell has no `SONAR_TOKEN`. + +An OSS Index audit was not run because this shell has no `OSSINDEX_USERNAME` and +`OSSINDEX_TOKEN`. + +## Version And Changelog Update + +- [x] Do not raise the version or update the changelog unless the implementation + introduces a user-visible behavior change diff --git a/doc/design/architecture_decisions.md b/doc/design/architecture_decisions.md index bf07593..b5ac911 100644 --- a/doc/design/architecture_decisions.md +++ b/doc/design/architecture_decisions.md @@ -51,46 +51,46 @@ Needs: bld Tags: Build, Gradle -### How Does the Build Handle OSS Index Quota Limits? +### How Does the Project Monitor Dependency Vulnerabilities? -The project uses OSS Index dependency security scanning as a build breaker so vulnerable dependencies block integration. In April 2026 Sonatype introduced quotas on the OSS Index free plan. When that quota is exceeded, OSS Index returns HTTP 429 instead of vulnerability data. +The project needs vulnerability monitoring for Gradle dependencies without making local and CI builds depend on an external vulnerability-audit service during every run. This decision is architecture-relevant because it impacts: * reliability of local and CI builds -* trust in the dependency security gate -* clarity when a build cannot obtain an OSS Index result +* trust in dependency vulnerability monitoring +* time-to-feedback for vulnerable dependency findings We considered the following alternatives: -1. Keep every OSS Index task failure fatal. +1. Keep OSS Index in the Gradle build. - This preserves a strict gate, but an exceeded external quota would block development without revealing anything about the project's dependency security state. + This preserves immediate feedback, but OSS Index quota, authentication, and service availability issues can block development without revealing anything about the project's dependency security state. -1. Disable OSS Index or make all audit failures non-fatal. +1. Keep OSS Index in the build but make audit failures non-fatal. - This would keep builds moving, but it would also remove the build-breaking protection for known vulnerable dependencies and ordinary audit failures. + This avoids blocked builds, but it keeps a fragile build integration without a strict enforcement benefit. -1. Treat only HTTP 429 as a documented warning exception. +1. Remove OSS Index from the Gradle build and rely on GitHub Dependabot alerts. - This keeps vulnerability detection and ordinary audit failures fatal while letting builds continue when OSS Index does not provide results because the external quota was exceeded. + This removes the immediate build-time vulnerability gate, but it keeps vulnerability monitoring in GitHub without making every build depend on OSS Index availability. -#### OSS Index Audit Continues on HTTP 429 -`dsn~oss-index-audit-continues-on-http-429~1` +#### Dependency Vulnerability Monitoring Uses Dependabot +`dsn~dependency-vulnerability-monitoring-uses-dependabot~1` -The Gradle build keeps OSS Index dependency auditing as a build breaker for detected vulnerabilities and non-429 audit failures. When the OSS Index audit fails because the OSS Index service returns HTTP 429, the build logs a warning that the quota or plan may need checking and continues. +The Gradle build does not run OSS Index dependency auditing. Dependency vulnerability monitoring happens through GitHub Dependabot alerts. Rationale: -An HTTP 429 response indicates rate limiting or quota exhaustion, not that the scanned dependency set contains known vulnerabilities. Continuing in that case prevents the external plan quota from blocking local and CI development while still making the missing security result visible in the build log. +Dependabot lacks the immediate local build feedback that OSS Index provided, but it gives the project a vulnerability check without blocking local and CI builds on OSS Index quotas, credentials, or service availability. Comment: -The HTTP 429 exception does not apply to vulnerability findings, authentication failures, ordinary connection failures, malformed responses, or other OSS Index service errors. +Builds remain responsible for ordinary compilation, tests, tracing, plugin verification, and static analysis. Dependency verification metadata still protects artifact integrity, but it is not a vulnerability scanner. Needs: bld -Tags: Build, Security, OSS Index +Tags: Build, Security, Dependabot ## Test Framework Decisions diff --git a/doc/design/quality_requirements.md b/doc/design/quality_requirements.md index 2123ce0..498a6f6 100644 --- a/doc/design/quality_requirements.md +++ b/doc/design/quality_requirements.md @@ -55,11 +55,15 @@ The plugin uses the minimum set of dependencies required for: Additional libraries are not allowed by default. Any new third-party dependency requires an explicit design decision and approval before it is added to the build. +The Gradle dependency verification metadata in `gradle/verification-metadata.xml` is committed to source control. Maintainers update and review this metadata whenever dependency declarations, Gradle plugin versions, the IntelliJ Platform version, or other build inputs change the resolved dependency artifacts. The standard update command is `./gradlew --write-verification-metadata sha256 help`. + +Generated local IntelliJ Platform Ivy metadata for bundled plugin and module artifacts is trusted without checksum verification because the IntelliJ Platform Gradle Plugin can generate environment-specific Ivy descriptors for the local IntelliJ Platform artifact repository. This exception applies only to `ivy-*.xml` descriptors in the `bundledPlugin` and `bundledModule` groups. Resolved JAR artifacts remain checksum verified. + ## Static Analysis And Security Gates Static code analysis runs in SonarQube Cloud and acts as a build breaker. A failing quality gate blocks integration until the reported issues are resolved or an approved exception exists. -Dependency security scanning runs with OSS Index and acts as a build breaker for detected vulnerabilities and ordinary audit failures. If OSS Index returns HTTP 429, the build logs a quota warning and continues because the audit result is unavailable for reasons outside the dependency set. The build stays free of known vulnerable dependencies. +Dependency vulnerability monitoring runs through GitHub Dependabot instead of the Gradle build. Dependabot alerts provide the repository's vulnerability check for known vulnerable dependencies, while local and CI builds no longer run OSS Index as an immediate build-breaking gate. OpenFastTrace tracing runs as a build breaker for the specification artifacts in scope. The trace stays clean for the requirement and design artifact types used by the project. diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml new file mode 100644 index 0000000..cc1475c --- /dev/null +++ b/gradle/verification-metadata.xml @@ -0,0 +1,3206 @@ + + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/navigation/OftSpecificationCompletionProvider.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/navigation/OftSpecificationCompletionProvider.java index 23bf17e..43f2fec 100644 --- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/navigation/OftSpecificationCompletionProvider.java +++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/navigation/OftSpecificationCompletionProvider.java @@ -20,6 +20,7 @@ import org.itsallcode.openfasttrace.intellijplugin.indexing.OftIndexedSpecification; import java.util.Optional; +import java.util.Set; // [impl->dsn~specification-item-completion~1] // [impl->dsn~complete-specification-item-id-in-covers-section~1] @@ -29,6 +30,9 @@ // [impl->dsn~complete-specification-item-id-in-incomplete-coverage-tag-target~1] // [impl->dsn~suppress-coverage-tag-target-completion-outside-target-context~1] public final class OftSpecificationCompletionProvider extends CompletionContributor implements DumbAware { + private static final Set FALLBACK_TEXT_COMMENT_MARKERS = + Set.of("//", "#", "--", ";", "'", "/*", "