Merging Android unit test and connected test code coverage data is broken - android-gradle-plugin

Version 2.3.3 of the Android Gradle Plugin was able to provide merged unit test and connected test code coverage data. In version 3.0.0, this capability is broken because each of the test types use a different and incompatible version of JaCoCo. Rafael Toledo provided a Medium blog post showing how to make this work with 2.3.3. I have provided a Github repo that illustrates the working code and the broken code in a few branches. The repo documentation provides a Readers Digest description of the problem. At this point I am convinced the Gradle Plugin team owns the issue and will file a bug shortly. My questions are:
1) Can anyone suggest a viable workaround? (there is a suggested fix by Carmen Alvarez posted to the Medium blog post but I get no joy from it.)
2) Can someone point me to instructions on how to hack and build the Gradle Android Plugin to test out a potential fix? (I found the answer to this one at http://tools.android.com/build/gradleplugin )

According to Android Plugin DSL Reference that contributes Android specific things:
To specify the version of JaCoCo you want to use, you now need to include it as a buildscript dependency in your project-level build.gradle file, as follows:
buildscript {
dependencies {
classpath "org.jacoco:org.jacoco.core:<jacoco-version>"
...
}
}
Previously Android Plugin had
android {
jacoco {
version = "<jacoco-version>"
}
}
According to Gradle JaCoCo Plugin documentation that contributes task of type JacocoReport:
The JaCoCo plugin adds a project extension named jacoco of type JacocoPluginExtension, which allows configuring defaults for JaCoCo usage in your build.
jacoco {
toolVersion = "<jacoco-version>"
}
And so here is modification for your https://github.com/pajato/acc that allows to align versions so that execution of ./gradlew clean jacocoTestReport succeeds:
buildscript {
dependencies {
classpath "org.jacoco:org.jacoco.core:0.7.9"
}
}
allprojects {
apply plugin: "jacoco"
jacoco {
toolVersion = "0.7.9"
}
}

Related

Can't add kotlinx to a fresh Kotlin/JS project

Trying to figure out what I'm doing wrong. I created a small video of exactly what I'm doing in IntelliJ on Windows.
https://www.youtube.com/watch?v=nIH_55Zbxus&feature=youtu.be
And I'll describe it here in text.
Create a new project
Tick the Gradle > Kotlin/JS for browser template and untick everything else
Add implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8' to the dependencies block in the build.gradle.
Sync the gradle files
Attempt to use something from the kotlinx.coroutines namespace
Hopefully its just a silly thing I'm missing. I expected to just have to add the coroutines library to be able to actually import it. It looks like the library is listed in the project structure for the main module so I'm not sure what else might be wrong. Here is a repo of the project too.
plugins {
id 'org.jetbrains.kotlin.js' version '1.3.72'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-js"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
testImplementation "org.jetbrains.kotlin:kotlin-test-js"
}
kotlin.target.browser { }
You should add kotlinx-coroutines-core-js dependency. See the documentation: https://github.com/Kotlin/kotlinx.coroutines#js

Annotation Processor in IntelliJ and Gradle

tl;dr: I cannot configure IntelliJ to generate the java files in the same directory as gradle
I have a small project which uses the immutables annotation processor.
It works as expected in the gradle command line build, but I cannot get IntelliJ to output the generated files to the same directory.
The full project is available on GitLab
Gradle config:
I use the folowing gradle plugins:
gradle-idea plugin which handles the idea configuration
gradle-apt-plugin which provides the apt configuration and handles the compile-class path and idea config related to annotation processing (if also the idea plugin is applied)
relevant parts of the build-script (link to the full listing):
apply plugin: 'java'
apply plugin: "net.ltgt.apt"
apply plugin: 'idea'
dependencies {
def immutablesVersion = '2.3.9'
compileOnly "org.immutables:value:$immutablesVersion:annotations"
compileOnly "org.immutables:encode:$immutablesVersion"
apt "org.immutables:value:$immutablesVersion"
}
when I start ./gradlew build everything is as expected:
The source file DataEncoding.java is processed an the generated java-file DataEncodingEnabled.java ends up in
/build/generated/source/apt/main under the expected package com.tmtron.immutables.data
and the generated file is also compiled to a .class file
In IntelliJ I activate the annotation processing as suggested by the gradle-apt-plugin docs:
Then I execute ./gradlew clean to make sure, that the previous files are gone and then I click Build - Build Project in IntelliJ.
The annotation processor is executed, but the problem is that the generated java file ends up in the wrong location:
It is in: /build/generated/source/apt/main/build/generated/source/apt/main/com.tmtron.immutables.data
the bold part is redundant.
What am I doing wrong and how can I set it up correctly, so that IntelliJ and gradle generate the files in the same directory?
Notes:
I have of course already tried to just leave the "Production sources dir" in the IntelliJ annotation configuration empty, but his does not work: then it automatically uses "generated" and I also end up with a wrong path.
IntelliJ version 2016.3.4
Now https://github.com/tbroyer/gradle-apt-plugin states:
The goal of this plugin was to eventually no longer be needed, being superseded by built-in features. This is becoming a reality with Gradle 5.2 and IntelliJ IDEA 2019.1.
So:
dependencies {
compile("com.google.dagger:dagger:2.18")
annotationProcessor("com.google.dagger:dagger-compiler:2.18")
compileOnly("com.google.auto.factory:auto-factory:1.0-beta6")
annotationProcessor("com.google.auto.factory:auto-factory:1.0-beta6")
compileOnly("org.immutables:value-annotations:2.7.1")
annotationProcessor("org.immutables:value:2.7.1")
}
compileOnly is necessary if you use annotations, compile if you use classes, annotationProcessor introduced in Gradle 4.6.
To enable processing specific compile task:
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
}
To disable:
compileTestJava {
options.compilerArgs += '-proc:none'
}
UPDATE 2.2019
since Gradle 5.2 there is an easy way to do it - see gavenkoas answer
UPDATE 5.2018
The easiest way, I know of is to use the apt-idea plugin
Just activate the plugin in the build.gradle file:
plugins {
id 'java'
id 'net.ltgt.apt-idea' version "0.15"
}
and then add the annotation processors to the annotationProcessor configuration:
final DAGGER_VER = '2.16'
dependencies {
implementation "com.google.dagger:dagger:${DAGGER_VER}"
annotationProcessor"com.google.dagger:dagger-compiler:${DAGGER_VER}"
}
Test-project on GitHub: ex.dagger
(using IntelliJ 2018.1.4, Gradle 4.7)
ORIG ANSWER
There's a simple workaround using the parent-dir which works fine in IntelliJ 2016.3.4
Production sources directory: ../main
Test sources directory: ../test
Now gradle and IntelliJ will generate the code to the same directories.
Fixed in GitLab project V0.0.2
see also: apt-gradle-plugin issue#35
Hey there everyone I had the same issue and found a clean way of solving this issue.
I am using two libraries that require annotation processing (Lombok and MapStruct).
Also my IntelliJ is 2019.1 (update yours in case it's older) and Gradle 5.2.1.
First let's configure IntelliJ:
Disable Annotaion Processing in Settings, since we're going to delegate everything to Gradle:
Delegeate IDE actions to Gradle:
Last step is to configure your dependencies correctly in Gradle.
Dependencies section in Gradle:
Now you can execute the Build and Run from both command line and IDE.
Cheers!
2019.2.x
Disable annotation processor of intellij
add, build directory in your gradle build.gradle file
then run your gradle task to generate build file classes, example gradle compileJava
File -> project structure -> Modules -> Main Folder || remove exclude and add as source
And project should find all annotation and generated source file. Hope it helps.

IntelliJ, Android and Gradle

I am trying to get my existing Android Project working with gradle and IntelliJ 12.
Previously I had it working with maven but that didn't seem to be so flexible as gradle, and from what I think I got to know is that I need less subfolders.
My Android project is divided into a clean java library (:core) and the actual Application (:android). These two projects are both in my main project folder.
~-+MainProject
|--+core
| L--build.gradle
|--+android
| L--build.gradle
|--build.gradle
L--settings.gradle
I think the ideal solution to get gradle work with this is to treat the (:core) and (:android) project as nested projects, meaning I can simply be with my cmd in MainProject source folder to start the gradle tasks.
However I came up with different problems:
Gradle dependencies are only included in the core project
that means neither in the instrumentatetionTest nor in the main project files are any
directories correctly set as source / test directories
IntelliJ doesn't resolve any classes that I added as dependencies in gradle (AndroidSDK, junit, mockito, those from the :core project)
tried to use the plugin 'idea' but either I used it wrong or it didn't solve the problem
I get duplicate dependency Error for building the APK
must have something to do with junit:4.11 and mockito-core:1.9.5 that I added
what I tried:
deleting the dependencys -> build fails cause some classes of course could'nt be resolved
changing to junit:4.5+ as suggesed in some other thread -> no change at all
Here are the *.gradle configuartions
MainProject:
-- settings.gradle
include ':core', ':android'
-- build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
subprojects {
repositories {
mavenLocal()
maven { url "http://repo.maven.apache.org/maven2" }
}
}
:core
-- build.gradle
apply plugin: 'java'
dependencies {
testCompile 'junit:junit:4.11'
testCompile 'org.mockito:mockito-core:1.9.5'
}
:android
apply plugin: 'android'
repositories {
mavenCentral()
}
dependencies {
compile project(":core")
compile 'com.google.android:android:4.1.1.4'
instrumentTestCompile 'junit:junit:4.11'
instrumentTestCompile 'org.mockito:mockito-core:1.9.5'
instrumentTestCompile 'com.google.dexmaker:dexmaker:1.0'
instrumentTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
}
/* ... androidSettings
I hope someone could help me with that
MFG Dornathal
Alright, so you've got the right idea, but there are a few changes you still need.
Your root build.gradle file should be as follows:
subprojects {
repositories {
mavenCentral()
}
}
You only need to include mavenLocal() if you are using a locally installed repo. Most people don't, and nothing in your project indicates that you need one.
mavenCentral() can be used to replace to maven URL you were using.
We only need to modify the buildscript for the android project, so we should localize that to the android project's build.gradle.
Your settings.gradle and your build.gradle for the core project are good.
Your build.gradle for the android project however, needs some changes:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
dependencies {
compile project(":core")
instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
}
By including the android plugin, we link directly to the installed SDK. This means we no longer need to include the android dependency: compile 'com.google.android:android:4.1.1.4'.
We don't need to include junit. It's provided by the SDK, so we'll just use that. One thing to note is that the SDK only includes JUnit 3.
We don't need to include mockito and dexmaker unless we actually use it for the android tests. If it's only being used for the tests on the java library, we don't need it here.
To answer your questions:
I'm not sure what you're asking here. It might help if you should your project structure including the directories in which you have files and such.
Your hunch is correct. Hamcrest, which provides matchers for tests, made a breaking change to their API between versions 1.1 and 1.3. JUnit 4.11 has a dependency on Hamcrest 1.3. Mockito 1.9.5 however, depends on Hamcrest 1.1. So when both are included, the 1.3 overrides the 1.1 & Mockito no longer works. Reverting to JUnit 4.5 is also a problem. Junit 4.5 includes the Hamcrest 1.1 jar as a file rather than as a dependency in the POM. So this will cause issues when we have 2 versions of the same file. JUnit 4.10 is the way you want to go here. This has the dependency on Hamcrest 1.1 and includes it in the POM instead of as a file. Win win! I've had issues with this too, and the best way for me to figure it out was to just look at the POM files on Maven Central and see what they tell me.
One final note. Intellij 12 cannot handle Gradle Multi-project builds. You need to switch to Android Studio or Intellij 13 for that.

IntelliJ IDEA gradle project setup

What is the best procedure for beginning a new Gradle project in IntelliJ IDEA 12.1.3?
I created a skeleton build.gradle file with the idea plugin to generate the project files:
apply plugin: 'java'
apply plugin: 'idea'
task wrapper(type: Wrapper) {
gradleVersion = '1.6'
}
When I open the new project IntelliJ complains that the Groovy SDK is not configured for module:
After configuring the Groovy SDK I get Java inspection issues in the build file:
Am I doing something wrong or is this normal for a Gradle based project in IDEA? Should I just disable inspection?
UPDATE
I was able to import a skeleton project and IDEA automatically configured everything properly. However I am still receiving Java inspection errors in build.gradle as shown above.
If you use Gradle's idea task to generate project files, this is normal, as there is no way to tell IDEA what the class path of the build script itself is. If you instead use IDEA's Gradle integration ("Import from Gradle model"), this problem doesn't exist.
This question was asked anout a year ago for IDEA 12, and at that time the Gradle support was still... let's say "in progress". In the meantime IDEA 13 is out, and the Gradle support plugin has improved dramatically. See this (short) video for the current capabilities: https://m.youtube.com/watch?v=3Euo6xzCwY4 It isn't a stupid menu walkthrough, it is a concrete example.

Compiling LESS into CSS with Gradle without installing a plug-in

This may seem like an odd question. I want to compile LESS into CSS without installing a plug-in into my local gradle. There are several gradle plug-ins out there that compile LESS into CSS, which is great, but I would like to compile and use the plug-ins at runtime rather than install them prior.
Is this possible? If there was a standard plug-in like for CoffeeScript, it would be no big deal and easy, but there isn't one for LESS. I'm rather new to Gradle, so I'm unsure of how to move forward. The obvious solution is to bloody install the plug-in, but given a constraint that I can't, is it possible to compile/use it at runtime?
https://github.com/koenongena/lesscss-gradle-plugin
https://github.com/skhome/gradle-less-plugin
https://github.com/msgilligan/gradle-lesscss-plugin
In most cases you don't install plugins into your Gradle installation. Rather, you declare the usage of the plugin as part of your build.gradle. At build runtime, it then resolves any plugins that are needed for your build script, loads them, and then runs the build. The particular plugins you listed are a bit unusual in that (as far as I can tell) they haven't yet been published in a publicly accessible Maven repository (such as Maven Central or Bintray). After a quick search, I found one that appears to be in Maven Central:
https://github.com/obecker/gradle-lesscss-plugin
To use it, you don't need to install anything ahead of time. Instead, you declare it in your build.gradle like this:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'de.obqo.gradle:gradle-lesscss-plugin:1.0-1.3.3'
}
}
apply plugin: 'lesscss'
If you don't want to use a plugin, you can pretty easily compile LESS files in Gradle without using any plugin at all. That's because the Gradle plugin architecture builds on exactly the same DSL and deep API as you use in build scripts. The main difference is one of intent; a plugin has been packaged in a way that is intended for re-use in other projects.
The bare minimum needed is access to a library that performs LESS compilation, and a declaration of a task that uses it. Here's a quick example using lesscss-java. It only compiles a single LESS file, but it should be easy to extend for whatever your requirements are.
build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.lesscss:lesscss:1.3.0"
}
}
task lessCompile << {
def compiler = new org.lesscss.LessCompiler()
compiler.compile(file("some.less"), file("some.css"))
}
some.less:
#mainColor: black;
body {
background-color: #mainColor;
}
After running gradle lessCompile, the result is some.css:
body {
background-color: #000000;
}