summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2023-09-27 16:45:35 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2023-09-27 16:45:35 +0200
commitcd633c8cadc784bc28b5c080c7bfd7756f8fa8ff (patch)
tree6a7e5e04285c69d67237657165a5a74136ef8124
parent22c0ed22e2db624475a62f5c3bba6559f7a06e5d (diff)
Allow properties in rule set
-rw-r--r--maven-plugins/allowed-maven-dependencies.txt109
-rw-r--r--maven-plugins/pom.xml2
-rw-r--r--vespa-dependencies-enforcer/allowed-maven-dependencies.txt349
-rw-r--r--vespa-dependencies-enforcer/pom.xml10
-rw-r--r--vespa-enforcer-extensions/pom.xml18
-rw-r--r--vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/AllowedDependencies.java305
-rw-r--r--vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjects.java319
-rw-r--r--vespa-enforcer-extensions/src/test/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjectsTest.java108
-rw-r--r--vespa-enforcer-extensions/src/test/resources/allowed-dependencies.txt11
9 files changed, 541 insertions, 690 deletions
diff --git a/maven-plugins/allowed-maven-dependencies.txt b/maven-plugins/allowed-maven-dependencies.txt
index 6853632ea40..06f2f34964b 100644
--- a/maven-plugins/allowed-maven-dependencies.txt
+++ b/maven-plugins/allowed-maven-dependencies.txt
@@ -1,41 +1,31 @@
# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#[non-test]
-# Contains dependencies that are not used exclusively in 'test' scope
-aopalliance:aopalliance:1.0
-com.fasterxml.jackson.core:jackson-annotations:2.15.2
-com.fasterxml.jackson.core:jackson-core:2.15.2
-com.fasterxml.jackson.core:jackson-databind:2.15.2
-com.github.luben:zstd-jni:1.5.5-5
-com.google.errorprone:error_prone_annotations:2.22.0
+aopalliance:aopalliance:${aopalliance.vespa.version}
+com.fasterxml.jackson.core:jackson-annotations:${jackson2.vespa.version}
+com.fasterxml.jackson.core:jackson-core:${jackson2.vespa.version}
+com.fasterxml.jackson.core:jackson-databind:${jackson-databind.vespa.version}
+com.github.luben:zstd-jni:${luben.zstd.vespa.version}
+com.google.errorprone:error_prone_annotations:${error-prone-annotations.vespa.version}
com.google.guava:failureaccess:1.0.1
-com.google.guava:guava:32.1.2-jre
-com.google.inject:guice:6.0.0
+com.google.guava:guava:${guava.vespa.version}
+com.google.inject:guice:${guice.vespa.version}
com.google.j2objc:j2objc-annotations:2.8
-commons-codec:commons-codec:1.16.0
-commons-io:commons-io:2.13.0
-jakarta.inject:jakarta.inject-api:2.0.1
-javax.annotation:javax.annotation-api:1.2
-javax.inject:javax.inject:1
+commons-codec:commons-codec:${commons-codec.vespa.version}
+commons-io:commons-io:${commons-io.vespa.version}
+jakarta.inject:jakarta.inject-api:${jakarta.inject.vespa.version}
+javax.annotation:javax.annotation-api:${commons-logging.vespa.version}
+javax.inject:javax.inject:${javax.inject.vespa.version}
+junit:junit:${junit4.vespa.version}
+net.bytebuddy:byte-buddy-agent:${byte-buddy.vespa.version}
+net.bytebuddy:byte-buddy:${byte-buddy.vespa.version}
org.apache-extras.beanshell:bsh:2.0b6
org.apache.commons:commons-collections4:4.4
-org.apache.commons:commons-compress:1.24.0
-org.apache.commons:commons-lang3:3.13.0
-org.apache.maven:maven-archiver:3.6.1
-org.apache.maven:maven-artifact:3.9.4
-org.apache.maven:maven-builder-support:3.9.4
-org.apache.maven:maven-core:3.9.4
-org.apache.maven:maven-model:3.9.4
-org.apache.maven:maven-model-builder:3.9.4
-org.apache.maven:maven-plugin-api:3.9.4
-org.apache.maven:maven-repository-metadata:3.9.4
-org.apache.maven:maven-resolver-provider:3.9.4
-org.apache.maven:maven-settings:3.9.4
-org.apache.maven:maven-settings-builder:3.9.4
-org.apache.maven.enforcer:enforcer-api:3.4.1
-org.apache.maven.enforcer:enforcer-rules:3.4.1
-org.apache.maven.plugin-tools:maven-plugin-annotations:3.9.0
-org.apache.maven.plugins:maven-shade-plugin:3.5.1
+org.apache.commons:commons-compress:${commons-compress.vespa.version}
+org.apache.commons:commons-lang3:${commons-lang3.vespa.version}
+org.apache.maven.enforcer:enforcer-api:${maven-enforcer-plugin.vespa.version}
+org.apache.maven.enforcer:enforcer-rules:${maven-enforcer-plugin.vespa.version}
+org.apache.maven.plugin-tools:maven-plugin-annotations:${maven-plugin-tools.vespa.version}
+org.apache.maven.plugins:maven-shade-plugin:${maven-shade-plugin.vespa.version}
org.apache.maven.resolver:maven-resolver-api:1.9.14
org.apache.maven.resolver:maven-resolver-impl:1.9.14
org.apache.maven.resolver:maven-resolver-named-locks:1.9.14
@@ -43,42 +33,47 @@ org.apache.maven.resolver:maven-resolver-spi:1.9.14
org.apache.maven.resolver:maven-resolver-util:1.9.14
org.apache.maven.shared:maven-dependency-tree:3.2.1
org.apache.maven.shared:maven-shared-utils:3.3.4
+org.apache.maven:maven-archiver:${maven-archiver.vespa.version}
+org.apache.maven:maven-artifact:${maven-core.vespa.version}
+org.apache.maven:maven-builder-support:${maven-core.vespa.version}
+org.apache.maven:maven-core:${maven-core.vespa.version}
+org.apache.maven:maven-model-builder:${maven-core.vespa.version}
+org.apache.maven:maven-model:${maven-core.vespa.version}
+org.apache.maven:maven-plugin-api:${maven-plugin-api.vespa.version}
+org.apache.maven:maven-repository-metadata:${maven-core.vespa.version}
+org.apache.maven:maven-resolver-provider:${maven-core.vespa.version}
+org.apache.maven:maven-settings-builder:${maven-core.vespa.version}
+org.apache.maven:maven-settings:${maven-core.vespa.version}
+org.apiguardian:apiguardian-api:${apiguardian.vespa.version}
org.codehaus.plexus:plexus-archiver:4.8.0
org.codehaus.plexus:plexus-cipher:2.0
org.codehaus.plexus:plexus-classworlds:2.7.0
org.codehaus.plexus:plexus-component-annotations:2.1.0
org.codehaus.plexus:plexus-interpolation:1.26
-org.codehaus.plexus:plexus-io:3.4.1
+org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version}
org.codehaus.plexus:plexus-sec-dispatcher:2.0
-org.codehaus.plexus:plexus-utils:3.5.1
+org.codehaus.plexus:plexus-utils:${maven-shade-plugin.vespa.version}
org.eclipse.aether:aether-api:1.0.0.v20140518
org.eclipse.aether:aether-util:1.0.0.v20140518
org.eclipse.sisu:org.eclipse.sisu.inject:0.3.5
org.eclipse.sisu:org.eclipse.sisu.plexus:0.3.5
+org.hamcrest:hamcrest-core:${hamcrest.vespa.version}
+org.hamcrest:hamcrest:${hamcrest.vespa.version}
org.iq80.snappy:snappy:0.4
org.jdom:jdom2:2.0.6.1
-org.ow2.asm:asm:9.5
-org.ow2.asm:asm-commons:9.5
-org.ow2.asm:asm-tree:9.5
-org.slf4j:slf4j-api:1.7.36
+org.junit.jupiter:junit-jupiter-api:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter-engine:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter-params:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter:${junit.vespa.version}
+org.junit.platform:junit-platform-commons:${junit.platform.vespa.version}
+org.junit.platform:junit-platform-engine:${junit.platform.vespa.version}
+org.mockito:mockito-core:${mockito.vespa.version}
+org.objenesis:objenesis:3.3
+org.opentest4j:opentest4j:${opentest4j.vespa.version}
+org.ow2.asm:asm-commons:${asm.vespa.version}
+org.ow2.asm:asm-tree:${asm.vespa.version}
+org.ow2.asm:asm:${asm.vespa.version}
+org.slf4j:slf4j-api:${slf4j.vespa.version}
org.tukaani:xz:1.9
-org.twdata.maven:mojo-executor:2.4.0
+org.twdata.maven:mojo-executor:${mojo-executor.vespa.version}
org.vafer:jdependency:2.9.0
-
-#[test-only]
-# Contains dependencies that are used exclusively in 'test' scope
-junit:junit:4.13.2
-net.bytebuddy:byte-buddy:1.14.8
-net.bytebuddy:byte-buddy-agent:1.14.8
-org.apiguardian:apiguardian-api:1.1.2
-org.hamcrest:hamcrest:2.2
-org.hamcrest:hamcrest-core:2.2
-org.junit.jupiter:junit-jupiter:5.10.0
-org.junit.jupiter:junit-jupiter-api:5.10.0
-org.junit.jupiter:junit-jupiter-engine:5.10.0
-org.junit.jupiter:junit-jupiter-params:5.10.0
-org.junit.platform:junit-platform-commons:1.10.0
-org.junit.platform:junit-platform-engine:1.10.0
-org.mockito:mockito-core:5.5.0
-org.objenesis:objenesis:3.3
-org.opentest4j:opentest4j:1.3.0
diff --git a/maven-plugins/pom.xml b/maven-plugins/pom.xml
index f12731ba9da..bc8ed090c3f 100644
--- a/maven-plugins/pom.xml
+++ b/maven-plugins/pom.xml
@@ -47,7 +47,7 @@
</goals>
<configuration>
<rules>
- <enforceDependencies implementation="com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects">
+ <enforceDependencies implementation="com.yahoo.vespa.maven.plugin.enforcer.AllowedDependencies">
<rootProjectId>com.yahoo.vespa:maven-plugins</rootProjectId>
<specFile>allowed-maven-dependencies.txt</specFile>
<ignored>
diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
index b70b3ff2bb1..3ae0923aef0 100644
--- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
+++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
@@ -1,211 +1,206 @@
# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#[non-test]
-# Contains dependencies that are not used exclusively in 'test' scope
-ai.djl:api:0.23.0
ai.djl.huggingface:tokenizers:0.23.0
-aopalliance:aopalliance:1.0
+ai.djl:api:0.23.0
+aopalliance:aopalliance:${aopalliance.vespa.version}
backport-util-concurrent:backport-util-concurrent:3.1
ch.qos.logback:logback-classic:1.2.10
ch.qos.logback:logback-core:1.2.10
classworlds:classworlds:1.1-alpha-2
-com.amazonaws:aws-java-sdk-core:1.12.540
-com.amazonaws:aws-java-sdk-kms:1.12.540
-com.amazonaws:aws-java-sdk-s3:1.12.540
-com.amazonaws:aws-java-sdk-ssm:1.12.540
-com.amazonaws:aws-java-sdk-sts:1.12.540
-com.amazonaws:jmespath-java:1.12.540
-com.auth0:java-jwt:4.4.0
-com.fasterxml.jackson.core:jackson-annotations:2.15.2
-com.fasterxml.jackson.core:jackson-core:2.15.2
-com.fasterxml.jackson.core:jackson-databind:2.15.2
-com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.15.2
-com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.2
-com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2
-com.github.luben:zstd-jni:1.5.5-5
+com.amazonaws:aws-java-sdk-core:${aws-sdk.vespa.version}
+com.amazonaws:aws-java-sdk-kms:${aws-sdk.vespa.version}
+com.amazonaws:aws-java-sdk-s3:${aws-sdk.vespa.version}
+com.amazonaws:aws-java-sdk-ssm:${aws-sdk.vespa.version}
+com.amazonaws:aws-java-sdk-sts:${aws-sdk.vespa.version}
+com.amazonaws:jmespath-java:${aws-sdk.vespa.version}
+com.auth0:java-jwt:${java-jwt.vespa.version}
+com.fasterxml.jackson.core:jackson-annotations:${jackson2.vespa.version}
+com.fasterxml.jackson.core:jackson-core:${jackson2.vespa.version}
+com.fasterxml.jackson.core:jackson-databind:${jackson-databind.vespa.version}
+com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:${jackson2.vespa.version}
+com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2.vespa.version}
+com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jackson2.vespa.version}
+com.github.luben:zstd-jni:${luben.zstd.vespa.version}
com.github.spotbugs:spotbugs-annotations:3.1.9
-com.google.code.findbugs:jsr305:3.0.2
-com.google.errorprone:error_prone_annotations:2.22.0
+com.google.code.findbugs:jsr305:${findbugs.vespa.version}
+com.google.errorprone:error_prone_annotations:${error-prone-annotations.vespa.version}
com.google.guava:failureaccess:1.0.1
-com.google.guava:guava:32.1.2-jre
-com.google.inject:guice:6.0.0
+com.google.guava:guava:${guava.vespa.version}
+com.google.inject:guice:${guice.vespa.version}
com.google.j2objc:j2objc-annotations:2.8
-com.google.protobuf:protobuf-java:3.24.3
-com.ibm.icu:icu4j:73.2
-com.microsoft.onnxruntime:onnxruntime:1.15.1
-com.sun.activation:javax.activation:1.2.0
+com.google.jimfs:jimfs:${jimfs.vespa.version}
+com.google.protobuf:protobuf-java:${protobuf.vespa.version}
+com.ibm.icu:icu4j:${icu4j.vespa.version}
+com.microsoft.onnxruntime:onnxruntime:${onnxruntime.vespa.version}
+com.sun.activation:javax.activation:${properties-maven-plugin.vespa.version}
com.sun.istack:istack-commons-runtime:4.1.2
-com.sun.xml.bind:jaxb-core:2.3.0.1
-com.sun.xml.bind:jaxb-impl:2.3.0
+com.sun.xml.bind:jaxb-core:${jaxb-core.vespa.version}
+com.sun.xml.bind:jaxb-impl:${jaxb-impl.vespa.version}
com.thaiopensource:jing:20091111
-com.yahoo.athenz:athenz-auth-core:1.11.42
-com.yahoo.athenz:athenz-client-common:1.11.42
-com.yahoo.athenz:athenz-zms-core:1.11.42
-com.yahoo.athenz:athenz-zpe-java-client:1.11.42
-com.yahoo.athenz:athenz-zts-core:1.11.42
+com.yahoo.athenz:athenz-auth-core:${athenz.vespa.version}
+com.yahoo.athenz:athenz-client-common:${athenz.vespa.version}
+com.yahoo.athenz:athenz-zms-core:${athenz.vespa.version}
+com.yahoo.athenz:athenz-zpe-java-client:${athenz.vespa.version}
+com.yahoo.athenz:athenz-zts-core:${athenz.vespa.version}
com.yahoo.rdl:rdl-java:1.5.4
commons-cli:commons-cli:1.5.0
-commons-codec:commons-codec:1.16.0
+commons-codec:commons-codec:${commons-codec.vespa.version}
commons-fileupload:commons-fileupload:1.5
-commons-io:commons-io:2.13.0
-commons-logging:commons-logging:1.2
-io.airlift:airline:0.9
-io.dropwizard.metrics:metrics-core:4.2.20
-io.jsonwebtoken:jjwt-api:0.11.5
-io.jsonwebtoken:jjwt-impl:0.11.5
-io.jsonwebtoken:jjwt-jackson:0.11.5
-io.netty:netty-buffer:4.1.98.Final
-io.netty:netty-codec:4.1.98.Final
-io.netty:netty-common:4.1.98.Final
-io.netty:netty-handler:4.1.98.Final
-io.netty:netty-resolver:4.1.98.Final
-io.netty:netty-tcnative:2.0.61.Final
-io.netty:netty-tcnative-classes:2.0.61.Final
-io.netty:netty-transport:4.1.98.Final
-io.netty:netty-transport-classes-epoll:4.1.98.Final
-io.netty:netty-transport-native-epoll:4.1.98.Final
-io.netty:netty-transport-native-unix-common:4.1.98.Final
-io.prometheus:simpleclient:0.16.0
-io.prometheus:simpleclient_common:0.16.0
-io.prometheus:simpleclient_tracer_common:0.16.0
-io.prometheus:simpleclient_tracer_otel:0.16.0
-io.prometheus:simpleclient_tracer_otel_agent:0.16.0
-jakarta.inject:jakarta.inject-api:2.0.1
-javax.activation:javax.activation-api:1.2.0
-javax.annotation:javax.annotation-api:1.2
-javax.inject:javax.inject:1
-javax.servlet:javax.servlet-api:3.1.0
-javax.ws.rs:javax.ws.rs-api:2.1.1
-javax.xml.bind:jaxb-api:2.3.1
-joda-time:joda-time:2.12.5
-junit:junit:4.13.2
-net.java.dev.jna:jna:5.13.0
-net.openhft:zero-allocation-hashing:0.16
-org.antlr:antlr-runtime:3.5.3
-org.antlr:antlr4-runtime:4.13.1
-org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle:1.3.6
-org.apache.commons:commons-compress:1.24.0
-org.apache.commons:commons-csv:1.10.0
-org.apache.commons:commons-exec:1.3
-org.apache.commons:commons-lang3:3.13.0
-org.apache.commons:commons-math3:3.6.1
-org.apache.curator:curator-client:5.5.0
-org.apache.curator:curator-framework:5.5.0
-org.apache.curator:curator-recipes:5.5.0
-org.apache.felix:org.apache.felix.framework:7.0.5
-org.apache.felix:org.apache.felix.log:1.3.0
-org.apache.httpcomponents:httpclient:4.5.14
-org.apache.httpcomponents:httpcore:4.4.16
-org.apache.httpcomponents:httpmime:4.5.14
-org.apache.httpcomponents.client5:httpclient5:5.2.1
-org.apache.httpcomponents.core5:httpcore5:5.2.3
-org.apache.httpcomponents.core5:httpcore5-h2:5.2.3
-org.apache.lucene:lucene-analysis-common:9.7.0
-org.apache.lucene:lucene-core:9.7.0
-org.apache.maven:maven-archiver:3.6.1
-org.apache.maven:maven-artifact:3.9.4
+commons-io:commons-io:${commons-io.vespa.version}
+commons-logging:commons-logging:${commons-logging.vespa.version}
+io.airlift:airline:${airline.vespa.version}
+io.dropwizard.metrics:metrics-core:${dropwizard.metrics.vespa.version}
+io.jsonwebtoken:jjwt-api:${java-jjwt.vespa.version}
+io.jsonwebtoken:jjwt-impl:${java-jjwt.vespa.version}
+io.jsonwebtoken:jjwt-jackson:${java-jjwt.vespa.version}
+io.netty:netty-buffer:${netty.vespa.version}
+io.netty:netty-codec:${netty.vespa.version}
+io.netty:netty-common:${netty.vespa.version}
+io.netty:netty-handler:${netty.vespa.version}
+io.netty:netty-resolver:${netty.vespa.version}
+io.netty:netty-tcnative-classes:${netty-tcnative.vespa.version}
+io.netty:netty-tcnative:${netty-tcnative.vespa.version}
+io.netty:netty-transport-classes-epoll:${netty.vespa.version}
+io.netty:netty-transport-native-epoll:${netty.vespa.version}
+io.netty:netty-transport-native-unix-common:${netty.vespa.version}
+io.netty:netty-transport:${netty.vespa.version}
+io.prometheus:simpleclient:${prometheus.client.vespa.version}
+io.prometheus:simpleclient_common:${prometheus.client.vespa.version}
+io.prometheus:simpleclient_tracer_common:${prometheus.client.vespa.version}
+io.prometheus:simpleclient_tracer_otel:${prometheus.client.vespa.version}
+io.prometheus:simpleclient_tracer_otel_agent:${prometheus.client.vespa.version}
+jakarta.inject:jakarta.inject-api:${jakarta.inject.vespa.version}
+javax.activation:javax.activation-api:${properties-maven-plugin.vespa.version}
+javax.annotation:javax.annotation-api:${commons-logging.vespa.version}
+javax.inject:javax.inject:${javax.inject.vespa.version}
+javax.servlet:javax.servlet-api:${javax.servlet-api.vespa.version}
+javax.ws.rs:javax.ws.rs-api:${javax.ws.rs-api.vespa.version}
+javax.xml.bind:jaxb-api:${jaxb-api.vespa.version}
+joda-time:joda-time:${joda-time.vespa.version}
+junit:junit:${junit4.vespa.version}
+net.bytebuddy:byte-buddy-agent:${byte-buddy.vespa.version}
+net.bytebuddy:byte-buddy:${byte-buddy.vespa.version}
+net.java.dev.jna:jna:${jna.vespa.version}
+net.openhft:zero-allocation-hashing:${zero-allocation-hashing.vespa.version}
+org.antlr:antlr-runtime:${antlr.vespa.version}
+org.antlr:antlr4-runtime:${antlr4.vespa.version}
+org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle:${spifly.vespa.version}
+org.apache.commons:commons-compress:${commons-compress.vespa.version}
+org.apache.commons:commons-csv:${commons-csv.vespa.version}
+org.apache.commons:commons-exec:${commons-exec.vespa.version}
+org.apache.commons:commons-lang3:${commons-lang3.vespa.version}
+org.apache.commons:commons-math3:${commons.math3.vespa.version}
+org.apache.curator:curator-client:${curator.vespa.version}
+org.apache.curator:curator-framework:${curator.vespa.version}
+org.apache.curator:curator-recipes:${curator.vespa.version}
+org.apache.curator:curator-test:${curator.vespa.version}
+org.apache.felix:org.apache.felix.framework:${felix.vespa.version}
+org.apache.felix:org.apache.felix.log:${felix.log.vespa.version}
+org.apache.httpcomponents.client5:httpclient5:${apache.httpclient5.vespa.version}
+org.apache.httpcomponents.core5:httpcore5-h2:${apache.httpcore5.vespa.version}
+org.apache.httpcomponents.core5:httpcore5:${apache.httpcore5.vespa.version}
+org.apache.httpcomponents:httpclient:${apache.httpclient.vespa.version}
+org.apache.httpcomponents:httpcore:${apache.httpcore.vespa.version}
+org.apache.httpcomponents:httpmime:${apache.httpclient.vespa.version}
+org.apache.lucene:lucene-analysis-common:${lucene.vespa.version}
+org.apache.lucene:lucene-core:${lucene.vespa.version}
+org.apache.maven.plugin-tools:maven-plugin-annotations:${maven-plugin-tools.vespa.version}
+org.apache.maven.plugins:maven-jar-plugin:${maven-jar-plugin.vespa.version}
+org.apache.maven.shared:file-management:3.1.0
+org.apache.maven.wagon:wagon-provider-api:${maven-wagon.vespa.version}
+org.apache.maven:maven-archiver:${maven-archiver.vespa.version}
org.apache.maven:maven-artifact-manager:2.2.1
-org.apache.maven:maven-model:3.9.4
-org.apache.maven:maven-plugin-api:3.9.4
+org.apache.maven:maven-artifact:${maven-core.vespa.version}
+org.apache.maven:maven-model:${maven-core.vespa.version}
+org.apache.maven:maven-plugin-api:${maven-core.vespa.version}
org.apache.maven:maven-plugin-registry:2.2.1
org.apache.maven:maven-profile:2.2.1
org.apache.maven:maven-project:2.2.1
-org.apache.maven:maven-repository-metadata:3.9.4
-org.apache.maven:maven-settings:3.9.4
-org.apache.maven.plugin-tools:maven-plugin-annotations:3.9.0
-org.apache.maven.plugins:maven-jar-plugin:3.3.0
-org.apache.maven.shared:file-management:3.1.0
-org.apache.maven.wagon:wagon-provider-api:3.5.3
-org.apache.opennlp:opennlp-tools:2.3.0
+org.apache.maven:maven-repository-metadata:${maven-core.vespa.version}
+org.apache.maven:maven-settings:${maven-core.vespa.version}
+org.apache.opennlp:opennlp-tools:${opennlp.vespa.version}
org.apache.velocity:velocity-engine-core:2.3
org.apache.yetus:audience-annotations:0.12.0
-org.apache.zookeeper:zookeeper:3.8.0
-org.apache.zookeeper:zookeeper:3.8.1
-org.apache.zookeeper:zookeeper-jute:3.8.0
+org.apache.zookeeper:zookeeper-jute:${zookeeper.client.vespa.version}
org.apache.zookeeper:zookeeper-jute:3.8.1
-org.apiguardian:apiguardian-api:1.1.2
-org.bouncycastle:bcpkix-jdk18on:1.76
-org.bouncycastle:bcprov-jdk18on:1.76
-org.bouncycastle:bcutil-jdk18on:1.76
+org.apache.zookeeper:zookeeper:${zookeeper.client.vespa.version}
+org.apache.zookeeper:zookeeper:3.8.1
+org.apiguardian:apiguardian-api:${apiguardian.vespa.version}
+org.assertj:assertj-core:${assertj.vespa.version}
+org.bouncycastle:bcpkix-jdk18on:${bouncycastle.vespa.version}
+org.bouncycastle:bcprov-jdk18on:${bouncycastle.vespa.version}
+org.bouncycastle:bcutil-jdk18on:${bouncycastle.vespa.version}
org.codehaus.plexus:plexus-archiver:4.8.0
org.codehaus.plexus:plexus-classworlds:2.7.0
org.codehaus.plexus:plexus-component-annotations:1.5.5
org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1
org.codehaus.plexus:plexus-interpolation:1.26
-org.codehaus.plexus:plexus-io:3.4.1
-org.codehaus.plexus:plexus-utils:3.5.1
-org.eclipse.angus:angus-activation:2.0.1
-org.eclipse.collections:eclipse-collections:11.1.0
-org.eclipse.collections:eclipse-collections-api:11.1.0
-org.eclipse.jetty:jetty-alpn-client:11.0.16
-org.eclipse.jetty:jetty-alpn-java-client:11.0.16
-org.eclipse.jetty:jetty-alpn-java-server:11.0.16
-org.eclipse.jetty:jetty-alpn-server:11.0.16
-org.eclipse.jetty:jetty-client:11.0.16
-org.eclipse.jetty:jetty-http:11.0.16
-org.eclipse.jetty:jetty-io:11.0.16
-org.eclipse.jetty:jetty-jmx:11.0.16
-org.eclipse.jetty:jetty-security:11.0.16
-org.eclipse.jetty:jetty-server:11.0.16
-org.eclipse.jetty:jetty-servlet:11.0.16
-org.eclipse.jetty:jetty-util:11.0.16
-org.eclipse.jetty.http2:http2-client:11.0.16
-org.eclipse.jetty.http2:http2-common:11.0.16
-org.eclipse.jetty.http2:http2-hpack:11.0.16
-org.eclipse.jetty.http2:http2-http-client-transport:11.0.16
-org.eclipse.jetty.http2:http2-server:11.0.16
-org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2
+org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version}
+org.codehaus.plexus:plexus-utils:${maven-shade-plugin.vespa.version}
+org.eclipse.angus:angus-activation:${jakarta.inject.vespa.version}
+org.eclipse.collections:eclipse-collections-api:${eclipse-collections.vespa.version}
+org.eclipse.collections:eclipse-collections:${eclipse-collections.vespa.version}
+org.eclipse.jetty.http2:http2-client:${jetty.vespa.version}
+org.eclipse.jetty.http2:http2-common:${jetty.vespa.version}
+org.eclipse.jetty.http2:http2-hpack:${jetty.vespa.version}
+org.eclipse.jetty.http2:http2-http-client-transport:${jetty.vespa.version}
+org.eclipse.jetty.http2:http2-server:${jetty.vespa.version}
+org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:${jetty-servlet-api.vespa.version}
+org.eclipse.jetty:jetty-alpn-client:${jetty.vespa.version}
+org.eclipse.jetty:jetty-alpn-java-client:${jetty.vespa.version}
+org.eclipse.jetty:jetty-alpn-java-server:${jetty.vespa.version}
+org.eclipse.jetty:jetty-alpn-server:${jetty.vespa.version}
+org.eclipse.jetty:jetty-client:${jetty.vespa.version}
+org.eclipse.jetty:jetty-http:${jetty.vespa.version}
+org.eclipse.jetty:jetty-io:${jetty.vespa.version}
+org.eclipse.jetty:jetty-jmx:${jetty.vespa.version}
+org.eclipse.jetty:jetty-security:${jetty.vespa.version}
+org.eclipse.jetty:jetty-server:${jetty.vespa.version}
+org.eclipse.jetty:jetty-servlet:${jetty.vespa.version}
+org.eclipse.jetty:jetty-util:${jetty.vespa.version}
org.eclipse.sisu:org.eclipse.sisu.inject:0.3.5
org.eclipse.sisu:org.eclipse.sisu.plexus:0.3.5
org.fusesource.jansi:jansi:1.18
-org.glassfish.jaxb:jaxb-core:4.0.3
-org.glassfish.jaxb:jaxb-runtime:4.0.3
-org.glassfish.jaxb:txw2:4.0.3
-org.hamcrest:hamcrest:2.2
-org.hamcrest:hamcrest-core:2.2
-org.hdrhistogram:HdrHistogram:2.1.12
+org.glassfish.jaxb:jaxb-core:${jaxb.runtime.vespa.version}
+org.glassfish.jaxb:jaxb-runtime:${jaxb.runtime.vespa.version}
+org.glassfish.jaxb:txw2:${jaxb.runtime.vespa.version}
+org.hamcrest:hamcrest-core:${hamcrest.vespa.version}
+org.hamcrest:hamcrest:${hamcrest.vespa.version}
+org.hdrhistogram:HdrHistogram:${hdrhistogram.vespa.version}
org.iq80.snappy:snappy:0.4
-org.json:json:20230618
-org.junit.jupiter:junit-jupiter-api:5.10.0
-org.junit.jupiter:junit-jupiter-api:5.8.1
-org.junit.jupiter:junit-jupiter-engine:5.8.1
-org.junit.platform:junit-platform-commons:1.8.1
-org.junit.platform:junit-platform-engine:1.8.1
-org.junit.platform:junit-platform-launcher:1.8.1
+org.json:json:${org.json.vespa.version}
+org.junit.jupiter:junit-jupiter-api:${junit.vespa.tenant.version}
+org.junit.jupiter:junit-jupiter-api:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter-engine:${junit.vespa.tenant.version}
+org.junit.jupiter:junit-jupiter-engine:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter-params:${junit.vespa.version}
+org.junit.jupiter:junit-jupiter:${junit.vespa.version}
+org.junit.platform:junit-platform-commons:${junit.platform.vespa.tenant.version}
+org.junit.platform:junit-platform-commons:${junit.platform.vespa.version}
+org.junit.platform:junit-platform-engine:${junit.platform.vespa.tenant.version}
+org.junit.platform:junit-platform-engine:${junit.platform.vespa.version}
+org.junit.platform:junit-platform-launcher:${junit.platform.vespa.tenant.version}
+org.junit.vintage:junit-vintage-engine:${junit.vespa.tenant.version}
+org.junit.vintage:junit-vintage-engine:${junit.vespa.version}
org.kohsuke:libpam4j:1.11
-org.lz4:lz4-java:1.8.0
-org.opentest4j:opentest4j:1.3.0
-org.ow2.asm:asm:9.5
-org.ow2.asm:asm-analysis:9.5
-org.ow2.asm:asm-commons:9.5
-org.ow2.asm:asm-tree:9.5
-org.ow2.asm:asm-util:9.5
-org.questdb:questdb:7.3.2
-org.slf4j:jcl-over-slf4j:1.7.36
-org.slf4j:log4j-over-slf4j:1.7.36
-org.slf4j:slf4j-api:1.7.36
-org.slf4j:slf4j-jdk14:1.7.36
-org.slf4j:slf4j-simple:1.7.36
+org.lz4:lz4-java:${org.lz4.vespa.version}
+org.mockito:mockito-core:${mockito.vespa.version}
+org.mockito:mockito-junit-jupiter:${mockito.vespa.version}
+org.objenesis:objenesis:3.3
+org.opentest4j:opentest4j:${opentest4j.vespa.version}
+org.ow2.asm:asm-analysis:${asm.vespa.version}
+org.ow2.asm:asm-commons:${asm.vespa.version}
+org.ow2.asm:asm-tree:${asm.vespa.version}
+org.ow2.asm:asm-util:${asm.vespa.version}
+org.ow2.asm:asm:${asm.vespa.version}
+org.questdb:questdb:${questdb.vespa.version}
+org.slf4j:jcl-over-slf4j:${slf4j.vespa.version}
+org.slf4j:log4j-over-slf4j:${slf4j.vespa.version}
+org.slf4j:slf4j-api:${slf4j.vespa.version}
+org.slf4j:slf4j-jdk14:${slf4j.vespa.version}
+org.slf4j:slf4j-simple:${slf4j.vespa.version}
org.tukaani:xz:1.9
-org.xerial.snappy:snappy-java:1.1.10.4
+org.wiremock:wiremock-standalone:${wiremock.vespa.version}
+org.xerial.snappy:snappy-java:${snappy.vespa.version}
software.amazon.ion:ion-java:1.0.2
-xerces:xercesImpl:2.12.2
-
-#[test-only]
-# Contains dependencies that are used exclusively in 'test' scope
-com.google.jimfs:jimfs:1.3.0
-net.bytebuddy:byte-buddy:1.14.8
-net.bytebuddy:byte-buddy-agent:1.14.8
-org.apache.curator:curator-test:5.5.0
-org.assertj:assertj-core:3.24.2
-org.junit.jupiter:junit-jupiter:5.10.0
-org.junit.jupiter:junit-jupiter-engine:5.10.0
-org.junit.jupiter:junit-jupiter-params:5.10.0
-org.junit.platform:junit-platform-commons:1.10.0
-org.junit.platform:junit-platform-engine:1.10.0
-org.junit.vintage:junit-vintage-engine:5.10.0
-org.junit.vintage:junit-vintage-engine:5.8.1
-org.mockito:mockito-core:5.5.0
-org.mockito:mockito-junit-jupiter:5.5.0
-org.objenesis:objenesis:3.3
-org.wiremock:wiremock-standalone:3.1.0
+xerces:xercesImpl:${xerces.vespa.version}
diff --git a/vespa-dependencies-enforcer/pom.xml b/vespa-dependencies-enforcer/pom.xml
index 768e5708ee5..91820fd292b 100644
--- a/vespa-dependencies-enforcer/pom.xml
+++ b/vespa-dependencies-enforcer/pom.xml
@@ -38,7 +38,7 @@
</goals>
<configuration>
<rules>
- <enforceDependencies implementation="com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects">
+ <enforceDependencies implementation="com.yahoo.vespa.maven.plugin.enforcer.AllowedDependencies">
<rootProjectId>com.yahoo.vespa:vespa</rootProjectId>
<specFile>allowed-maven-dependencies.txt</specFile>
<ignored>
@@ -47,14 +47,6 @@
<i>com.yahoo.vespa.bundle-plugin:*:*</i>
<i>com.yahoo.vespa.jdisc_core:*:*</i>
</ignored>
-
- <!-- Classifly all dependencies of below modules as 'test' -->
- <testUtilProjects>
- <!-- Misc -->
- <i>com.yahoo.vespa:testutil</i>
- <!-- Bundle plugin integration test -->
- <i>com.yahoo.vespa.bundle-plugin:*</i>
- </testUtilProjects>
</enforceDependencies>
</rules>
<fail>true</fail>
diff --git a/vespa-enforcer-extensions/pom.xml b/vespa-enforcer-extensions/pom.xml
index 9d8e99156f3..04abb00739c 100644
--- a/vespa-enforcer-extensions/pom.xml
+++ b/vespa-enforcer-extensions/pom.xml
@@ -45,6 +45,11 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
@@ -54,21 +59,18 @@
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
+ <!-- generate index of project components -->
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>sisu-maven-plugin</artifactId>
+ <version>0.9.0.M1</version>
<executions>
<execution>
- <phase>package</phase>
<goals>
- <goal>shade</goal>
+ <goal>main-index</goal>
</goals>
- <configuration>
- <createDependencyReducedPom>false</createDependencyReducedPom>
- </configuration>
</execution>
</executions>
</plugin>
-
</plugins>
</build>
diff --git a/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/AllowedDependencies.java b/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/AllowedDependencies.java
new file mode 100644
index 00000000000..656e2f52558
--- /dev/null
+++ b/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/AllowedDependencies.java
@@ -0,0 +1,305 @@
+package com.yahoo.vespa.maven.plugin.enforcer;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.enforcer.rule.api.AbstractEnforcerRule;
+import org.apache.maven.enforcer.rule.api.EnforcerRule;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
+import org.apache.maven.shared.dependency.graph.DependencyNode;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author bjorncs
+ */
+@Named("allowedDependencies")
+@SuppressWarnings("deprecation")
+public class AllowedDependencies extends AbstractEnforcerRule implements EnforcerRule {
+
+ private static final String WRITE_SPEC_PROP = "dependencyEnforcer.writeSpec";
+ private static final String GUESS_VERSION = "dependencyEnforcer.guessProperty";
+
+ @Inject private MavenProject project;
+ @Inject private MavenSession session;
+ @Inject private DependencyGraphBuilder graphBuilder;
+
+ // Injected parameters
+ public List<String> ignored;
+ public String rootProjectId;
+ public String specFile;
+
+ @Override
+ public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
+ try {
+ project = (MavenProject) helper.evaluate("${project}");
+ session = (MavenSession) helper.evaluate("${session}");
+ graphBuilder = helper.getComponent(DependencyGraphBuilder.class);
+ } catch (ExpressionEvaluationException | ComponentLookupException e) {
+ throw new RuntimeException(e);
+ }
+ execute();
+ }
+
+ public void execute() throws EnforcerRuleException {
+ var dependencies = getDependenciesOfAllProjects();
+ getLog().info("Found %d unique dependencies ".formatted(dependencies.size()));
+ var specFile = Paths.get(project.getBasedir() + File.separator + this.specFile).normalize();
+ var spec = loadDependencySpec(specFile);
+ var resolved = resolve(spec, dependencies);
+ if (System.getProperties().containsKey(WRITE_SPEC_PROP)) {
+ writeDependencySpec(specFile, resolved, System.getProperties().containsKey(GUESS_VERSION));
+ getLog().info("Updated spec file '%s'".formatted(specFile.toString()));
+ } else {
+ warnOnDuplicateVersions(resolved);
+ validateDependencies(resolved, session.getRequest().getPom().toPath(), project.getArtifactId());
+ }
+ getLog().info("The dependency enforcer completed successfully");
+ }
+
+ private static void validateDependencies(Resolved resolved, Path aggregatorPomRoot, String moduleName)
+ throws EnforcerRuleException {
+ if (!resolved.unmatchedRules().isEmpty() || !resolved.unmatchedDeps().isEmpty()) {
+ var errorMsg = new StringBuilder("The dependency enforcer failed:\n");
+ if (!resolved.unmatchedRules().isEmpty()) {
+ errorMsg.append("Rules not matching any dependency:\n");
+ resolved.unmatchedRules().forEach(r -> errorMsg.append(" - ").append(r.asString()).append('\n'));
+ }
+ if (!resolved.unmatchedDeps().isEmpty()) {
+ errorMsg.append("Dependencies not matching any rule:\n");
+ resolved.unmatchedDeps().forEach(d -> errorMsg.append(" - ").append(d.asString(null)).append('\n'));
+ }
+ throw new EnforcerRuleException(
+ errorMsg.append("Maven dependency validation failed. ")
+ .append("If this change was intentional, update the dependency spec by running:\n")
+ .append("$ mvn validate -D").append(WRITE_SPEC_PROP).append(" -pl :").append(moduleName)
+ .append(" -f ").append(aggregatorPomRoot).append("\n").toString());
+ }
+ }
+
+ private Set<Dependency> getDependenciesOfAllProjects() throws EnforcerRuleException {
+ try {
+ Pattern depIgnorePattern = Pattern.compile(
+ ignored.stream()
+ .map(s -> s.replace(".", "\\.").replace("*", ".*").replace(":", "\\:").replace('?', '.'))
+ .collect(Collectors.joining(")|(", "^(", ")$")));
+ List<MavenProject> projects = getAllProjects(session, rootProjectId);
+ Set<Dependency> dependencies = new HashSet<>();
+ for (MavenProject project : projects) {
+ var req = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
+ req.setProject(project);
+ var root = graphBuilder.buildDependencyGraph(req, null);
+ addDependenciesRecursive(root, dependencies, depIgnorePattern);
+ }
+ return Set.copyOf(dependencies);
+ } catch (DependencyGraphBuilderException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ private static void addDependenciesRecursive(DependencyNode node, Set<Dependency> dependencies, Pattern ignored) {
+ if (node.getChildren() != null) {
+ for (DependencyNode dep : node.getChildren()) {
+ Artifact a = dep.getArtifact();
+ Dependency dependency = Dependency.fromArtifact(a);
+ if (!ignored.matcher(dependency.asString(null)).matches()) {
+ dependencies.add(dependency);
+ }
+ addDependenciesRecursive(dep, dependencies, ignored);
+ }
+ }
+ }
+
+ /** Only return the projects we'd like to enforce dependencies for: the root project, its modules, their modules, etc. */
+ private static List<MavenProject> getAllProjects(MavenSession session, String rootProjectId) throws EnforcerRuleException {
+ if (rootProjectId == null) throw new EnforcerRuleException("Missing required <rootProjectId> in <enforceDependencies> in pom.xml");
+
+ List<MavenProject> allProjects = session.getAllProjects();
+ if (allProjects.size() == 1) {
+ throw new EnforcerRuleException(
+ "Only a single Maven module detected. Enforcer must be executed from root of aggregator pom.");
+ }
+ MavenProject rootProject = allProjects
+ .stream()
+ .filter(project -> rootProjectId.equals(projectIdOf(project)))
+ .findAny()
+ .orElseThrow(() -> new EnforcerRuleException("Root project not found: " + rootProjectId));
+
+ Map<Path, MavenProject> projectsByBaseDir = allProjects
+ .stream()
+ .collect(Collectors.toMap(project -> project.getBasedir().toPath().normalize(), project -> project));
+
+ var projects = new ArrayList<MavenProject>();
+
+ var pendingProjects = new ArrayDeque<MavenProject>();
+ pendingProjects.add(rootProject);
+
+ while (!pendingProjects.isEmpty()) {
+ MavenProject project = pendingProjects.pop();
+ projects.add(project);
+
+ for (var module : project.getModules()) {
+ // Assumption: The module is a relative path to a project base directory.
+ Path moduleBaseDir = project.getBasedir().toPath().resolve(module).normalize();
+ MavenProject moduleProject = projectsByBaseDir.get(moduleBaseDir);
+ if (moduleProject == null)
+ throw new EnforcerRuleException("Failed to find module '" + module + "' in project " + project.getBasedir());
+ pendingProjects.add(moduleProject);
+ }
+ }
+
+ projects.sort(Comparator.comparing(AllowedDependencies::projectIdOf));
+ return projects;
+ }
+
+ private List<Rule> loadDependencySpec(Path specFile) {
+ try (Stream<String> s = Files.lines(specFile)) {
+ return s.map(String::trim)
+ .filter(l -> !l.isEmpty() && !l.startsWith("#"))
+ .map(Rule::fromString)
+ .toList();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private Resolved resolve(List<Rule> spec, Set<Dependency> dependencies) {
+ var resolvedDeps = new HashSet<Dependency>();
+ var resolveRules = new HashSet<Rule>();
+ var unmatchedDeps = new HashSet<Dependency>();
+ var unmatchedRules = new HashSet<Rule>();
+ for (var rule : spec) {
+ var requiredDependency = rule.resolveToDependency(project.getProperties());
+ if (dependencies.contains(requiredDependency)) {
+ resolvedDeps.add(requiredDependency);
+ resolveRules.add(rule);
+ } else {
+ unmatchedRules.add(rule);
+ }
+ }
+ for (var dependency : dependencies) {
+ if (!resolvedDeps.contains(dependency)) {
+ unmatchedDeps.add(dependency);
+ }
+ }
+ return new Resolved(resolvedDeps, resolveRules, unmatchedDeps, unmatchedRules);
+ }
+
+ void writeDependencySpec(Path specFile, Resolved resolved, boolean guessVersion) {
+ var content = new TreeSet<String>();
+ resolved.matchedRules().forEach(r -> content.add(r.asString()));
+ resolved.unmatchedDeps().forEach(d -> content.add(d.asString(guessVersion ? project.getProperties() : null)));
+ try (var out = Files.newBufferedWriter(specFile)) {
+ out.write("# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.\n\n");
+ for (var line : content) {
+ out.write(line); out.write('\n');
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private void warnOnDuplicateVersions(Resolved resolved) {
+ Map<String, Set<String>> versionsForDependency = new TreeMap<>();
+ Set<Dependency> allDeps = new HashSet<>(resolved.matchedDeps());
+ allDeps.addAll(resolved.unmatchedDeps());
+ for (Dependency d : allDeps) {
+ String id = "%s:%s".formatted(d.groupId(), d.artifactId());
+ versionsForDependency.computeIfAbsent(id, __ -> new TreeSet<>()).add(d.version());
+ }
+ versionsForDependency.forEach((dependency, versions) -> {
+ if (versions.size() > 1) {
+ getLog().warn("'%s' has multiple versions %s".formatted(dependency, versions));
+ }
+ });
+ }
+
+ private static String projectIdOf(MavenProject project) { return "%s:%s".formatted(project.getGroupId(), project.getArtifactId()); }
+
+ private record Rule(String groupId, String artifactId, String version, Optional<String> classifier){
+ static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{(.+?)}");
+
+ static Rule fromString(String s) {
+ String[] splits = s.split(":");
+ return splits.length == 3
+ ? new Rule(splits[0], splits[1], splits[2], Optional.empty())
+ : new Rule(splits[0], splits[1], splits[2], Optional.of(splits[3]));
+ }
+
+ Dependency resolveToDependency(Properties props) {
+ // Replace expressions on form ${property} in 'version' field with value from properties
+ var matcher = PROPERTY_PATTERN.matcher(version);
+ var resolvedVersion = version;
+ while (matcher.find()) {
+ String property = matcher.group(1);
+ String value = props.getProperty(property);
+ if (value == null) throw new IllegalArgumentException("Missing property: " + property);
+ resolvedVersion = version.replace(matcher.group(), value);
+ }
+ return new Dependency(groupId, artifactId, resolvedVersion, classifier);
+ }
+
+ String asString() {
+ var b = new StringBuilder(groupId).append(':').append(artifactId).append(':').append(version);
+ classifier.ifPresent(c -> b.append(':').append(c));
+ return b.toString();
+ }
+ }
+
+ record Dependency(String groupId, String artifactId, String version, Optional<String> classifier) {
+ static Dependency fromArtifact(Artifact a) {
+ return new Dependency(
+ a.getGroupId(), a.getArtifactId(), a.getVersion(), Optional.ofNullable(a.getClassifier()));
+ }
+
+ String asString(Properties props) {
+ String versionStr = version;
+ if (props != null) {
+ // Guess property name if properties are provided
+ var matchingProps = props.entrySet().stream()
+ .filter(e -> e.getValue().equals(version))
+ .map(v -> "${%s}".formatted(v.getKey()))
+ .collect(Collectors.joining("|"));
+ if (!matchingProps.isEmpty()) versionStr = matchingProps;
+ }
+ var b = new StringBuilder(groupId).append(':').append(artifactId).append(':').append(versionStr);
+ classifier.ifPresent(c -> b.append(':').append(c));
+ return b.toString();
+ }
+ }
+
+ record Resolved(Set<Dependency> matchedDeps, Set<Rule> matchedRules,
+ Set<Dependency> unmatchedDeps, Set<Rule> unmatchedRules) {}
+
+ // Mark rule as not cachable
+ @Override public boolean isCacheable() { return false; }
+ @Override public boolean isResultValid(EnforcerRule r) { return false; }
+ @Override public String getCacheId() { return ""; }
+}
diff --git a/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjects.java b/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjects.java
deleted file mode 100644
index 3db1019a2b1..00000000000
--- a/vespa-enforcer-extensions/src/main/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjects.java
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.maven.plugin.enforcer;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.enforcer.rule.api.EnforcerRule;
-import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
-import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.DefaultProjectBuildingRequest;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * @author bjorncs
- */
-@SuppressWarnings("deprecation")
-public class EnforceDependenciesAllProjects implements EnforcerRule {
-
- private static final String WRITE_SPEC_PROP = "dependencyEnforcer.writeSpec";
- private static final String NON_TEST_HEADER = "#[non-test]";
- private static final String TEST_ONLY_HEADER = "#[test-only]";
-
- private String rootProjectId;
- private String specFile;
- private List<String> ignored = List.of();
- private List<String> testUtilProjects = List.of();
-
- @Override
- public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
- Log log = helper.getLog();
- Dependencies deps = getDependenciesOfAllProjects(helper, ignored, testUtilProjects, rootProjectId);
- log.info("Found %d unique dependencies (%d non-test, %d test only)".formatted(
- deps.nonTest().size() + deps.testOnly().size(), deps.nonTest().size(), deps.testOnly().size()));
- Path specFile = resolveSpecFile(helper, this.specFile);
- if (System.getProperties().containsKey(WRITE_SPEC_PROP)) {
- writeDependencySpec(specFile, deps);
- log.info("Updated spec file '%s'".formatted(specFile.toString()));
- } else {
- warnOnDuplicateVersions(log, deps);
- validateDependencies(deps, specFile, aggregatorPomRoot(helper), projectName(helper));
- }
- log.info("The dependency enforcer completed successfully");
- }
-
- // Config injection for rule configuration. Method names must match config XML elements.
- @SuppressWarnings("unused") public void setRootProjectId(String l) { this.rootProjectId = l; }
- @SuppressWarnings("unused") public String getRootProjectId() { return rootProjectId; }
- @SuppressWarnings("unused") public void setSpecFile(String f) { this.specFile = f; }
- @SuppressWarnings("unused") public String getSpecFile() { return specFile; }
- @SuppressWarnings("unused") public void setIgnored(List<String> l) { this.ignored = l; }
- @SuppressWarnings("unused") public List<String> getIgnored() { return ignored; }
- @SuppressWarnings("unused") public void setTestUtilProjects(List<String> l) { this.testUtilProjects = l; }
- @SuppressWarnings("unused") public List<String> getTestUtilProjects() { return testUtilProjects; }
-
- record Dependency(String groupId, String artifactId, String version, Optional<String> classifier)
- implements Comparable<Dependency> {
- static Dependency fromArtifact(Artifact a) {
- return new Dependency(
- a.getGroupId(), a.getArtifactId(), a.getVersion(), Optional.ofNullable(a.getClassifier()));
- }
-
- static Dependency fromString(String s) {
- String[] splits = s.split(":");
- return splits.length == 3
- ? new Dependency(splits[0], splits[1], splits[2], Optional.empty())
- : new Dependency(splits[0], splits[1], splits[2], Optional.of(splits[3]));
- }
-
- String asString() {
- var b = new StringBuilder(groupId).append(':').append(artifactId).append(':').append(version);
- classifier.ifPresent(c -> b.append(':').append(c));
- return b.toString();
- }
-
- static final Comparator<Dependency> COMPARATOR = Comparator.comparing(Dependency::groupId)
- .thenComparing(Dependency::artifactId).thenComparing(Dependency::version)
- .thenComparing(d -> d.classifier().orElse(""));
- @Override public int compareTo(Dependency o) { return COMPARATOR.compare(this, o); }
- }
-
- record Dependencies(SortedSet<Dependency> nonTest, SortedSet<Dependency> testOnly) {}
-
- static void validateDependencies(Dependencies dependencies, Path specFile, Path aggregatorPomRoot,
- String moduleName)
- throws EnforcerRuleException {
- Dependencies allowedDependencies = loadDependencySpec(specFile);
- if (!allowedDependencies.equals(dependencies)) {
- StringBuilder errorMsg = new StringBuilder("The dependency enforcer failed:\n");
- generateDiff(errorMsg, "non-test", dependencies.nonTest(), allowedDependencies.nonTest());
- generateDiff(errorMsg, "test-only", dependencies.testOnly(), allowedDependencies.testOnly());
- throw new EnforcerRuleException(
- errorMsg.append("Maven dependency validation failed. ")
- .append("If this change was intentional, update the dependency spec by running:\n")
- .append("$ mvn validate -D").append(WRITE_SPEC_PROP).append(" -pl :").append(moduleName)
- .append(" -f ").append(aggregatorPomRoot).append("\n").toString());
- }
- }
-
- static void generateDiff(
- StringBuilder errorMsg, String label, SortedSet<Dependency> actual, SortedSet<Dependency> expected) {
- SortedSet<Dependency> forbidden = new TreeSet<>(actual);
- forbidden.removeAll(expected);
- SortedSet<Dependency> removed = new TreeSet<>(expected);
- removed.removeAll(actual);
- if (!forbidden.isEmpty()) {
- errorMsg.append("Forbidden ").append(label).append(" dependencies:\n");
- forbidden.forEach(d -> errorMsg.append(" - ").append(d.asString()).append('\n'));
- }
- if (!removed.isEmpty()) {
- errorMsg.append("Removed ").append(label).append(" dependencies:\n");
- removed.forEach(d -> errorMsg.append(" - ").append(d.asString()).append('\n'));
- }
- }
-
- private static Dependencies getDependenciesOfAllProjects(EnforcerRuleHelper helper, List<String> ignored,
- List<String> testUtilProjects, String rootProjectId)
- throws EnforcerRuleException {
- try {
- Pattern depIgnorePattern = Pattern.compile(
- ignored.stream()
- .map(s -> s.replace(".", "\\.").replace("*", ".*").replace(":", "\\:").replace('?', '.'))
- .collect(Collectors.joining(")|(", "^(", ")$")));
- Pattern projectIgnorePattern = Pattern.compile(
- testUtilProjects.stream()
- .map(s -> s.replace(".", "\\.").replace("*", ".*").replace(":", "\\:").replace('?', '.'))
- .collect(Collectors.joining(")|(", "^(", ")$")));
- SortedSet<Dependency> nonTestDeps = new TreeSet<>();
- SortedSet<Dependency> testDeps = new TreeSet<>();
- MavenSession session = mavenSession(helper);
- var graphBuilder = helper.getComponent(DependencyGraphBuilder.class);
- List<MavenProject> projects = getAllProjects(session, rootProjectId);
- for (MavenProject project : projects) {
- var req = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
- req.setProject(project);
- DependencyNode root = graphBuilder.buildDependencyGraph(req, null);
- String projectId = projectIdOf(project);
- boolean overrideToTest = projectIgnorePattern.matcher(projectId).matches();
- if (overrideToTest) helper.getLog().info("Treating dependencies of '%s' as 'test'".formatted(projectId));
- addDependenciesRecursive(root, nonTestDeps, testDeps, depIgnorePattern, overrideToTest);
- }
- testDeps.removeAll(nonTestDeps);
- return new Dependencies(nonTestDeps, testDeps);
- } catch (DependencyGraphBuilderException | ComponentLookupException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- private static String projectIdOf(MavenProject project) { return "%s:%s".formatted(project.getGroupId(), project.getArtifactId()); }
-
- /** Only return the projects we'd like to enforce dependencies for: the root project, its modules, their modules, etc. */
- private static List<MavenProject> getAllProjects(MavenSession session, String rootProjectId) throws EnforcerRuleException {
- if (rootProjectId == null) throw new EnforcerRuleException("Missing required <rootProjectId> in <enforceDependencies> in pom.xml");
-
- List<MavenProject> allProjects = session.getAllProjects();
- if (allProjects.size() == 1) {
- throw new EnforcerRuleException(
- "Only a single Maven module detected. Enforcer must be executed from root of aggregator pom.");
- }
- MavenProject rootProject = allProjects
- .stream()
- .filter(project -> rootProjectId.equals(projectIdOf(project)))
- .findAny()
- .orElseThrow(() -> new EnforcerRuleException("Root project not found: " + rootProjectId));
-
- Map<Path, MavenProject> projectsByBaseDir = allProjects
- .stream()
- .collect(Collectors.toMap(project -> project.getBasedir().toPath().normalize(), project -> project));
-
- var projects = new ArrayList<MavenProject>();
-
- var pendingProjects = new ArrayDeque<MavenProject>();
- pendingProjects.add(rootProject);
-
- while (!pendingProjects.isEmpty()) {
- MavenProject project = pendingProjects.pop();
- projects.add(project);
-
- for (var module : project.getModules()) {
- // Assumption: The module is a relative path to a project base directory.
- Path moduleBaseDir = project.getBasedir().toPath().resolve(module).normalize();
- MavenProject moduleProject = projectsByBaseDir.get(moduleBaseDir);
- if (moduleProject == null)
- throw new EnforcerRuleException("Failed to find module '" + module + "' in project " + project.getBasedir());
- pendingProjects.add(moduleProject);
- }
- }
-
- projects.sort(Comparator.comparing(EnforceDependenciesAllProjects::projectIdOf));
- return projects;
- }
-
- private static void addDependenciesRecursive(
- DependencyNode node, Set<Dependency> nonTestDeps, Set<Dependency> testDeps, Pattern ignored,
- boolean overrideToTest) {
- if (node.getChildren() != null) {
- for (DependencyNode dep : node.getChildren()) {
- Artifact a = dep.getArtifact();
- Dependency dependency = Dependency.fromArtifact(a);
- if (!ignored.matcher(dependency.asString()).matches()) {
- if (a.getScope().equals("test") || overrideToTest) {
- testDeps.add(dependency);
- } else {
- nonTestDeps.add(dependency);
- }
- }
- addDependenciesRecursive(dep, nonTestDeps, testDeps, ignored, overrideToTest);
- }
- }
- }
-
- private static void warnOnDuplicateVersions(Log log, Dependencies deps) {
- Map<String, Set<String>> versionsForDependency = new TreeMap<>();
- Set<Dependency> allDeps = new TreeSet<>(deps.nonTest());
- allDeps.addAll(deps.testOnly());
- for (Dependency d : allDeps) {
- String id = "%s:%s".formatted(d.groupId(), d.artifactId());
- versionsForDependency.computeIfAbsent(id, __ -> new TreeSet<>()).add(d.version());
- }
- versionsForDependency.forEach((dependency, versions) -> {
- if (versions.size() > 1) {
- log.warn("'%s' has multiple versions %s".formatted(dependency, versions));
- }
- });
- }
-
- private static Path resolveSpecFile(EnforcerRuleHelper helper, String specFile) {
- return Paths.get(mavenProject(helper).getBasedir() + File.separator + specFile).normalize();
- }
-
- private static String projectName(EnforcerRuleHelper helper) { return mavenProject(helper).getArtifactId(); }
-
- private static Path aggregatorPomRoot(EnforcerRuleHelper helper) {
- return mavenSession(helper).getRequest().getPom().toPath();
- }
-
- private static MavenProject mavenProject(EnforcerRuleHelper helper) {
- try {
- return (MavenProject) helper.evaluate("${project}");
- } catch (ExpressionEvaluationException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- private static MavenSession mavenSession(EnforcerRuleHelper helper) {
- try {
- return (MavenSession) helper.evaluate("${session}");
- } catch (ExpressionEvaluationException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- static void writeDependencySpec(Path specFile, Dependencies dependencies) {
- try (var out = Files.newBufferedWriter(specFile)) {
- out.write("# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.\n\n");
- out.write(NON_TEST_HEADER); out.write('\n');
- out.write("# Contains dependencies that are not used exclusively in 'test' scope\n");
- for (Dependency d : dependencies.nonTest()) {
- out.write(d.asString()); out.write('\n');
- }
- out.write("\n"); out.write(TEST_ONLY_HEADER); out.write('\n');
- out.write("# Contains dependencies that are used exclusively in 'test' scope\n");
- for (Dependency d : dependencies.testOnly()) {
- out.write(d.asString()); out.write('\n');
- }
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- private static Dependencies loadDependencySpec(Path specFile) {
- try {
- List<String> lines;
- try (Stream<String> s = Files.lines(specFile)) {
- lines = s.map(String::trim).filter(l -> !l.isEmpty()).toList();
- }
- SortedSet<Dependency> nonTest = parseDependencies(lines.stream().takeWhile(l -> !l.equals(TEST_ONLY_HEADER)));
- SortedSet<Dependency> testOnly = parseDependencies(lines.stream().dropWhile(l -> !l.equals(TEST_ONLY_HEADER)));
- return new Dependencies(nonTest, testOnly);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- private static SortedSet<Dependency> parseDependencies(Stream<String> lines) {
- return lines.filter(l -> !l.startsWith("#")).map(Dependency::fromString)
- .collect(Collectors.toCollection(TreeSet::new));
- }
-
- // Mark rule as not cachable
- @Override public boolean isCacheable() { return false; }
- @Override public boolean isResultValid(EnforcerRule r) { return false; }
- @Override public String getCacheId() { return ""; }
-
-}
diff --git a/vespa-enforcer-extensions/src/test/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjectsTest.java b/vespa-enforcer-extensions/src/test/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjectsTest.java
deleted file mode 100644
index 59062cbd61c..00000000000
--- a/vespa-enforcer-extensions/src/test/java/com/yahoo/vespa/maven/plugin/enforcer/EnforceDependenciesAllProjectsTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.maven.plugin.enforcer;
-
-import com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects.Dependencies;
-import com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects.Dependency;
-import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import static com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects.validateDependencies;
-import static com.yahoo.vespa.maven.plugin.enforcer.EnforceDependenciesAllProjects.writeDependencySpec;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-/**
- * @author bjorncs
- */
-class EnforceDependenciesAllProjectsTest {
-
- private static final Path POM_FILE = Paths.get("/vespa-src/pom.xml");
-
- @Test
- void succeeds_dependencies_matches_spec() {
- SortedSet<Dependency> nonTest = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:foo:1.2.3"),
- Dependency.fromString("com.example:bar:2.3.4")));
- SortedSet<Dependency> testOnly = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:testfoo:1.2.3"),
- Dependency.fromString("com.example:testbar:2.3.4")));
- Path specFile = Paths.get("src/test/resources/allowed-dependencies.txt");
- Dependencies deps = new Dependencies(nonTest, testOnly);
- assertDoesNotThrow(() -> validateDependencies(deps, specFile, POM_FILE, "my-dep-enforcer"));
- }
-
- @Test
- void fails_on_forbidden_dependency() {
- SortedSet<Dependency> nonTest = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:foo:1.2.3"),
- Dependency.fromString("com.example:bar:2.3.4"),
- Dependency.fromString("com.example:foobar:3.4.5")));
- SortedSet<Dependency> testOnly = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:testfoo:1.2.3"),
- Dependency.fromString("com.example:testbar:2.3.4")));
- Path specFile = Paths.get("src/test/resources/allowed-dependencies.txt");
- Dependencies deps = new Dependencies(nonTest, testOnly);
- var exception = assertThrows(EnforcerRuleException.class,
- () -> validateDependencies(deps, specFile, POM_FILE, "my-dep-enforcer"));
- String expectedErrorMessage =
- """
- The dependency enforcer failed:
- Forbidden non-test dependencies:
- - com.example:foobar:3.4.5
- Maven dependency validation failed. If this change was intentional, update the dependency spec by running:
- $ mvn validate -DdependencyEnforcer.writeSpec -pl :my-dep-enforcer -f /vespa-src/pom.xml
- """;
- assertEquals(expectedErrorMessage, exception.getMessage());
- }
-
- @Test
- void fails_on_missing_dependency() {
- SortedSet<Dependency> nonTest = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:bar:2.3.4")));
- SortedSet<Dependency> testOnly = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:testfoo:1.2.3")));
- Path specFile = Paths.get("src/test/resources/allowed-dependencies.txt");
- Dependencies deps = new Dependencies(nonTest, testOnly);
- var exception = assertThrows(EnforcerRuleException.class,
- () -> validateDependencies(deps, specFile, POM_FILE, "my-dep-enforcer"));
- String expectedErrorMessage =
- """
- The dependency enforcer failed:
- Removed non-test dependencies:
- - com.example:foo:1.2.3
- Removed test-only dependencies:
- - com.example:testbar:2.3.4
- Maven dependency validation failed. If this change was intentional, update the dependency spec by running:
- $ mvn validate -DdependencyEnforcer.writeSpec -pl :my-dep-enforcer -f /vespa-src/pom.xml
- """;
- assertEquals(expectedErrorMessage, exception.getMessage());
- }
-
- @Test
- void writes_valid_spec_file(@TempDir Path tempDir) throws IOException {
- SortedSet<Dependency> nonTest = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:foo:1.2.3"),
- Dependency.fromString("com.example:bar:2.3.4")));
- SortedSet<Dependency> testOnly = new TreeSet<>(Set.of(
- Dependency.fromString("com.example:testfoo:1.2.3"),
- Dependency.fromString("com.example:testbar:2.3.4")));
- Dependencies deps = new Dependencies(nonTest, testOnly);
- Path outputFile = tempDir.resolve("allowed-dependencies.txt");
- writeDependencySpec(outputFile, deps);
- assertEquals(
- Files.readString(Paths.get("src/test/resources/allowed-dependencies.txt")),
- Files.readString(outputFile));
-
- }
-
-} \ No newline at end of file
diff --git a/vespa-enforcer-extensions/src/test/resources/allowed-dependencies.txt b/vespa-enforcer-extensions/src/test/resources/allowed-dependencies.txt
deleted file mode 100644
index 2ef0f9e0c0c..00000000000
--- a/vespa-enforcer-extensions/src/test/resources/allowed-dependencies.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#[non-test]
-# Contains dependencies that are not used exclusively in 'test' scope
-com.example:bar:2.3.4
-com.example:foo:1.2.3
-
-#[test-only]
-# Contains dependencies that are used exclusively in 'test' scope
-com.example:testbar:2.3.4
-com.example:testfoo:1.2.3