In gradle, can I read extra property of subproject from root project? - android-gradle-plugin

In my root project, I'd like to config "apt" for all my projects like code below. But I don't know how to get package name from subproject?
allprojects {
apply plugin: 'android-apt'
apt {
arguments {
androidManifestFile variant.outputs[0].processResources.manifestFile
resourcePackageName '?????'
}
}
}

Related

Apply local jar-plugin without using maven

I'd like to load my custom plugin from a local jar. The jar file compiles fine and when I check it, the manifest and the plugin class are there.
gradlePlugin {
plugins {
create("asdf") { // <-- I really call it "asdf" in the kts script
id = "asdf"
implementationClass = "pluginTest.TestPlugin"
version = "1.4.0"
}
}
}
The plugin doesn't do anything useful yet as it should be a proof-of-concept to make sure it actually works at all:
class TestPlugin : Plugin<Project> {
override fun apply(project: Project) {
println("Hallo TestPlugin!")
}
}
I then try to use it like this in another project:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath(files("..\\..\\path\\to\\pluginTest.jar"))
}
}
plugins {
id("asdf") version "1.4.0"
}
but it keeps telling me that:
Plugin [id: 'asdf', version: '1.4.0'] was not found in any of the following sources:
What am I missing here? I use Gradle v6.5.
When you have the plugin jar on the classpath, you can't have a version number in the plugin application. I guess this is because you can't have multiple jars with different versions on the classpath in the first place, so specifying a version here doesn't make any sense (except perhaps to validate that you are using the correct one). This won't fix the problem, but it is a start.
To be honest, I don't know why your approach still won't work. The buildscript block is supposed to set up dependencies for that particular script, and that should make the plugin visible to it. It doesn't for some reason.
Perhaps this is a bug or perhaps this is just an undocumented limitation on the use of the plugin {} block. Maybe you could ask over at the Gradle forums or create an issue for it. However, there are workarounds that don't involve publishing to a (local) Maven repository, which I agree can be a bit annoying.
If you use "apply from" instead of "plugins {}", it works. For some reason, the former can see the buildscript classpath whereas the latter can't:
// build.gradle (Groovy DSL)
buildscript {
dependencies {
classpath(files("..\\..\\path\\to\\pluginTest.jar"))
}
}
apply from: "asdf"
Alternatively, move the buildscript plugin from the build.gradle file to the settings.gradle file. This makes is available to the entire build classpath and will make it work with the plugin block:
// settings.gradle (Groovy DSL):
buildscript {
dependencies {
classpath(files("..\\..\\path\\to\\pluginTest.jar"))
}
}
// build.gradle (Groovy DSL)
plugins {
id("asdf")
}
Lastly, just in case you haven't considered it already, you may be able to add the plugin as a composite build. This will create a source dependency to the plugin and has the advantage that transitive dependencies will be carried over (the ones you put in the plugin's own dependency block) and that it will be built automatically if not up-to-date. I use this approach for integration testing my plugins and also sometimes to apply them to my other real projects to test them in a bigger setting before publishing new versions.
Do that with either:
// settings.gradle (Groovy DSL):
includeBuild("..\\..\\path\\to\\plugin")
// build.gradle (Groovy DSL):
plugins {
id("asdf")
}
Or without hard-coding it in the build (so you can dynamically switch between local and published versions):
// build.gradle (Groovy DSL):
plugins {
id("asdf") version "1.4.0" // Version is optional (will be ignored when the command line switch below)
}
// Run with:
./gradlew --include-build "..\\..\\path\\to\\plugin" build
With #BjørnVester's answer I figured it out!
You need to put the buildscript in settings.gradle.kts as it doesn't get executed in the build.gradle.kts even when placed before plugins.
buildscript {
repositories {
flatDir {
dirs("..\\reusable-kotlin\\build\\libs") // <-- folder with jars
}
}
dependencies {
classpath("com.hedev.kotlin:reusable-kotlin:1.4.0")
}
}
But there's a catch! You must use the file-name of the jar in the classpath's name identifier that goes like this:
group:file-name:version
The file gradle will look for will be file-name-version.jar or file-name.jar which you'll see in the error message if you make a mistake (I added the _ on purpose to trigger the error):
Could not resolve all artifacts for configuration 'classpath'.
Could not find com.hedev.kotlin:reusable-kotlin_:1.4.0. Searched in the following locations:
- file:/C:/some/path/reusable-kotlin/build/libs/reusable-kotlin_-1.4.0.jar
- file:/C:/some/path/reusable-kotlin/build/libs/reusable-kotlin_.jar
In order for this to work I also had to add the group property to the plugin itself:
gradlePlugin {
plugins {
create("asdf") {
id = "asdf"
implementationClass = "com.hedev.kotlin.gradle.TestPlugin"
version = "1.4.0"
group = "com.hedev.kotlin"
}
}
}
Finally you can apply it in build.gradle.kts with (no version here):
plugins {
id("asdf")
}

Setting up gradle and project structure for Kotlin Multiplatform project

I want to build a CLI tool with Kotlin Multiplatform which runs on Linux, Macos and Windows.
But I am struggling with setting up my build.gradle and my project structure. I am using IntelliJ IDEA 2020.1 and created my basic project with File -> New -> Project -> Kotlin / Native | Gradle
Currently I am looking through guides from kotlinlang.org but I am more falling then achieving something.
So far my build.gradle looks as follows:
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.3.72'
}
repositories {
mavenCentral()
}
kotlin {
// For ARM, should be changed to iosArm32 or iosArm64
// For Linux, should be changed to e.g. linuxX64
// For MacOS, should be changed to e.g. macosX64
// For Windows, should be changed to e.g. mingwX64
linuxX64("linux") {
}
mingwX64("mingw") {
}
macosX64("macos") {
binaries {
executable {
// Change to specify fully qualified name of your application's entry point:
entryPoint = 'sample.main'
// Specify command-line arguments, if necessary:
runTask?.args('')
}
}
}
sourceSets {
commonMain {
kotlin.srcDir('src/main')
resources.srcDir('src/res')
dependencies {
implementation kotlin('stdlib-common')
implementation "com.github.ajalt:clikt-multiplatform:2.7.0"
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
macosX64().compilations.test.defaultSourceSet {
dependsOn commonMain
}
// Note: To enable common source sets please comment out
'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
macosMain {
}
macosTest {
}
}
}
wrapper {
gradleVersion = "6.4.1"
distributionType = "ALL"
}
And my project structure is still basic:
Project structure
Formerly I only worked on Android Projects with Kotlin, and I guess I am spoiled with gradle as Android generates the most basic stuff and everything is working without doing that much.
I understand that I need to create packages like linuxMain and mingwMain, but where to I put common sourcesets? I tried to create a package called commonMain, but it won't even let me create Kotlin files in that package.
When I am finished I want to have (in the best case) one common source set and one entry point for all my targets. Is this even possible?
As far as I can see, you specify your commonMain source set's source locations as /src/main/. By default, it's usually set onto /src/commonMain/kotlin/. So if you will remove those srcDir settings and create a .kt file in your /src/commonMain/kotlin/ folder, everything should work fine. Also, I hope you have removed 'kotlin.import.noCommonSourceSets' property from your gradle.properties as your script recommended.

Setting Up a Multiplatform Project

considering Kotlin 1.2 introduced kotlin-platform-common I'm trying to build my first common .class file, so I did the below:
main.kt:
package hello
fun main() {
println("kotlin!")
}
gradle.build:
group 'h'
version 'prn'
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin-platform-common'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
}
sourceSets {
main.kotlin.srcDirs += 'src/kotlin'
main.resources.srcDirs += 'src/resources'
}
jar {
manifest {
attributes 'Main-Class': 'hello.MainKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
Then I run gradle build
Q1- I coud not find any .class file generated? how to get it generated and where should I find it?
Q2- I got a .jar file generated, but once I tried to run it, I got an error:
Error: Could not find or load main class hello.MainKt
I tried to run it using the below 2 option, but got the same error for bot:
Option 1:
kotlin -cp <filename>.jar hello.MainKt
Option 2:
java -jar <filename>.jar
Project structure, and errors are as in this pic below:
With Kotlin 1.2, common modules don't generate binaries (like .class files), only metadata files. This is true even if you don't use the expect keyword anywhere.
So you have to create another module which includes something like this:
apply plugin: 'kotlin-platform-jvm'
The JVM modules will also need an expectedBy entry in dependencies for your common module. Plus you'll probably want a corresponding JS module of course.
It's probably best to let IntelliJ create the whole multiplatform project for you and then edit the Gradle files to suit, but this page lists the manual steps: https://kotlinlang.org/docs/reference/multiplatform.html#setting-up-a-multiplatform-project

spring-boot fails to load liquibase change on gradle build

I am using Spring-boot 1.1.1.RELEASE and I have an H2 database that is created at startup. When I run my main class from IntelliJ, all works well. When I run with "gradle build test" I get errors on my integration tests:
Caused by: java.lang.IllegalStateException: Cannot find changelog location: class path resource [db/changelog/db.changelog-master.yaml] (please add changelog or check your Liquibase configuration)
at org.springframework.util.Assert.state(Assert.java:385)
at org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration$LiquibaseConfiguration.checkChangelogExists(LiquibaseAutoConfiguration.java:80)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
Here is my gradle file:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'maven'
project.ext {
springBootVersion = '1.1.1.RELEASE'
}
buildscript {
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url "http://repo.spring.io/libs-milestone" }
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.1.RELEASE")
}
}
jar {
baseName = 'my-app'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-milestone" }
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url "http://repo.spring.io/snapshot" }
maven { url 'http://repo.spring.io/milestone' }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compile("org.springframework.boot:spring-boot:1.0.1.RELEASE")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
compile("org.springframework.security:spring-security-web:4.0.0.M1")
compile("org.springframework.security:spring-security-config:4.0.0.M1")
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:2.1.1.RELEASE')
compile("org.springframework:spring-orm:4.0.0.RC1")
compile("org.hibernate:hibernate-core:4.3.4.Final")
compile("org.hibernate:hibernate-entitymanager:4.3.4.Final")
compile("org.hibernate:hibernate-validator")
compile("com.h2database:h2:1.3.172")
compile("joda-time:joda-time:2.3")
compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
compile('org.codehaus.groovy:groovy-all:2.2.1')
compile('org.jadira.usertype:usertype.jodatime:2.0.1')
compile("org.liquibase:liquibase-core")
testCompile('org.spockframework:spock-core:1.0-groovy-2.0-SNAPSHOT') {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile('org.spockframework:spock-spring:1.0-groovy-2.0-SNAPSHOT') {
exclude group: 'org.spockframework', module: 'spock-core'
exclude group: 'org.spockframework', module: 'spring-beans'
exclude group: 'org.spockframework', module: 'spring-test'
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile("org.springframework.boot:spring-boot-starter-test:$springBootVersion")
testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
testCompile("junit:junit")
}
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
I have in both src/main/resources and src/test/resources an application.properties file that contains the following entry:
liquibase.changeLog=classpath:db/changelog/db.changelog-master.xml
And then in both src/main/resources/db/changelog and src/test/resources/db/changelog I have a db.changelog-master.xml When I build the project, I see that build/resources/test and build/resources/main have the application.properties, db/changelog/db.changelog-master.xml there.
This would appear to be a classpath issue, since it works from within IntelliJ and not the commandline. Can anyone suggest what I might be doing wrong here?
I wanted to add my fix here (even though my build is Maven). My application.properties was in my root directory, but it would not find my db.changelog.xml classpath as directed from the root directory. It needed the classpath to be from my /resources directory. Maybe I have my application.properties in an unconventional location, but I thought it was to be put in the root directory.
My Fix
Though the actual path from my application.properties is this:
liquibase.change-log=classpath:/src/main/resources/liquibase/db.changelog.xml
It needed this path to find it:
liquibase.change-log=classpath:/liquibase/db.changelog.xml
I can see spock on the test classpath, so probably it's not using the right test context loader still (I wish they'd fix that). You need to add the loader or an initializer manually to your #ContextConfiguration. Docs here.

Android Studio : Config Gradle file for library project

I have an Android Project, and I want to create a sub-library (just another Android Project) as library for this one.
Here is my Structure:
Project/
settings.gradle
build.gradle
/ProjectA
/ProjectA/build.gradle
/ProjectA/libs
/ProjectA/libs/ProjectB
/ProjectA/libs/ProjectB/build.gradle
ProjectA is my main project. I do as following. In setting.gradle. I add:
include ':ProjectA'
include ':ProjectA:libs:ProjectB'
after that. I copy all information of ProjectA/build.gradle into ProjectB/build.gradle content of file is:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.1"
defaultConfig {
minSdkVersion 9
targetSdkVersion 18
}
buildTypes {
debug {
packageNameSuffix ".debug"
}
}
}
After that, I change ProjectA/build.gradle. Add this line: compile projects(:libs:projectB) to dependencies. After that I receive error :
Project with path ':libs:ProjectB' could not be found in project ':ProjectA'
Please help me how to configure for multiply project in Android Studio.
Thanks :)
Either of these will work:
compile project(':ProjectA:libs:ProjectB')
or
compile project('libs:ProjectB')
The leading colon is like a leading slash on a filesystem path: it makes it an absolute path, starting with the project root. Without a leading colon, it's relative to the module's root.
Having said all that, your project structure is complex. Does ProjectB really need to be contained in ProjectA? Would this work better instead?
Project/
settings.gradle
build.gradle
/ProjectA
/ProjectA/build.gradle
/ProjectB
/ProjectB/build.gradle
I have solution for my problem. Sadly, I see no full tutorial for my problem. And by many mistakes, I can try it by hand.I have try a way : here is my short tutorial. Hope help someone here.
Short Description : I will add a SlidingMenu library to my project. This library is special because :
it's an Eclipse-type project (means : has a slide difference compare to android project create by Android Studio or Intellij IDEA),
so you must have a step config by hand. If this's a normal library
create by Android Studio, you can remove mapping by hand step in below
Gradle file.
It uses v4 support library. Often, your app uses this library too. So, if you compile both same two libries in same project. You will
meet error. So, there is a way : using Android Repository to synchronized. You will not meet exception that two same libraries in one project.
You create a libs folder inside your app. After that, copy whole project library to this folder. For example, I'm using SlidingMenu. After that, you create gradle.build with following content. ( I have added some comments, for easier to follow)
// SlidingMenu is an Eclipse project. so its structure is different. and must config by hand.
// script to decide which gradle version will use for maven
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
// because this is a android library. we change : apply plugin: 'android' to
apply plugin: 'android-library'
// Base Project includes "Support Library v4 jar to its project
// 1. If Not Compile it : this library project cannot compile because missing libraries
// 2. Cannot delete jar file in libs folder. Because its code depend on this libs. Delete jar file turn out that cannot see class file
// 3. My Solution : Use Gradle Repository. By use Gradle Repository, this library will be synchronized between two projects.
// So, just one instance could be used for both project.
dependencies {
compile 'com.android.support:support-v4:19.0.0'
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.1"
// Mapping phrase : use if this library is Eclipse-base project
// modify link because this project is from Eclipse Project
// not from normal gradle Project. So project structure is different. Cannot make default
// Config by hand, get Gradle knows which part for each type of directory
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}
Here is main gradle file :
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
// this is main project : so we use apply plugin : 'android'
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.1"
defaultConfig {
minSdkVersion 9
targetSdkVersion 18
}
}
dependencies {
compile 'com.android.support:appcompat-v7:19.0.0'
compile 'com.android.support:support-v4:18.0.0'
// compile project SlidingMenu
compile project(':Hop Am Chuan:libs:SlidingMenu')
// add this line just for demonstration. you can use or remove it.
// compile files('libs/google-gson-2.2.4/gson-2.2.4.jar')
}
Hope this help :)