Archive

Posts Tagged ‘buildSrc’

Gradle and buildSrc and eclipse

I have been playing round with gradle and grails v3, there are a couple of things you need to know about gradle and eclipse. Especially if your going to write your extensions for gradle tasks etc.

one when you create a default gradle project in eclipse it doesn’t automatically build a buildSrc directory for you. But if you add one, gradle recognises this directory and tries to build the groovy/java files you might provide.

Moreover eclipse doesn’t recognise any such directory by itself and so the source code validation etc won’t really work. This is a bother if your want to use the IDE as your natural environment, which most do i suspect.

the default file structure you need to add is buildSrc/src/main/groovy or buildSrc/src/main/java respectively. Whilst gradle will build code in these folders, the IDE will treat this as a standard non source folder structure by default.

so if you try and add a class – it does what the IDE normally does and takes your class and the package and creates the file under the standard /src/main/groovy. I then had to move the it from there to the buildSrc sub directory.

The fix for this is to edit your build.gradle and explicitly add the buildSrc tree to the source sets and refresh all your dependencies (right click your project in explorer, and select gradle/refresh dependencies

sourceSets {
	main {
		java {
			srcDir 'src/main/java'
			srcDir 'src/main/groovy'
			srcDir 'buildSrc/src/main/java'
			srcDir 'buildSrc/src/main/groovy'
		}
		resources {
			srcDir 'src/resources'
			srcDir 'buildSrc/src/resources'
		}
	}
}

This will add the directory as a source folder in the project for you, and you can now create classes explicitly in these the new buildSrc folders.

Gradle automatically applies a default ‘build.gradle’ for the :buildSrc project if you don’t provide one which assumes the following defaults for you

apply plugin: 'groovy'
dependencies {
    compile gradleApi()
    compile localGroovy()
}

if you require additional flexibility you can provide your own in buildSrc/buildGradle, which is additive to this default, for example you might add

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.11'
}

see section 60 – Organising build logic in the user guide.

However, this not all you have to do. As your going to add your plugin or code in buildSrc you need to import the gradle api classes. like this for a simple dummy class

 
package com.softwood.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

class WillsTask extends DefaultTask {
	
	WillsTask () {
		group = 'Wills tasks'

		description = "one of wills tasks"
	}
	
	@TaskAction
	void start () {
		println "hello from Wills task"
	}

}

as the in buildSrc/src/main/groovy is now a source folder this throws allsort of warnings about not seeing the imports, (gradle my apply a default for you – but the IDE wont recognise that). So you have to go back to the build.gradle and add a compile dependency, like this

dependencies {
	compile gradleApi()
...
[/sourecode]

and refresh your dependencies again.  This gets the missing classes and adds them to your eclipse library 'Gradle Dependencies'

your buildSrc tree should now compile with no warnings and you can import your task definitions and use them in your build.gradle like this


import com.softwood.tasks.WillsTask

apply plugin: 'groovy'
apply plugin: 'eclipse'

....
task will (type : WillsTask) {
	doLast() {
		println "hello will"
	}
}

This now seems to work fine except that your main project dependencies now includes the gradleApi() classes. I haven’t figured how to setup dependencies just for the :buildSrc project and no other and keep them separated from the normal stuff in your project

within your build.gradle you can include a buildscript closure like this


buildscript {
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath gradleApi()
		classpath localGroovy()
		
	}
}

to add library dependencies to your :buildSrc classpath, in the above i’ve added the gradleApi() for example and the local groovy for the build (same as the implicit defaults). This works – but if the remove the ‘compile gradleApi()’ from your main dependencies your buildSrc folder will show failure to compile (as you have removed the libraries from ‘Gradle Dependencies’). But if you run the task ‘will’ it will all work.

I think this a deficiency with the interaction with eclipse and i need to query stack overflow/post a feature to get that resolved.

Advertisements
Categories: gradle Tags: , ,
%d bloggers like this: