How to check from within a Gradle file if a task has been or has not been excluded? - gradle

In a Gradle file is the following configuration:
publishing {
publications {
if (os == 'osx') {
nebulaIvy(IvyPublication) {
artifact('build/final/java_plugin-linux-x86_64/linux-x86_64.exe') {
classifier 'linux-x86_64'
extension 'exe'
type 'exe'
}
}
}
The Linux binary is built through the task buildInDocker. If the buildInDocker task is excluded (eg gradlew -x buildInDocker), that part of the configuration shouldn't be done. How can this be done?

Use https://docs.gradle.org/current/javadoc/org/gradle/StartParameter.html#getExcludedTaskNames(): !project.getGradle().startParameter.getExcludedTaskNames().contains('buildInDocker').

Related

Gradle JAR Creation Timing

i have a gradle build that retrieves properties file and such that are remote (to keep passwords out of github) but the remote retrieval doesn't complete by the time the JAR is built.
i figured i either had to get the JAR created in the execution phase instead of configuration phase or add the remote files in the execution phase but i couldn't get either working.
any suggestions?
task fatJar(type: Jar) {
doFirst {
exec {
executable './scripts/getRemoteResources.sh'
}
}
...
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
//some resources are retrieved remotely & b/c of timing they don't get included here
from ('src/main/java/resources') {
include '*'
}
with jar
//tried this but doesn't work
//doLast {
// jar {
// from ('src/main/java/resources') {
// include '*'
// }
// }
//}
}
You shouldn't use the task graph for this. Also you shouldn't download the file to src/main/
Instead, you should
Create a task to download the remote resources to a directory under $buildDir (so it's cleaned via the "clean" task)
Configure the TaskOutputs so that the result can be cached and re-used.
Wire the task into Gradle's DAG
Add the directory to the "processResources" task so it ends up on the runtime classpath (ie in the jar)
Eg:
tasks.register('remoteResources', Exec) {
inputs.property('environment', project.property('env')) // this assumes there's a project property named 'env'
outputs.dir "$buildDir/remoteResources" // point 2 (above)
commandLine = [
'./scripts/getRemoteResources.sh',
'--environment', project.property('env'),
'--outputdir', "$buildDir/remoteResources"
]
doFirst {
delete "$buildDir/remoteResources"
mkdir "$buildDir/remoteResources"
}
}
processResources {
from tasks.remoteResources // points 3 & 4 (above)
}
See The Java Plugin - Tasks
processResources — Copy
Copies production resources into the production resources directory.
this seems to work so i'm going with it unless someone has a better solution...
gradle.taskGraph.beforeTask { Task task ->
println "just before $task.name"
// i just chose to kick this off with the first task sent through here
if (task.name=="compileJava") {
exec {
executable './scripts/getRemoteResources.sh'
}
}
}
task fatJar(type: Jar) {
...
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
from ('src/main/java/resources') {
include '*'
}
with jar
}

How do I use ant-compress within Gradle (untar an xz tar file)?

I want to untar a file that is in .tar.xz format. Gradle's tarTree() does not support this format, so I need to unzip the .xz to a .tar, then I can make use of it.
According to the docs, i should be able to do something like this:
ant.untar(src: myTarFile, compression: "xz", dest: extractDir)
However, I get an error:
Caused by: : xz is not a legal value for this attribute
at org.apache.tools.ant.types.EnumeratedAttribute.setValue(EnumeratedAttribute.java:94)
This SO answer talks about using the Apache Ant Compress antlib within Maven. How can I achieve a similar result using Gradle?
Converting the Maven SO answer in your link would be something like:
configurations {
antCompress
}
dependencies {
antCompress 'org.apache.ant:ant-compress:1.4'
}
task untar {
ext {
xzFile = file('path/to/file.xz')
outDir = "$buildDir/untar"
}
inputs.file xzFile
outputs.dir outDir
doLast {
ant.taskdef(
resource:"org/apache/ant/compress/antlib.xml"
classpath: configurations.antCompress.asPath
)
ant.unxz(src:xzFile.absolutePath, dest:"$buildDir/unxz.tar" )
copy {
from tarTree("$buildDir/unxz.tar")
into outDir
}
}
}
See https://docs.gradle.org/current/userguide/ant.html
Here's my solution that involves command line utilities.
task untar() {
inputs.property('archiveFile', 'path/to/file.xz')
inputs.property('dest', 'path/to/file.xz')
outputs.dir("${buildDir}/destination")
doLast {
mkdir("${buildDir}/destination")
exec {
commandLine('tar', 'xJf', inputs.properties.archiveFile, '-C', "${buildDir}/destination")
}
}
}

Gradle task to create a zip archive of a directory

I have a gradle task to create a zip archive of a directory.
The gradle task is:
task archiveReports(type: Zip) {
from '/projects/Reports/*'
archiveName 'Reports.zip'
}
When I am running the command 'gradle archiveReports', its showing the build is successful. However, no zip file is getting created.
Am I missing something here?
I figured out a way for this:
Its working for me now.
task myZip(type: Zip) {
from 'Reports/'
include '*'
include '*/*' //to include contents of a folder present inside Reports directory
archiveName 'Reports.zip'
destinationDir(file('/dir1/dir2/dir3/'))
}
With Gradle 6.7,
task packageDistribution(type: Zip) {
archiveFileName = "my-distribution.zip"
destinationDirectory = file("$buildDir/dist")
from "$buildDir/toArchive"
}
Note : archiveName is deprected.
With Kotlin DSL
tasks.register<Zip>("packageDistribution") {
archiveFileName.set("my-distribution.zip")
destinationDirectory.set(layout.buildDirectory.dir("dist"))
from(layout.buildDirectory.dir("toArchive"))
}
With Groovy
tasks.register('packageDistribution', Zip) {
archiveFileName = "my-distribution.zip"
destinationDirectory = layout.buildDirectory.dir('dist')
from layout.buildDirectory.dir("toArchive")
}
Taken from the official docs
Just in case anyone will come here to find out how to zip your project e.g. to use it as an AWS lambda zip, here you go:
tasks {
val zipTask by register("createZip", Zip::class) {
from(processResources)
from(compileKotlin)
archiveFileName.set("app.zip")
into("lib") {
from(configurations.runtimeClasspath)
}
}
build {
dependsOn(zipTask)
}
}

Gradle copy build script dependency to folder

We are building one of our applications with gradle and part of the distribution I want to include an external jar which is not a run time dependency in a config folder. That jar is needed as part of the application install and it contains some custom ant tasks.
Our build script dependency looks like below:
buildscript {
...
dependencies {
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
classpath 'my-group:custom-tasks:1.2.3'
}
}
How would I access and copy the custom-task-1.2.3.jar into a certain folder so I can include it in my distribution? Something like below:
task copyCustomTasks {
doLast {
copy {
// This below is a make up to express what I want
from buildscript.dependencies
include 'custom-tasks*.jar'
into "$buildDir/config"
}
}
}
If this is not the gradle way of doing things please let me know what alternatives I have.
Thank you in advance for your help.
UPDATE
I solved my problem in a different way by creating an extra configuration. However I would still be interested to find out how you can access build script dependencies at run time. Thanks again for your inputs.
configurations {
install {
description = "application install classpath"
transitive = true
}
}
...
dependencies {
...
install('my-group:custom-tasks:1.2.3')
...
}
...
task copyInstallDeps {
doLast {
copy {
from configurations.install
into "$buildDir/config"
}
}
}
You're quite close:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.guava:guava:18.0'
}
}
task copyLibs(type: Copy) {
from buildscript.configurations.classpath
into 'lib'
}

How to run a Gradle task after apks are produced in Android Studio?

The following task (in build.gradle of an app's module) seems to run always before the apk is produced:
android.applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
def releaseBuildTask = tasks.create(name: "debug") {
println(".................... test ..............................")
}
releaseBuildTask.mustRunAfter variant.assemble
}
}
Could anyone offer a tip on how to run a task after the apks are produced?
Android tasks are typically created in the "afterEvaluate" phase.
Starting from gradle 2.2, those tasks also include "assembleDebug" and
"assembleRelease". To access such tasks, the user will need to use an
afterEvaluate closure:
afterEvaluate {
assembleDebug.dependsOn someTask
}
source: https://code.google.com/p/android/issues/detail?id=219732#c32
try add this in you app/build.gradle
assembleDebug.doLast {
android.applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
def releaseBuildTask = tasks.create(name: "debug") {
println(".................... test ..............................")
}
releaseBuildTask.mustRunAfter variant.assemble
}
}
println "build finished"
}
invoke the build command and specify the task assembleDebug
./gradlew assembleDebug
I found a solution that works, to copy the release APK into the project root automatically on build completion.
android {
...
task copyReleaseApk(type: Copy) {
from 'build/outputs/apk'
into '..' // Into the project root, one level above the app folder
include '**/*release.apk'
}
afterEvaluate {
packageRelease.finalizedBy(copyReleaseApk)
}
}

Resources