diff --git a/src/main/kotlin/com/intershop/gradle/icm/ICMBuildPlugin.kt b/src/main/kotlin/com/intershop/gradle/icm/ICMBuildPlugin.kt index b4ff5c6..a9b488b 100644 --- a/src/main/kotlin/com/intershop/gradle/icm/ICMBuildPlugin.kt +++ b/src/main/kotlin/com/intershop/gradle/icm/ICMBuildPlugin.kt @@ -17,10 +17,12 @@ package com.intershop.gradle.icm import com.intershop.gradle.icm.extension.IntershopExtension +import com.intershop.gradle.icm.tasks.CopyThirdpartyLibs import com.intershop.gradle.icm.tasks.CreateServerInfoProperties import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.JavaPlugin +import java.io.File /** * The main plugin class of this plugin. @@ -42,6 +44,8 @@ class ICMBuildPlugin : Plugin { IntershopExtension.INTERSHOP_EXTENSION_NAME, IntershopExtension::class.java, this ) + + // create configurations for ICM project val dbinit = configurations.maybeCreate("dbinit") dbinit.setTransitive(false) @@ -53,6 +57,14 @@ class ICMBuildPlugin : Plugin { configurations.maybeCreate("dockerRuntimeLib") configureCreateServerInfoPropertiesTask(project, extension) + + rootProject.subprojects.forEach { prj -> + prj.plugins.withType(JavaPlugin::class.java) { plugin -> + prj.tasks.maybeCreate("copyThirdpartyLibs", CopyThirdpartyLibs::class.java).apply { + outputDir = File(prj.buildDir, "lib" ) + } + } + } } else { logger.warn("ICM build plugin will be not applied to the sub project '{}'", project.name) } diff --git a/src/main/kotlin/com/intershop/gradle/icm/tasks/CopyThirdpartyLibs.kt b/src/main/kotlin/com/intershop/gradle/icm/tasks/CopyThirdpartyLibs.kt new file mode 100644 index 0000000..abe0b85 --- /dev/null +++ b/src/main/kotlin/com/intershop/gradle/icm/tasks/CopyThirdpartyLibs.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2019 Intershop Communications AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.intershop.gradle.icm.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.internal.component.external.model.DefaultModuleComponentArtifactIdentifier +import java.io.File +import java.util.stream.Collectors +import java.util.stream.Stream + +open class CopyThirdpartyLibs : DefaultTask() { + + private val outputDirProperty: DirectoryProperty = project.objects.directoryProperty() + + /** + * Output directory for generated files. + * + * @property outputDir + */ + @get:OutputDirectory + var outputDir: File + get() = outputDirProperty.get().asFile + set(value) = outputDirProperty.set(value) + + @get:Classpath + private val configurationClasspath: FileCollection by lazy { + val returnFiles = project.files() + + if (project.convention.findPlugin(JavaPluginConvention::class.java) != null) { + returnFiles.from(project.configurations.getByName("runtimeClasspath").files) + } + + returnFiles + } + + @TaskAction + fun runCopy() { + // we are not sure what is changed. + if(outputDir.listFiles().size > 0) { + outputDir.deleteRecursively() + outputDir.mkdirs() + } + + project.configurations.getByName("runtimeClasspath") + .resolvedConfiguration.resolvedArtifacts.forEach { artifact -> + if (artifact.id is DefaultModuleComponentArtifactIdentifier) { + var identifier = artifact.id as DefaultModuleComponentArtifactIdentifier + var name = "${identifier.componentIdentifier.group}-${identifier.componentIdentifier.module}-${identifier.componentIdentifier.version}.${artifact.type}" + println(name) + artifact.file.copyTo( + File(outputDir, name), + overwrite = true + ) + } + } + } +} \ No newline at end of file diff --git a/src/test/groovy/com/intershop/gradle/icm/ICMBuildPluginIntegrationSpec.groovy b/src/test/groovy/com/intershop/gradle/icm/ICMBuildPluginIntegrationSpec.groovy index 3f4c0af..d011bb3 100644 --- a/src/test/groovy/com/intershop/gradle/icm/ICMBuildPluginIntegrationSpec.groovy +++ b/src/test/groovy/com/intershop/gradle/icm/ICMBuildPluginIntegrationSpec.groovy @@ -17,6 +17,8 @@ package com.intershop.gradle.icm import com.intershop.gradle.test.AbstractIntegrationGroovySpec +import org.gradle.testkit.runner.TaskOutcome + import static org.gradle.testkit.runner.TaskOutcome.SUCCESS class ICMBuildPluginIntegrationSpec extends AbstractIntegrationGroovySpec { @@ -167,4 +169,182 @@ class ICMBuildPluginIntegrationSpec extends AbstractIntegrationGroovySpec { where: gradleVersion << supportedGradleVersions } + + def 'CopyThirdpartyLibs of subprojects to empty folder'() { + given: + settingsFile << """ + rootProject.name='rootproject' + """.stripIndent() + + buildFile << """ + plugins { + id 'java' + id 'com.intershop.gradle.icm' + } + + repositories { + jcenter() + } + """.stripIndent() + + def prj1dir = createSubProject('testCartridge1', """ + apply plugin: 'java' + + dependencies { + implementation 'com.google.inject:guice:4.0' + implementation 'com.google.inject.extensions:guice-servlet:3.0' + implementation 'javax.servlet:javax.servlet-api:3.1.0' + + implementation 'io.prometheus:simpleclient:0.6.0' + implementation 'io.prometheus:simpleclient_hotspot:0.6.0' + implementation 'io.prometheus:simpleclient_servlet:0.6.0' + } + + repositories { + jcenter() + } + """.stripIndent()) + + def prj2dir = createSubProject('testCartridge2', """ + apply plugin: 'java' + + dependencies { + implementation 'org.codehaus.janino:janino:2.5.16' + implementation 'org.codehaus.janino:commons-compiler:3.0.6' + implementation 'ch.qos.logback:logback-core:1.2.3' + implementation 'ch.qos.logback:logback-classic:1.2.3' + implementation 'commons-collections:commons-collections:3.2.2' + } + + repositories { + jcenter() + } + """.stripIndent()) + + writeJavaTestClass("com.intershop.testCartridge1", prj1dir) + writeJavaTestClass("com.intershop.testCartridge2", prj2dir) + + when: + def result = getPreparedGradleRunner() + .withArguments("copyThirdpartyLibs") + .withGradleVersion(gradleVersion) + .build() + + then: + result.task(':testCartridge1:copyThirdpartyLibs').outcome == SUCCESS + result.task(':testCartridge2:copyThirdpartyLibs').outcome == SUCCESS + + file("testCartridge2/build/lib/ch.qos.logback-logback-classic-1.2.3.jar").exists() + file("testCartridge1/build/lib/com.google.inject-guice-4.0.jar").exists() + + when: + def result2 = getPreparedGradleRunner() + .withArguments("copyThirdpartyLibs") + .withGradleVersion(gradleVersion) + .build() + + then: + result2.task(':testCartridge1:copyThirdpartyLibs').outcome == TaskOutcome.UP_TO_DATE + result2.task(':testCartridge2:copyThirdpartyLibs').outcome == TaskOutcome.UP_TO_DATE + + where: + gradleVersion << supportedGradleVersions + } + + def 'CopyThirdpartyLibs of subprojects with changed dependencies'() { + given: + settingsFile << """ + rootProject.name='rootproject' + """.stripIndent() + + buildFile << """ + plugins { + id 'java' + id 'com.intershop.gradle.icm' + } + + repositories { + jcenter() + } + """.stripIndent() + + def prj1dir = createSubProject('testCartridge1', """ + apply plugin: 'java' + + dependencies { + implementation "com.google.inject:guice:\${project.ext.inject_guice_version}" + implementation 'com.google.inject.extensions:guice-servlet:3.0' + implementation 'javax.servlet:javax.servlet-api:3.1.0' + + implementation 'io.prometheus:simpleclient:0.6.0' + implementation 'io.prometheus:simpleclient_hotspot:0.6.0' + implementation 'io.prometheus:simpleclient_servlet:0.6.0' + } + + repositories { + jcenter() + } + """.stripIndent()) + + def prj2dir = createSubProject('testCartridge2', """ + apply plugin: 'java' + + dependencies { + implementation "ch.qos.logback:logback-core:\${project.ext.logback_logback_classic_version}" + implementation "ch.qos.logback:logback-classic:\${project.ext.logback_logback_classic_version}" + } + + repositories { + jcenter() + } + """.stripIndent()) + + writeJavaTestClass("com.intershop.testCartridge1", prj1dir) + writeJavaTestClass("com.intershop.testCartridge2", prj2dir) + + when: + File gradleProps = file("gradle.properties") + gradleProps.createNewFile() + gradleProps << """ + inject_guice_version = 4.0 + logback_logback_classic_version = 1.2.3 + """.stripIndent() + + def result = getPreparedGradleRunner() + .withArguments("copyThirdpartyLibs") + .withGradleVersion(gradleVersion) + .build() + + then: + result.task(':testCartridge1:copyThirdpartyLibs').outcome == SUCCESS + result.task(':testCartridge2:copyThirdpartyLibs').outcome == SUCCESS + + new File(testProjectDir,"testCartridge2/build/lib/ch.qos.logback-logback-classic-1.2.3.jar").exists() + new File(testProjectDir,"testCartridge1/build/lib/com.google.inject-guice-4.0.jar").exists() + + when: + gradleProps.delete() + gradleProps.createNewFile() + gradleProps << """ + inject_guice_version = 4.2.2 + logback_logback_classic_version = 1.2.0 + """.stripIndent() + + def result2 = getPreparedGradleRunner() + .withArguments("copyThirdpartyLibs") + .withGradleVersion(gradleVersion) + .build() + + then: + result2.task(':testCartridge1:copyThirdpartyLibs').outcome == SUCCESS + result2.task(':testCartridge2:copyThirdpartyLibs').outcome == SUCCESS + + new File(testProjectDir,"testCartridge2/build/lib/ch.qos.logback-logback-classic-1.2.0.jar").exists() + new File(testProjectDir,"testCartridge1/build/lib/com.google.inject-guice-4.2.2.jar").exists() + ! new File(testProjectDir,"testCartridge2/build/lib/ch.qos.logback-logback-classic-1.2.3.jar").exists() + ! new File(testProjectDir,"testCartridge1/build/lib/com.google.inject-guice-4.0.jar").exists() + + where: + gradleVersion << supportedGradleVersions + } }