diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java index e602dd09da..c8703dd814 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java @@ -16,6 +16,8 @@ package com.google.cloud.tools.jib.gradle; +import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME; + import com.google.cloud.tools.jib.ProjectInfo; import com.google.cloud.tools.jib.gradle.skaffold.CheckJibVersionTask; import com.google.cloud.tools.jib.gradle.skaffold.FilesTaskV2; @@ -23,18 +25,20 @@ import com.google.cloud.tools.jib.gradle.skaffold.SyncMapTask; import com.google.cloud.tools.jib.plugins.common.VersionChecker; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.gradle.api.GradleException; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; -import org.gradle.api.UnknownTaskException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.DependencySet; import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.plugins.BasePlugin; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskProvider; import org.gradle.jvm.tasks.Jar; @@ -162,68 +166,49 @@ public void apply(Project project) { SyncMapTask.class, task -> task.setJibExtension(jibExtension)); + Set> jibTaskProviders = + ImmutableSet.of(buildImageTask, buildDockerTask, buildTarTask, syncMapTask); + // A check to catch older versions of Jib. This can be removed once we are certain people // are using Jib 1.3.1 or later. tasks.register(SKAFFOLD_CHECK_REQUIRED_VERSION_TASK_NAME, CheckJibVersionTask.class); project.afterEvaluate( projectAfterEvaluation -> { - try { - TaskProvider warTask = TaskCommon.getWarTaskProvider(projectAfterEvaluation); - TaskProvider bootWarTask = - TaskCommon.getBootWarTaskProvider(projectAfterEvaluation); - List> dependsOnTask = new ArrayList<>(); - if (warTask != null || bootWarTask != null) { - // Have all tasks depend on the 'war' and/or 'bootWar' task. - if (warTask != null) { - dependsOnTask.add(warTask); - } - if (bootWarTask != null) { - dependsOnTask.add(bootWarTask); - } - } else if ("packaged".equals(jibExtension.getContainerizingMode())) { - // Have all tasks depend on the 'jar' task. - TaskProvider jarTask = projectAfterEvaluation.getTasks().named("jar"); - dependsOnTask.add(jarTask); - - if (projectAfterEvaluation.getPlugins().hasPlugin("org.springframework.boot")) { - Jar jar = (Jar) jarTask.get(); - jar.setEnabled(true); - jar.getArchiveClassifier().set("original"); - } - } else { - // Have all tasks depend on the 'classes' task. - dependsOnTask.add(projectAfterEvaluation.getTasks().named("classes")); + TaskProvider warTask = TaskCommon.getWarTaskProvider(projectAfterEvaluation); + TaskProvider bootWarTask = + TaskCommon.getBootWarTaskProvider(projectAfterEvaluation); + List jibDependencies = new ArrayList<>(); + if (warTask != null || bootWarTask != null) { + // Have all tasks depend on the 'war' and/or 'bootWar' task. + if (warTask != null) { + jibDependencies.add(warTask); + } + if (bootWarTask != null) { + jibDependencies.add(bootWarTask); } - buildImageTask.configure(task -> task.dependsOn(dependsOnTask)); - buildDockerTask.configure(task -> task.dependsOn(dependsOnTask)); - buildTarTask.configure(task -> task.dependsOn(dependsOnTask)); - syncMapTask.configure(task -> task.dependsOn(dependsOnTask)); - - // Find project dependencies and add a dependency to their assemble task. We make sure - // to only add the dependency after BasePlugin is evaluated as otherwise the assemble - // task may not be available yet. - List computedDependencies = getProjectDependencies(projectAfterEvaluation); - for (Project dependencyProject : computedDependencies) { - dependencyProject - .getPlugins() - .withType( - BasePlugin.class, - unused -> { - TaskProvider assembleTask = - dependencyProject.getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME); - buildImageTask.configure(task -> task.dependsOn(assembleTask)); - buildDockerTask.configure(task -> task.dependsOn(assembleTask)); - buildTarTask.configure(task -> task.dependsOn(assembleTask)); - }); + } else if ("packaged".equals(jibExtension.getContainerizingMode())) { + // Have all tasks depend on the 'jar' task. + TaskProvider jarTask = projectAfterEvaluation.getTasks().named("jar"); + jibDependencies.add(jarTask); + + if (projectAfterEvaluation.getPlugins().hasPlugin("org.springframework.boot")) { + Jar jar = (Jar) jarTask.get(); + jar.setEnabled(true); + jar.getArchiveClassifier().set("original"); } - } catch (UnknownTaskException ex) { - throw new GradleException( - "Could not find task 'classes' on project " - + projectAfterEvaluation.getDisplayName() - + " - perhaps you did not apply the 'java' plugin?", - ex); } + + SourceSet mainSourceSet = + project + .getConvention() + .getPlugin(JavaPluginConvention.class) + .getSourceSets() + .getByName(MAIN_SOURCE_SET_NAME); + jibDependencies.add(mainSourceSet.getRuntimeClasspath()); + + jibTaskProviders.forEach( + provider -> provider.configure(task -> task.setDependsOn(jibDependencies))); }); } } diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java index a0f4ceff9e..2f2bf04c33 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java @@ -17,15 +17,12 @@ package com.google.cloud.tools.jib.gradle; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.gradle.api.GradleException; import org.gradle.api.Project; @@ -136,72 +133,6 @@ public void testCheckJibVersionInvoked() { } } - @SuppressWarnings("unchecked") - @Test - public void testProjectDependencyAssembleTasksAreRun() { - // root project is our jib packaged service - Project rootProject = createProject("java"); - - // our service DOES depend on this, and jib should trigger an assemble from this project - Project subProject = - ProjectBuilder.builder() - .withParent(rootProject) - .withProjectDir(testProjectRoot.getRoot()) - .withName("sub") - .build(); - subProject.getPluginManager().apply("java"); - - // our service doesn't depend on this, and jib should NOT trigger an assemble from this project - Project unrelatedSubProject = - ProjectBuilder.builder() - .withParent(rootProject) - .withProjectDir(testProjectRoot.getRoot()) - .withName("unrelated") - .build(); - unrelatedSubProject.getPluginManager().apply("java"); - - // equivalent of "compile project(':sub')" on the root(jib) project - rootProject - .getConfigurations() - .getByName("compile") - .getDependencies() - .add(rootProject.getDependencies().project(ImmutableMap.of("path", subProject.getPath()))); - - // programmatic check - Assert.assertEquals( - Collections.singletonList(":sub"), - JibPlugin.getProjectDependencies(rootProject) - .stream() - .map(Project::getPath) - .collect(Collectors.toList())); - - // check by applying the jib plugin and inspect the task dependencies - rootProject.getPluginManager().apply("com.google.cloud.tools.jib"); - - TaskContainer tasks = rootProject.getTasks(); - // add a custom task that our jib tasks depend on to ensure we do not overwrite this dependsOn - TaskProvider dependencyTask = rootProject.getTasks().register("myCustomTask", task -> {}); - KNOWN_JIB_TASKS.forEach(taskName -> tasks.getByPath(taskName).dependsOn(dependencyTask)); - - ((ProjectInternal) rootProject).evaluate(); - - KNOWN_JIB_TASKS.forEach( - taskName -> - Assert.assertEquals( - ImmutableSet.of(":sub:assemble", ":classes", ":myCustomTask"), - tasks - .getByPath(taskName) - .getDependsOn() - .stream() - .map( - object -> - object instanceof List ? object : Collections.singletonList(object)) - .map(List.class::cast) - .flatMap(List::stream) - .map(object -> ((TaskProvider) object).get().getPath()) - .collect(Collectors.toSet()))); - } - @SuppressWarnings("unchecked") @Test public void testWebAppProject() { @@ -213,10 +144,16 @@ public void testWebAppProject() { Assert.assertNotNull(warTask); for (String taskName : KNOWN_JIB_TASKS) { - List> taskProviders = - (List>) tasks.getByPath(taskName).getDependsOn().iterator().next(); - Assert.assertEquals(1, taskProviders.size()); - Assert.assertEquals(warTask, taskProviders.get(0).get()); + Set taskDependencies = + tasks + .getByPath(taskName) + .getDependsOn() + .stream() + .filter(TaskProvider.class::isInstance) + .map(it -> ((TaskProvider) it).get()) + .collect(Collectors.toSet()); + + Assert.assertTrue(taskDependencies.contains(warTask)); } } @@ -234,11 +171,16 @@ public void testWebAppProject_bootWar() { Assert.assertNotNull(bootWarTask); for (String taskName : KNOWN_JIB_TASKS) { - List> taskProviders = - (List>) tasks.getByPath(taskName).getDependsOn().iterator().next(); - Assert.assertEquals( - ImmutableSet.of(warTask, bootWarTask), - taskProviders.stream().map(TaskProvider::get).collect(Collectors.toSet())); + Set taskDependencies = + tasks + .getByPath(taskName) + .getDependsOn() + .stream() + .filter(TaskProvider.class::isInstance) + .map(it -> ((TaskProvider) it).get()) + .collect(Collectors.toSet()); + + Assert.assertTrue(taskDependencies.containsAll(Arrays.asList(warTask, bootWarTask))); } } @@ -257,11 +199,16 @@ public void testWebAppProject_bootWarDisabled() { bootWarTask.setEnabled(false); // should depend on bootWar even if disabled for (String taskName : KNOWN_JIB_TASKS) { - List> taskProviders = - (List>) tasks.getByPath(taskName).getDependsOn().iterator().next(); - Assert.assertEquals( - ImmutableSet.of(warTask, bootWarTask), - taskProviders.stream().map(TaskProvider::get).collect(Collectors.toSet())); + Set taskDependencies = + tasks + .getByPath(taskName) + .getDependsOn() + .stream() + .filter(TaskProvider.class::isInstance) + .map(it -> ((TaskProvider) it).get()) + .collect(Collectors.toSet()); + + Assert.assertTrue(taskDependencies.containsAll(Arrays.asList(warTask, bootWarTask))); } }