aboutsummaryrefslogtreecommitdiffstats
path: root/bundle-plugin/src/main/java/com/yahoo/container/plugin/util
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-07-08 13:24:41 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-07-08 13:24:41 +0200
commit9b8f0756ecc1a038fbaab4388f74886965a5c02f (patch)
treecdcc27f7300017635ca200441a62106447fa5aae /bundle-plugin/src/main/java/com/yahoo/container/plugin/util
parent92e778cf7cb3a41c516becd4b2e8cf5cc295b865 (diff)
Move helper classes from 'mojo' to 'util'
Diffstat (limited to 'bundle-plugin/src/main/java/com/yahoo/container/plugin/util')
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/util/Artifacts.java82
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleDependencyScopeTranslator.java115
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleUtils.java25
3 files changed, 222 insertions, 0 deletions
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/Artifacts.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/Artifacts.java
new file mode 100644
index 00000000000..fc771e23fa7
--- /dev/null
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/Artifacts.java
@@ -0,0 +1,82 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.util;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Tony Vaagenes
+ * @author ollivir
+ */
+public class Artifacts {
+ interface ScopeTranslator {
+ String scopeOf(Artifact artifact);
+ }
+
+ private static class NoopScopeTranslator implements ScopeTranslator {
+ @Override public String scopeOf(Artifact artifact) { return artifact.getScope(); }
+ }
+
+ public static class ArtifactSet {
+
+ private final List<Artifact> jarArtifactsToInclude;
+ private final List<Artifact> jarArtifactsProvided;
+ private final List<Artifact> nonJarArtifacts;
+
+ private ArtifactSet(
+ List<Artifact> jarArtifactsToInclude,
+ List<Artifact> jarArtifactsProvided,
+ List<Artifact> nonJarArtifacts) {
+ this.jarArtifactsToInclude = jarArtifactsToInclude;
+ this.jarArtifactsProvided = jarArtifactsProvided;
+ this.nonJarArtifacts = nonJarArtifacts;
+ }
+
+ public List<Artifact> getJarArtifactsToInclude() {
+ return jarArtifactsToInclude;
+ }
+
+ public List<Artifact> getJarArtifactsProvided() {
+ return jarArtifactsProvided;
+ }
+
+ public List<Artifact> getNonJarArtifacts() {
+ return nonJarArtifacts;
+ }
+ }
+
+ public static ArtifactSet getArtifacts(MavenProject project) { return getArtifacts(project, new NoopScopeTranslator()); }
+
+ public static ArtifactSet getArtifacts(MavenProject project, ScopeTranslator scopeTranslator) {
+ List<Artifact> jarArtifactsToInclude = new ArrayList<>();
+ List<Artifact> jarArtifactsProvided = new ArrayList<>();
+ List<Artifact> nonJarArtifactsToInclude = new ArrayList<>();
+ List<Artifact> nonJarArtifactsProvided = new ArrayList<>();
+ for (Artifact artifact : project.getArtifacts()) {
+ String scope = scopeTranslator.scopeOf(artifact);
+ if ("jar".equals(artifact.getType())) {
+ if (Artifact.SCOPE_COMPILE.equals(scope)) {
+ jarArtifactsToInclude.add(artifact);
+ } else if (Artifact.SCOPE_PROVIDED.equals(scope)) {
+ jarArtifactsProvided.add(artifact);
+ }
+ } else {
+ if (Artifact.SCOPE_COMPILE.equals(scope)) {
+ nonJarArtifactsToInclude.add(artifact);
+ } else if (Artifact.SCOPE_PROVIDED.equals(scope)) {
+ nonJarArtifactsProvided.add(artifact);
+ }
+ }
+ }
+ nonJarArtifactsToInclude.addAll(nonJarArtifactsProvided);
+ return new ArtifactSet(jarArtifactsToInclude, jarArtifactsProvided, nonJarArtifactsToInclude);
+ }
+
+ public static Collection<Artifact> getArtifactsToInclude(MavenProject project) {
+ return getArtifacts(project, new NoopScopeTranslator()).getJarArtifactsToInclude();
+ }
+}
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleDependencyScopeTranslator.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleDependencyScopeTranslator.java
new file mode 100644
index 00000000000..04ede59e2fe
--- /dev/null
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleDependencyScopeTranslator.java
@@ -0,0 +1,115 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.util;
+
+import org.apache.maven.artifact.Artifact;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Translates the scope of dependencies when constructing a test bundle.
+ * Used by {@link Artifacts} to determine which artifacts that are provided by the runtime or must be included in the bundle.
+ *
+ * Dependencies of scope 'test' are by default translated to 'compile'. Dependencies of other scopes are kept as is.
+ *
+ * Default scope translation for 'test' scope dependencies can be overridden through a comma-separated configuration string.
+ * Each substring is a triplet on the form [groupId]:[artifactId]:[scope].
+ * Scope translation overrides affects all transitive dependencies.
+ * The ordering of the triplets determines the priority - only the first matching override will affect a given dependency.
+ *
+ * @author bjorncs
+ */
+public class TestBundleDependencyScopeTranslator implements Artifacts.ScopeTranslator {
+
+ private static final Logger log = Logger.getLogger(TestBundleDependencyScopeTranslator.class.getName());
+
+ private final Map<Artifact, String> dependencyScopes;
+
+ private TestBundleDependencyScopeTranslator(Map<Artifact, String> dependencyScopes) {
+ this.dependencyScopes = dependencyScopes;
+ }
+
+ @Override public String scopeOf(Artifact artifact) { return Objects.requireNonNull(dependencyScopes.get(artifact)); }
+
+ public static TestBundleDependencyScopeTranslator from(Map<String, Artifact> dependencies, String rawConfig) {
+ List<DependencyOverride> dependencyOverrides = toDependencyOverrides(rawConfig);
+ Map<Artifact, String> dependencyScopes = new HashMap<>();
+ for (Artifact dependency : dependencies.values()) {
+ dependencyScopes.put(dependency, getScopeForDependency(dependency, dependencyOverrides, dependencies));
+ }
+ return new TestBundleDependencyScopeTranslator(dependencyScopes);
+ }
+
+ private static List<DependencyOverride> toDependencyOverrides(String rawConfig) {
+ if (rawConfig == null || rawConfig.isBlank()) return List.of();
+ return Arrays.stream(rawConfig.split(","))
+ .map(String::strip)
+ .filter(s -> !s.isBlank())
+ .map(TestBundleDependencyScopeTranslator::toDependencyOverride)
+ .collect(toList());
+ }
+
+ private static DependencyOverride toDependencyOverride(String overrideString) {
+ String[] elements = overrideString.split(":");
+ if (elements.length != 3) {
+ throw new IllegalArgumentException("Invalid dependency override: " + overrideString);
+ }
+ return new DependencyOverride(elements[0], elements[1], elements[2]);
+ }
+
+ private static String stripVersionAndScope(String idInDependencyTrail) {
+ int firstDelimiter = idInDependencyTrail.indexOf(':');
+ int secondDelimiter = idInDependencyTrail.indexOf(':', firstDelimiter + 1);
+ return idInDependencyTrail.substring(0, secondDelimiter);
+ }
+
+ private static String getScopeForDependency(
+ Artifact dependency, List<DependencyOverride> overrides, Map<String, Artifact> otherArtifacts) {
+ String oldScope = dependency.getScope();
+ if (!oldScope.equals(Artifact.SCOPE_TEST)) return oldScope;
+ for (DependencyOverride override : overrides) {
+ for (Artifact dependent : dependencyTrailOf(dependency, otherArtifacts)) {
+ if (override.isForArtifact(dependent)) {
+ log.fine(() -> String.format(
+ "Overriding scope of '%s'; scope '%s' overridden to '%s'",
+ dependency.getId(), oldScope, override.scope));
+ return override.scope;
+ }
+ }
+ }
+ log.fine(() -> String.format(
+ "Using default scope translation for '%s'; scope 'test' translated to 'compile'",
+ dependency.getId()));
+ return Artifact.SCOPE_COMPILE;
+ }
+
+ private static List<Artifact> dependencyTrailOf(Artifact artifact, Map<String, Artifact> otherArtifacts) {
+ return artifact.getDependencyTrail().stream()
+ .skip(1) // Maven project itself is the first entry
+ .map(parentId -> otherArtifacts.get(stripVersionAndScope(parentId)))
+ .filter(Objects::nonNull)
+ .collect(toList());
+ }
+
+ private static class DependencyOverride {
+ final String groupId;
+ final String artifactId;
+ final String scope;
+
+ DependencyOverride(String groupId, String artifactId, String scope) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.scope = scope;
+ }
+
+ boolean isForArtifact(Artifact artifact) {
+ return artifact.getGroupId().equals(groupId) && artifact.getArtifactId().equals(artifactId);
+ }
+ }
+}
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleUtils.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleUtils.java
new file mode 100644
index 00000000000..b8824952995
--- /dev/null
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/TestBundleUtils.java
@@ -0,0 +1,25 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.util;
+
+import org.apache.maven.project.MavenProject;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.JarFile;
+
+/**
+ * @author bjorncs
+ */
+public class TestBundleUtils {
+ private TestBundleUtils() {}
+
+ public static Path outputDirectory(MavenProject project) { return targetDirectory(project).resolve("test-bundle/"); }
+
+ public static Path manifestFile(MavenProject project) { return outputDirectory(project).resolve(JarFile.MANIFEST_NAME); }
+
+ public static Path archiveFile(MavenProject project) {
+ return targetDirectory(project).resolve(project.getBuild().getFinalName() + "-tests.jar");
+ }
+
+ private static Path targetDirectory(MavenProject project) { return Paths.get(project.getBuild().getDirectory()); }
+}