Can a standalone gradle plugin export a custom task type? - gradle

I have a standalone Gradle plugin that includes a custom task type:
gradle-conventions/build.gradle
plugins {
id 'groovy-gradle-plugin'
id 'maven-publish'
}
group = 'com.example'
version = '1.0'
publishing {
repositories {
maven {
url = uri('/path/to/repo')
}
}
}
gradle-conventions/src/main/groovy/com.example.my-conventions.gradle
abstract class CustomTask extends DefaultTask {
#TaskAction
def hello() {
println "hello"
}
}
I can consume the plugin from another project, but how can I register a CustomTask? Something like this:
project/build.gradle
plugins {
id 'com.example.my-conventions' version '1.0'
}
// how do I reference CustomTask here?
tasks.register('myCustomTask', com.example.CustomTask) {
// ...
}
Is it possible to export a custom task from a custom plugin? Or must I consume custom tasks using the buildscript mechanism?

Having inspected gradle-conventions-1.0.jar, it seems that the custom task class belongs to the default package, so I can register the task as follows:
project/build.gradle
plugins {
id 'com.example.my-conventions' version '1.0'
}
tasks.register('myCustomTask', CustomTask) {
// ...
}
But this only works com.example.my-conventions.gradle contains groovy code besides the class itself, otherwise I get the error:
An exception occurred applying plugin request [id: 'com.example.my-conventions', version: '1.0']
> Failed to apply plugin 'com.example.my-conventions'.
> java.lang.ClassNotFoundException: precompiled_ComExampleMyConventions
This approach avoids relying on the buildscript mechanism (which is not recommended in the Gradle documentation).

Related

How to include transiant depedency of springboot inside fabric mod

I want to use spring boot inside fabric mod. And it works while I'm runing my minecraft server with gradlew.bat runServer command. But when I'm using gradlew.bat build and put the production jar inside a real server I got no class deff found error. Like that :
java.lang.RuntimeException: Could not execute entrypoint stage 'server' due to errors, provided by 'litopia_services'!
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
at fr.litopia.services.LitopiaServices.onInitializeServer(LitopiaServices.java:23) ~[litopia-services-1.0.0.jar:?]
And it's seems leagite cause inside the jar that gradle build there is'nt spring boot transiant depencency.
So to prevent this issue I have to use api insted of include or implement include but none of that have work actually my build.gradle looks like that :
plugins {
id 'fabric-loom' version '0.11-SNAPSHOT'
id 'org.springframework.boot' version '2.5.14'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
maven { url 'https://jitpack.io' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://mvnrepository.com/artifac' }
maven { url 'https://zoidberg.ukp.informatik.tu-darmstadt.de/artifactory/public-releases' }
maven { url 'https://maven.terraformersmc.com/releases' }
mavenCentral()
}
configurations {
springBom
compileOnly.extendsFrom(springBom)
annotationProcessor.extendsFrom(springBom)
implementation.extendsFrom(springBom)
all {
// We need to use fabric implementation of log4j
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
// Spring boot dependencies
springBom enforcedPlatform('org.springframework.boot:spring-boot-dependencies:2.5.14')
api include('org.springframework.boot:spring-boot-starter')
implementation include('org.springframework.boot:spring-boot-dependencies:2.5.14')
implementation include('org.springframework.boot:spring-boot-starter-web')
implementation include('org.springframework.boot:spring-boot-starter-websocket')
// OpenAPI swagger
implementation include('org.springdoc:springdoc-openapi-ui:1.6.13')
// Spring discord api
implementation include('com.discord4j:discord4j-core:3.2.3')
}
processResources {
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
}
}
tasks.withType(JavaCompile).configureEach {
it.options.release = 17
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
}
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
}
}

Custom plugin: Maven-Publish plugin - add default publication if there is no defined in build.gradle

I am building a custom plugin. I would like to add a Java publication if there is no defined in build.gradle file.
This is my current code:
project.afterEvaluate {
project.plugins.withType<MavenPublishPlugin> {
configure<PublishingExtension> {
if (publications.isEmpty()) {
project.logger.info("Publish is empty, creating MavenPublish - java publication")
defineJavaPublication(this)
}
}
}
}
I had to use project.afterEvalute to get it working. Is there some better way to do this? Project.afterEvaluate is marked as deprecated - what should I use instead?

Custom task type not found when importing Gradle plugin

I am facing the following conundrum for which I spent a great deal of time trying to resolve with no success so far. I have a custom Gradle plugin whose job is to start a process and run it in the background.
My code plugin code is the following:
public class TaskSpawnerPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('spawnTask', type: TaskSpawner)
}
}
And this is the task in question:
public class TaskSpawner extends DefaultTask {
#Input
String command
#Input
String ready
#Input
String workDir = '.'
TaskSpawner() {
description = 'Given a Unix like cmd, this will start it and let it run on the background'
}
#TaskAction
public void spawn() {
getLogger().quiet "Attempting to run provided command $command"
if (!(command && ready)) {
throw new GradleException("Please make sure that both the command and ready check are provided!")
}
waitFor(createProcess(workDir, command))
}
private def waitFor(Process process) {
new BufferedReader(new InputStreamReader(process.getInputStream())).withCloseable {
reader ->
def line
while ((line = reader.readLine()) != null) {
getLogger().quiet line
if (line.contains(ready)) {
getLogger().quiet "$command is ready"
break
}
}
}
}
private def static createProcess(String directory, String command) {
new ProcessBuilder(command.split(' '))
.redirectErrorStream(true)
.directory(Paths.get(directory).toFile())
.redirectError(ProcessBuilder.Redirect.INHERIT)
.redirectInput(ProcessBuilder.Redirect.INHERIT)
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.start()
}
}
The code resides under a package structure that has following package name
fts.gradle
My build script looks like this:
plugins {
id 'java-gradle-plugin'
id 'groovy'
id 'maven-publish'
}
group = 'fts.gradle'
version = '0.3'
repositories {
jcenter()
}
dependencies {
compile gradleApi()
compile localGroovy()
}
gradlePlugin {
plugins {
greetingsPlugin {
id = 'fts.gradle.taskspawn'
implementationClass = 'fts.gradle.TaskSpawnerPlugin'
}
}
}
I build my plugin normally and deploy it on a locally hosted artifactory. My problem revolves around how to import it and use it in a project.
For the time being I do the following:
buildscript {
repositories {
maven { url "<maven_url>" }
}
dependencies {
classpath group: 'fts.gradle', name: 'task-spawner', version: '0.3'
}
}
plugins {
id 'java'
id 'application'
id 'eclipse'
}
apply plugin: 'fts.gradle'
And then I attempt to apply it using the following:
But when attempting to refresh the project this action fails:
* What went wrong:
A problem occurred evaluating project ':integration-tests'.
> Could not get unknown property 'TaskSpawner' for project ':integration-tests' of type org.gradle.api.Project.
I have read the documentation and I have tried all the various ways of creating and importing a plugin as a standalone jar but so far I've unsuccessful.
Can anyone please shed some light here? This has been driving nuts for the past days.
Note, for reference the Gradle version I use it 5.6.2

How to lazily get main sourceSets in Gradle

I need to configure sources jar for all of my subprojects. I have the following subprojects configuration defined:
subprojects {
apply(plugin = "java-library")
val sourcesJar = tasks.registering(Jar::class) {
archiveClassifier.set("sources")
from(the<SourceSetContainer>().named("main").get().allJava)
}
tasks.named("assemble") {
dependsOn(sourcesJar)
}
}
When I try to run ./gradlew tasks I receive an exception in my subproject saying that:
Extension of type 'SourceSetContainer' does not exist. Currently registered extension types: [ExtraPropertiesExtension]
My assumption is that the access to get() method of the extension causes problems but without that I cannot refer to the allJava sources that I need. So how to achieve desired result by using configuration avoidance API?
Running on Gradle 5.2.1 with Kotlin DSL.
I found working solution. The problem is that when you call the<T>() function it is taken from the Task type which is why it complains about absent extension. The solution is to call the<T>() function on project instance like this:
subprojects {
apply {
plugin<JavaLibraryPlugin>()
}
val sourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources")
from(
// take extension from project instance
project.the<SourceSetContainer>().named("main").get().allJava
)
}
}

gradle use class from maven build

Hy i have written a java Library an I want to use it in the Gradle script. What I have done:
Added the repository:
repositories {
maven {
url "../Projectname/maven_repo"
}
}
Added the Dependency:
dependencies {
classpath group: 'my.group.id', name: 'Projectname', version: '0.0.1-SNAPSHOT'
}
And now i want to use the Library in a Task:
task myTask () {
def file = file("${buildDir}/ws/.metadata/.log")
def htmlParser = new my.package.Projectname()
}
Now I always get the exception on the Buildserver that he isn’t able to find the class.
Thx for the Help.

Resources