My project's build.gradle is in Groovy but I'd like to run as a gradle task the main function of a Kotlin class in a root directory kt file.
I don't know where to begin in terms of syntax.
something like this? I came up with this after searching around a bit.
task doKotlinTask(type: JavaExec) {
classpath "/"
main = "KotlinTaskKt"
}
Create in the root directory buildSrc/src/main/kotlin and place MyKotlinClass.Ktthere. Create buildSrc/build.gradle to add any dependencies for MyKotlinClass.
Then in your project or app's build.gradle, append the following:
import my.package.for.the.kotlin.class
task doKotlinTask(type: MyKotlinClass) {
someParamForTheTask = "hello world"
}
Related
We are going to debug our Android app by adding some properties in app.properties and pre-process it in the Kotlin codes.
We wrote build.gradle like:
task dailytest {
doLast {
File testProperty = new File('assets/app.properties')
testProperty.append("\ndaily_test=true")
testProperty.append("\nfps_sample_interval_ms=")
testProperty.append(fps_sample_interval_ms)
testProperty.append("\ndrop_stack_sample_interval_ms=")
testProperty.append(drop_stack_sample_interval_ms)
testProperty.append("\nmin_drop_count_to_log=")
testProperty.append(min_drop_count_to_log)
}
}
And we compile it in command line using:
./gradlew dailytest -Pfps_sample_interval_ms="100" -Pdrop_stack_sample_interval_ms="100" -Pmin_drop_count_to_log="1" :connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.myapp.sub.MainActivityTest#test_click_shelf
I was wondering if maybe we could run this test case in Android Studio by adding some confirmations?
We did try to add ::dailytest in the Before launch part, but we couldn't manage to find a way to add the custom parameters.
You can have an afterEvaluate block in your build.gradle to run your task when you build your app, something like this:
afterEvaluate {
lint.dependsOn dailytest
}
I've got a directory with three android projects in it.
The MainDir looks like that :
/.gradle
/.git
/project1
/project2
/project3
.gitignore
.Jenkinsfile
.README.md
In jenkins I can't run a shell script during the build that launchs gradle tasks for eauch of those projects because he doesn't know these are projects (he says "no sub-project").
In a project dir it looks like :
/.gradle
/app
/build
/gradle
.gitignore
.build.gradle
.gradle.properties
.gradlew
Is there a way to make jenkins understand these are three projects he can launch gradle taks in ? Like creating a build.gradle file in the main directory doing that ?
Or should I just create 3 Jenkins items?
You could make three builds in jenkins but unless there is a need to build the libs seperately then it might just end up being extra effort. Sounds like what you really want is a multi project build [1]. A simple example could sit at the folder above your lib projects as two files, build.gradle and settings.gradle
The settings.gradle will define what projects are included in your build's scope.
For example given your project1, project2 and project3 example your settings.gradle may look like this.
rootProject.name = 'myRootProjectName'
// note the name is not required to match the actual path
include ":project1"
// but if the name is not the same as the path then we can just
// let gradle know where the project is expected
project(":project1").projectDir = new File(settingsDir, "pathToProject1")
include ":project2"
project(":project2").projectDir = new File(settingsDir, "pathToProject2")
include ":project3"
project(":project3").projectDir = new File(settingsDir, "pathToProject3")
//##### below would be instead of the code above, same thing just manual
// project setup vs letting gradle find the subprojects
// note sometimes you have lots of subprojects in that case it's sometimes
// easier to just use a little logic for finding and setting up the subprojects.
// don't use the code above ##### and below only use one or the other
// or you will have errors. The method below is the most scaleable since
// adding projects requires zero modifications to the root project
rootProject.name = 'myRootProjectName'
// set up a couple file filters to find the dirs we consider subprojects
FileFilter projectFilter = { File pathname ->
FileFilter gradleProjectFilter = { File file -> file.name == 'build.gradle' }
// add this folder if is a directory and that directory contains a build.gradle file
// here note `File#listFiles` is true if it's `size() > 0` due to
// groovy's concept of truth (details: http://groovy-lang.org/semantics.html#Groovy-Truth)
return pathname.isDirectory() && pathname.listFiles(gradleProjectFilter)
}
settingsDir.listFiles(projectFilter).each { dir ->
include ":$dir.name"
project(":$dir.name").projectDir = dir
}
now running gradle projects task should show the three submodules.
As for your build.gradle file you could specify some common properties to all the modules if needed or just leave the file blank, it must exist but can be empty. If you wanted to share some configurations then you might set up the build.gradle with something like this.
project.subprojects { Project subproject ->
// anything that is defined here will be executed before the subproject's build.gradle file
subproject.buildscript {
repositories {
jcenter()
// your private maven repo if needed
maven { url 'http://1.2.3.4:8081/nexus/content/repositories/release' }
}
dependencies {
// some plugin that is now available to be applied in any subproject
classpath 'my.sweet.gradle:plugin:0.1'
}
}
subproject.afterEvaluate {
// this block is executed after the subproject's build.gradle file
if (project.tasks.withType(org.gradle.jvm.tasks.Jar)) {
// for example you might want to set the manifest for each subproject
manifest {
attributes 'Implementation-Title': "Lib $subproject.name",
'Implementation-Version': version
}
}
}
}
[1] https://docs.gradle.org/current/userguide/multi_project_builds.html
I have following task in build.gradle under one of my module :
def output = "build/MobileFramework-Android.${version}/"
task myRelease(type: Copy, dependsOn: ':test:assembleRelease') {
from(project(':test').file('build/intermediates/outputs/apk/'))
into("$output")
include('test-release.apk')
rename('test-release.apk', 'apptm.apk')
}
The porpose is to copy a file from test Module to another module which includes build.gradle.
For some reason myRelease task is not working as I expected. Could you help me out?
I mistakenly specified the from path. The right path is:
from(project(':test').file('build/outputs/apk/'))
Im currently working on an android project where i have to process .java-files to possibly generate another .java-files which should then be compiled and packed into the .apk-file.
Lets assume i have 2 files which will be processed by my library, FILE_A.java and FILE_B.java.
Now i need to access these files within my library via reflection, e.g. with:
Class.forName("com.test.entities.FILE_A");
Class.forName("com.test.entities.FILE_B");
The problem is that i'm not able to access the class files, i think because of the missing classpath configuration. Currently i use this task to call my .jar-file:
task (mytask, type: org.gradle.api.tasks.JavaExec) {
classpath(files('libs/myjar.jar'))
main('com.test.TestMain')
}
preBuild.dependsOn mytask
I found some ressources on the web, but they all don't work.
I tried to add the following to the classpath:
sourceSets.main.runtimeClasspath (main is unknown)
android.sourceSets.main.runtimeClasspath (runtimeClasspath is unkown).
So how can i access the class files in my library?
Try this
task execute(dependsOn: ['compileReleaseJavaWithJavac'], type:JavaExec) {
main = 'com.geniml.Main'
classpath(files('build/intermediates/classes/release',"${android.getSdkDirectory().getAbsolutePath() + '/platforms/' + android.compileSdkVersion + '/android.jar'}"))
}
android gralde is 1.5.
As to build dir, you can use rootProject.getBuildDir(). But normally build dir is a convention. A static way is ok.
I want to add a custom task to my Gradle build file.
Should this go inside the android configuration closure or not?
I tried both and they seem to work fine and I couldn't find any explicit mention in the docs.
the task definition should usually not go into the android blog and on root level as zeventh suggests. though it sometimes useful to do this in the android block. especially when you create these tasks dynamically.
In the following example I create one task for each build variant:
android{
applicationVariants.all{ variant ->
def variantTask = task("${variant.name}CustomTask", type:CustomTask){
...
}
check.dependsOn variantTask
}
}
You should just put the task at the root level of the file, outside the android closure.
task yourTask << {
println "Hello world"
}