how to extract the plugin declarations to another file? - gradle

Using Gradle 7.5.1, I would like to declare all my plugins in one file, and then apply from that file in my main build.gradle.kts. Something like this:
./gradle/plugins.gradle.kts:
plugins {
id("net.researchgate.release") version "3.0.2" apply false
id("com.google.cloud.artifactregistry.gradle-plugin") version "2.1.5" apply false
}
and then in build.gradle.kts:
apply(from = "${project.projectDir.path}/gradle/plugins.gradle.kts")
allprojects {
apply(plugin = "net.researchgage.release")
apply(plugin = "com.google.cloud.artifactregistry.gradle-plugin")
... etc.
A bit of background, I'm trying to extract all common build components shared by different repositories, so I can git submodule those shared scripts across the board. The goal is to factor out all the common stuff in a centralized repository that can be reused.
The error message is as follows:
The plugins {} block must not be used here. If you need to apply a plugin imperatively, please use apply() or apply(plugin = "id") instead

OK, found it. First, the plugins.gradle.kts must be applied from settings.gradle.kts. Second, this works (main gradle build script):
plugins {
id("net.researchgate.release")
id("com.google.cloud.artifactregistry.gradle-plugin")
}
allprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "maven-publish")
... etc.
But this doesn't:
allprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "maven-publish")
apply(plugin = "net.researchgate.release")
apply(plugin = "com.google.cloud.artifactregistry.gradle-plugin")
... etc.
No idea why...

Related

How to setup a multi-module gradle project with Quarkus?

A multi-module gradle project with the Quarkus plugin applied in the root build.gradle.kts fails at the :quarkusBuild step with a NoSuchElementException:
> Task :quarkusBuild FAILED
building quarkus jar
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':quarkusBuild'.
> java.util.NoSuchElementException
The root build.gradle.kts is like so:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.72"
id("io.quarkus") version "1.9.1.Final"
}
group = "org.example"
version = "1.0-SNAPSHOT"
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply {
plugin("kotlin")
}
dependencies {
implementation(kotlin("stdlib"))
}
}
However move the line id("io.quarkus") version "1.9.1.Final" to the sub projects' build.gradle.kts and the build succeeds. It seems that the quarkus build step is run where the plugin is declared, rather than where it is actually applied.
Ideally I want to declare the plugin once in the root, then apply it to subprojects only, not have it execute against the root project, where there's obviously nothing to build.
Any ideas?
You need to add apply false
plugins {
kotlin("jvm") version "1.3.72" apply false
id("io.quarkus") version "1.9.1.Final" apply false
}
https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
Your build also assumes that every sub-module will be a Kotlin module which may or may not be true. You can do something a little more like this to apply specific configurations to specific tasks:
subprojects { subproject ->
subproject.tasks.withType(JavaCompile).configureEach {
sourceCompatibility = JavaVersion.VERSION_11
}
subproject.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
}
}

Running PMD with gradle without compiling

I need to integrate PMD into the build process, so I created a file, 'check.gradle' under a separate directory and added it to the build.gradle which is a main file for the build process.
build.gradle
buildscript {
ext {
sbDir = "${projectDir.parent}"
}
repositories {
mavenCentral()
jcenter()
}
}
allprojects {
repositories {
mavenCentral() // maven { url: 'http://jcenter.bintray.com' }
}
}
apply from: file('../build/pmd/check.gradle')
check.gradle
subprojects {
apply plugin: 'pmd'
pmd {
consoleOutput = true
toolVersion = "6.21.0"
reportsDir = file("pmd/reports")
ruleSets = ["../build/pmd/MyRuleSet.xml"]
ignoreFailures = true
}
}
The code base is written in Java. The problem is that I want to run it before compile happens or i don't want to run it separately as a simple task. Our compile task is pretty complicated, cuz it depends on many libraries.
I am running as like this.
gradlew.bat --build-file bundles/build.gradle check
Is there a way to scan all the java source code (we have 200 bundles - each bundle is packaged with many java files) without compiling java source code?

How to ignore gradle build of root project for a multi-project Kotlin Spring Boot application?

Background:
I currently have a multi-module (multi-project) application repo. The "root" is not a runnable application. It's merely the source directory where I have a root build.gradle.kts file which holds the dependencies and plugins that are common between all my sub-projects. Each of my sub-projects have their own build.gradle.kts.
So my overall project structure looks sort of like this:
my_root_project
- gradle
- wrapper
- gradle-wrapper.jar
- gradle-wrapper.properties
- gradle.build.kts
- settings.gradle.kts
- my_nested_project_a
- src
- main
- kotlin
- my_nested_project_b
...
Issue:
Every time I run gradle build, I get an error saying:
> Task :bootJar FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootJar'.
> Main class name has not been configured and it could not be resolved
However when I run any one of my sub-projects (e.g. build :my_nested_project_a:build), it builds just fine.
Current Gradle Build Files
Here's what I currently have in the "root" gradle.build.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
group = "com.example"
version = "1.0.0"
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.targetCompatibility = JavaVersion.VERSION_1_8
plugins {
id("org.springframework.boot") version "2.1.8.RELEASE" apply false
id("io.spring.dependency-management") version "1.0.8.RELEASE" apply false
kotlin("jvm") version "1.3.50"
kotlin("plugin.spring") version "1.3.50"
kotlin("plugin.jpa") version "1.3.50"
kotlin("plugin.allopen") version "1.3.50"
}
allprojects {
repositories {
maven(url = "https://my.company.com/repo/with/all/the/stuff/I/need")
}
apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "java")
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
apply(plugin = "org.jetbrains.kotlin.plugin.spring")
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
}
NOTE: I'm using apply false on my plugins because I thought it would keep gradle from trying to find a main class when building using gradle build.
What I'm trying to do:
I have a CI pipeline that I'd like to simply run gradle build which should run the build task for all of the sub-projects. However, in that process, I'd like to ignore running the build for the "root" project or bypass it since it's not a runnable application, and just build the sub-projects.
Any help would be greatly appreciated! :)
If you want to ignore task bootJar,s o add the following configuration.
bootJar {
enabled = false
}
In your root build.gradle.kts, ignore bootJar task, with Kotlin DSL :
import org.springframework.boot.gradle.tasks.bundling.BootJar
tasks.getByName<BootJar>("bootJar") {
enabled = false
}
If you have the plugin applied in allprojects session, you're applying it to the root as well, and since it's the first one resolved in gradle build, you should have the main class configured there.
Alternatively, you can remove the apply(plugin = "org.springframework.boot") line from the root and apply the plugin only to the module that has the main method annotated with #SpringBootApplication, and point the plugin to the main class there.
Say your main class is in my_nested_project_a/src/main/com/example/MainClass.kt.
Your my_nested_project_a/build.gradle.kts should look like:
plugins {
id("org.springframework.boot")
}
springBoot {
mainClassName = "com.example.MainClass"
}
dependencies {
...
}
And you should remove this line from the root build.gradle.kts:
apply(plugin = "org.springframework.boot")
I have a similar setup and question. I replaced allprojects with subprojects and added jar.enabled(false) to the root build.gradle file and it worked.
plugins {
id("java-library")
id('org.jetbrains.kotlin.jvm') version "${kotlinVersion}"
id("com.diffplug.spotless") version "${spotlessVersion}"
id("maven-publish")
}
jar.enabled(false)
subprojects {
apply plugin: "java-library"
apply plugin: "org.jetbrains.kotlin.jvm"
apply plugin: "com.diffplug.spotless"
apply plugin: "maven-publish"
group = GROUP
version = VERSION_NAME
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation("org.junit.jupiter:junit-jupiter:${junitVersion}")
}
publishing {
publications {
library(MavenPublication) {
from components.java
}
}
repositories {
maven {
url "https://gitlab.mhighpoint.com/api/v4/projects/${System.getenv('CI_PROJECT_ID')}/packages/maven"
credentials(HttpHeaderCredentials) {
name = "Job-Token"
value = System.getenv('CI_JOB_TOKEN')
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
spotless {
java {
googleJavaFormat() // googleJavaFormat('1.1') to specify a specific version
}
kotlin {
target '**/src/**/*.kt'
ktlint("0.41.0").userData('disabled_rules': 'no-wildcard-imports,import-ordering')
trimTrailingWhitespace()
indentWithSpaces()
endWithNewline()
}
format 'misc', {
target '**/*.gradle'
trimTrailingWhitespace()
indentWithSpaces() // or spaces. Takes an integer argument if you don't like 4
endWithNewline()
}
}
test {
useJUnitPlatform()
}
jar {
archiveBaseName = "${rootProject.name}-${project.name}"
}
tasks {
assemble.dependsOn(spotlessApply)
}
}

Kotlin DSL: Import a versions.gradle.kts into another build.gradle.kts

I have created a versions.gradle.kts just like that:
object Defines {
const val kotlinVersion = "1.2.61"
const val junitVersion = "5.3.0"
}
Now I want to import and use that files like that:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
group = "io.github.deglans"
version = "0.0.1-SNAPSHOT"
plugins {
application
kotlin("jvm") version Defines.kotlinVersion
}
application {
mainClassName = "io.github.deglans.polishnotation.MainKt"
}
dependencies {
compile(kotlin("stdlib-jdk8"))
testCompile("org.junit.jupiter", "junit-jupiter-api", Defines.junitVersion)
testRuntime("org.junit.jupiter", "junit-jupiter-engine", Defines.junitVersion)
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
How can I do that?
NOTE:
I have already seen this post but it is not exactly that I search...
While I think it should be possible to import another gradle.kts file, I couldn't get it to work properly.
However, I did manage to define my dependencies in a separate Kotlin file in the buildSrc directory.
Create a buildSrc folder in the root of your project (same level as build.gradle.kts)
Add a build.gradle.kts in that buildSrc folder. Here, you need to define the kotlin-dsl plugin. You also need to define the repository where to get the plugin.
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
Create a Kotlin file where you define your dependencies in src/main/kotlin inside the buildSrcfolder. You need to create a normal Kotlin .kt file, not a gradle.kts.
Reimport your Gradle config and you can now use the variables you defined in your Kotlin file created in step #3 in your build.gradle.kts.

Spring Boot Tutorial doesn't work with multi project gradle setup

i get a strange behaviour (at least for me :D) when I switch from the gradle file located in https://spring.io/guides/gs/serving-web-content/ to a multi project gradle file setup.
build.gradle in root directory
//Applied to all projects.
allprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
group = 'de.test.platform'
version = '0.1'
}
subprojects {
//Currently all subprojects are also java projects. If this changes we
//need to move it into the corresponding projects
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
idea {
module {
downloadSources = true
downloadJavadoc = false
}
}
}
idea {
project {
jdkName = '1.8'
languageLevel = '1.8'
}
}
build.gradle in sub directory frontend (thus sub project called :frontend)
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
}
}
apply plugin: 'war'
apply plugin: 'spring-boot'
jar {
baseName = 'crowdio-frontend'
version = '0.1.0'
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("junit:junit")
}
when I run gradle bootRun and navigate to http://localhost:8080/greeting as in the tutorial i get a infinite loop error. If i change the template from greeting.html to hello.html and return hello instead of greeting in the controller greeting() action i get an 404 Error.
The template is stored in project_root/frontend/src/main/resources/templates/greeting.html
It seems like that for whatever Reason spring boot can decide on thymeleaf with the exact structure of the gradle build file like in the tutorial. However if you switch to a multi project setup you need to add
compile("org.thymeleaf:thymeleaf-spring4")
as a dependency.

Resources