Realmente me gustaría apreciar Gradle 5 especialmente en combinación con el nuevo Kotlin DSL, pero estoy teniendo un momento muy difícil de conseguir (en mis ojos) una acumulación muy, muy simple y común que funciona con Gradle.
Tarea
Liberar una biblioteca de Java con varios submódulos interdependientes en Maven disposición de directorios por defecto como de alta calidad Maven artefactos / repositorio en una simple acumulación Gradle (es decir, a-la-punto SECO ).
Por lo tanto: Tener un proyecto de raíz como paraguas que define y contiene toda la configuración común (prácticamente todos excepto las dependencias reales).
Mis luchas actuales
Porté mis "resultados" actuales para un proyecto de ejemplo en Github y esta pregunta en el foro Gradle ya .
Actualmente estoy no declarar la tarea necesaria para proporcionar estándar -sources
y -javadoc
artefactos en mi centro de acumulación.
Por ejemplo, estos tres "soluciones" que encontrará en la búsqueda de soluciones basadas en un Kotlin DSL toda ningún trabajo (ya) en un escenario de varios módulos:
- https://stackoverflow.com/a/48070667
- https://stackoverflow.com/a/52596969/1237653
- e incluso el oficial "Maven Publicar" documentación sólo se está trabajando en un escenario de un solo módulo.
Solución incompleta ( /build.gradle.kts
)
Ejemplo Véase completa en Github: https://github.com/bentolor/gradle-maven-multimodule-kotlindsl
subprojects {
apply(plugin = "java-library")
apply(plugin = "maven-publish")
group = "de.bentolor.sampleproject"
version = "0.1.0"
repositories {
jcenter()
}
dependencies {
// Dependencies used in EVERY module
"compile"("commons-logging:commons-logging:1.2")
"testImplementation"("junit:junit:4.12")
}
tasks {
// not working
/*register("sourcesJar", Jar::class.java) {
from(sourceSets.main.get().allJava)
classifier = "sources"
}*/
// not working, eiher
/* task<Jar>("sourcesJar") {
from(sourceSets.main.get().allJava)
classifier = "sources"
} */
}
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
configure<PublishingExtension> {
publications {
create<MavenPublication>(project.name) {
from(components["java"])
// won't work, beause inaccessible declaration in `tasks{}`-Block
//add("archives", javadocJar)
//add("archives", sourcesJar)
}
}
repositories {
mavenLocal()
}
}
}
Ejemplo submódulo /module2/build.gradle.kts
group = "de.bentolor.sampleproject.module2"
dependencies {
compile(project(":module1"))
}
Prueba esto:
subprojects {
apply<JavaLibraryPlugin>()
apply<MavenPublishPlugin>()
group = "de.bentolor.sampleproject"
version = "0.1.0"
repositories {
jcenter()
}
dependencies {
val implementation by configurations
val testImplementation by configurations
implementation("commons-logging:commons-logging:1.2")
testImplementation("junit:junit:4.12")
}
// This will work, but as long as these tasks are need only for publishing you can declare them inplace later where you need
// tasks {
// val sourcesJar by creating(Jar::class) {
// val sourceSets: SourceSetContainer by project
// from(sourceSets["main"].allJava)
// classifier = "sources"
// }
// val javadoc by getting(Javadoc::class)
// val javadocJar by creating(Jar::class) {
// from(javadoc)
// classifier = "javadoc"
// }
// }
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
configure<PublishingExtension> {
publications {
create<MavenPublication>(project.name) {
from(components["java"])
// If you configured them before
// val sourcesJar by tasks.getting(Jar::class)
// val javadocJar by tasks.getting(Jar::class)
val sourcesJar by tasks.creating(Jar::class) {
val sourceSets: SourceSetContainer by project
from(sourceSets["main"].allJava)
classifier = "sources"
}
val javadocJar by tasks.creating(Jar::class) {
from(tasks.get("javadoc"))
classifier = "javadoc"
}
artifact(sourcesJar)
artifact(javadocJar)
}
}
}
}
Unas pocas notas:
- ¿Por qué utilizar
String
-basadoapply
, cuando se puede hacer un tipo de fallosapply<T>()
? - ¿Por qué utilizar invoca en picaduras en
dependencies
, cuando se puede utilizar delegados, que es menos hacky y mejor refactorable. - Considere el uso
implementation
en lugar decompile
¿Por qué sourceSets
no está trabajando en un proyecto de varios módulos?
Cuando se está utilizando DSL Kotlin genera descriptores de acceso para proyectos basados en los plugins aplicadas. Es un proceso de dos pasos: primero Gradle procesa los plugins (que es por eso que se recomienda a los pusieron en plugins
bloque) y genera descriptores de acceso y luego se puede utilizar en su código (descriptores de acceso se generan como extensiones Kotlin para Project
, NamedDomainObjectContainer
y así sucesivamente). Pero si usted está configurando subproyectos hay dos cuestiones:
- evalúa proyectos de los padres antes de los niños, por lo que las extensiones para niño no se conocen en los padres.
- El conjunto de plugins aplica a padre e hijo es diferente y es necesario utilizar métodos de acceso de los niños en los padres.
sourceSets
es uno de los descriptores de acceso generados por Kotlin DSL para los niños. Y es sólo no está disponible en los padres. Puede hacerlo por uno mismo: sólo se aplican java
plugin subprojects
. sourceSets
estará disponible en los guiones de los niños a construir, pero no en los padres.
Esta es la razón por la que usted puede utilizar java
en niños, pero tienen que utilizar configure<JavaPluginExtension>
cuando se configura en los padres.
Pero se puede utilizar delegados para obtener referencias de objetos de dominio, como tareas, conjuntos de fuente, configuración y así sucesivamente.