How to extend gradle war task with dofirst/dolast - gradle

I need to extend the gradle war task with some doFirst and doLast commands to compile my sencha frontend in production state.
I know to extend a task I need to add task.doFirst {} but this is not working with war. I did some tests using other tasks like
clean {
doFirst {
println "test"
}
}
This is working ... but with war it isn't
war {
doFirst {
println "test"
}
}
My main idea was to remove src/main/webapp from the from list and execute sencha-cmd sencha app build -c --destination $war/ production

You should create a separate task for the sencha compilation with it's own inputs/outputs so Gradle can perform up-to-date checking (so it can be skipped if not necessary). You can then wire the task into the gradle DAG via Task.dependsOn(...)
task compileSencha(type:Exec) {
inputs.dir 'src/main/sencha'
outputs.dir "$buildDir/sencha"
commandLine 'sencha', 'app', 'build', file('src/main/sencha').absolutePath, file("$buildDir/sencha").absolutePath
}
war {
from "$buildDir/sencha"
dependsOn compileSencha
}

Related

Get Gradle classpath from command line

With Maven, I can print the build classpath with this command:
mvn dependency:build-classpath
Is there a similar command I can use with Gradle from the command line, preferably without having to modify any of the build scripts?
You can list all the dependencies in a configuration from CLI:
gradle dependencies --configuration=runtimeOnly
Or you can do that via a task:
task classPath {
doFirst {
configurations.runtimeOnly.each { println it }
// This should probably work as well:
// sourceSets.main.runtimeClasspath.each { println it}
}
}

Why won't gradle jar build a jar that gradle build does?

In my Gradle project, I define an additional sourceSet.
sourceSets {
sample {
java {
srcDir 'sample/java'
}
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
}
}
I then add a task:
task sampleJar(type: Jar) {
classifier 'sample'
from sourceSets.sample.output
}
artifacts {
archives sampleJar
}
If I do > gradle build the additional jar file builds from the additional source set. However, if I do > gradle jar, it doesn't. any reason why?
When I go through the output messages, I see:
gradle build has sampleJar in the Tasks to be executed:
but
gradle jar doesn't.
But unsure as to why?
Because jar is just the task that assembles the main jar file.
build, on the other hand, is the top-level life-cycle task, which depends on assemble. And assemble is documented as
Depends on: jar, and all other tasks that create artifacts attached to the archives configuration.
Since your sampleJar pecisely creates an artifact attached to the archives configuration, assemble, and thus build depends on it.

Gradle root project depends on subprojects build

How can I mention subproject should build before root project.
in settings.gradle
rootProject.name = 'loginmodule'
include 'servicebundle'
include 'webbundle'
include 'webredirectbundle'
When I try this build dependson subprojects:build it is giving error like circular dependency.
Currently in my root project build.gradle is bundling all subprojects like below
task createESA(type: Zip, dependsOn: generateSubSystemFile) {
subprojects.each { dependsOn("${it.name}:build") }
from subprojects.collect { "${it.buildDir}/libs" }
from (subsystemFile) {
into 'OSGI-INF'
}
from ('resources/OSGI-INF') {
into 'OSGI-INF'
}
baseName project.name
extension 'esa'
}
build.finalizedBy createESA
I am using gradle clean build to build the project.
Is there any better way to do that ?? I just want to build all subprojects first before root project build.
Have your createESA task depend on subprojects*.build, it'll say that task can't run until all of the build tasks in all of the subprojects have run. Then, declare that the root project's build task depends on createESA.
task createESA(type: Zip, dependsOn: subprojects*.build) {
// etc...
}
build.dependsOn createESA

gradle composite build: jars from included build in ant taskdef classpath

Project foo defines some ant tasks that are used in root project. For composite build:
setting.gradle
includeBuild '../foo'
build.gradle
configurations {
foo
}
dependencies {
foo fileTree(dir : '../foo/build/libs', include: ['*.jar'])
}
ant.taskdef(name: 'foo',
classname: 'mypackage.Foo',
classpath: configurations.foo.asPath)
The jar of included project foo should be built before evaluating the root project so that the jar will be available in the ant taskdef classpath. How?
but task dependency is in the execution phase, like
task run {
dependsOn gradle.includedBuild('../foo').task(':jar')
}
The jar will be available only after the task is executed, too late.
You can configure ant taskdef at execution phase, when the included project is already built. e.g.
task run {
dependsOn gradle.includedBuild('../foo').task(':jar')
doFirst {
ant.taskdef(name: 'foo',
classname: 'mypackage.Foo',
classpath: configurations.foo.asPath)
// call your ant target as usual
}
}
Even if there is a way of configuring evaluation-time dependency on a composite subproject, you will get a great performance degradation of project evaluation. Even a simple task like tasks or projects will require a full build of ant tasks - definetly not something you want

How to set output file from another gradle build script's task from GradleBuild task?

I have project A with gradle build. I have another project B with gradle build also. I want to include project B's jar into project A's war. I can call project B's build script from project A's build script (see below).
But I can not set project B's jar as output file of task buildB.
Is there any way to set project B's jar (which is output file of task jar) as output file of task buildB?
task buildB(type: GradleBuild) {
buildFile = "../BProject/build.gradle"
tasks = ["clean", "jar"] // jar task produce xxx.jar as it's outputs.files
// HERE, any script to set xxx.jar as outputs.files of task buildB???
}
war {
from (buildB) { // can not get xxx.jar from buildB
into "WEB-INF/classes"
}
}
You probably need to configure a multi module project and define a project-scope dependency.
Since the answer full answer will be lengthy, here you can find a demo that shows how it can be done.
The demo consists of two projects. One project is built to war and has a dependency to another project which is built to war. If you build a project, b will be built automatically and included as a jar.
This is what I did.
/settings.gradle
include 'AProject', 'BProject'
/AProject/build.gradle
task buildB(type: GradleBuild) {
buildFile = "../BProject/build.gradle"
tasks = ["clean", "jar"] // jar task produce xxx.jar as it's outputs.files
}
war {
dependsOn buildB
doFirst {
from (project(':BProject').tasks['jar']) {
into "WEB-INF/classes"
}
}
}

Resources