Skip to content

Commit 3675cfe

Browse files
committed
Actually allow generation of an entire directory worth of code.
1 parent 5fbf50e commit 3675cfe

File tree

3 files changed

+94
-23
lines changed

3 files changed

+94
-23
lines changed

RELEASENOTES

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
0.5: Initial release
1+
0.5.5: Add an extension to the generate task that allows directory wide generation
2+
of unspecified. files. This is mainly useful for annotation processing.
23

3-
0.5.1: Don't have a hard dependency on kotlin.
4+
0.5.1: Don't have a hard dependency on kotlin.
5+
6+
0.5: Initial release

build.gradle

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@
2222
buildscript {
2323

2424
ext {
25-
if (! rootProject.ext.has('kotlin_version') ) { kotlin_version = '1.0.1-2' }
25+
if (!rootProject.ext.has('kotlin_version')) {
26+
kotlin_version = '1.0.1-2'
27+
}
2628
}
2729
dependencies {
2830
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
2931
}
3032

3133
repositories {
34+
mavenLocal()
3235
jcenter()
3336
maven {
3437
url "https://plugins.gradle.org/m2"
@@ -38,17 +41,18 @@ buildscript {
3841

3942

4043
plugins {
41-
id "com.jfrog.bintray" version "1.6"
4244
id "com.gradle.plugin-publish" version "0.9.4"
45+
id "com.jfrog.bintray" version "1.6"
46+
id 'maven-publish'
4347
}
4448

4549
apply plugin: 'kotlin'
46-
apply plugin: 'maven-publish'
50+
//apply plugin: 'maven-publish'
4751

4852
sourceCompatibility = JavaVersion.VERSION_1_6
4953
targetCompatibility = JavaVersion.VERSION_1_6
5054

51-
version = '0.5.1'
55+
version = '0.5.5'
5256
group = 'net.devrieze'
5357

5458
bintray {
@@ -67,8 +71,8 @@ bintray {
6771
name = project.version
6872
desc = 'Fixed when not using kotlin. Kotlin is now optionally supported.'
6973
released = new Date()
70-
vcsTag = 'v0.5.1'
71-
// attributes = [ 'gradle-plugin': 'net.devrieze.gradlecodegen:' ]
74+
vcsTag = "v$version"
75+
attributes = [ 'gradle-plugin': 'net.devrieze:gradle-codegen:net.devrieze.gradlecodegen' ]
7276
}
7377
}
7478
}
@@ -79,7 +83,7 @@ publishing {
7983
from components.java
8084
groupId group
8185
artifactId 'gradle-codegen'
82-
86+
8387
artifact sourceJar {
8488
classifier "sources"
8589
}
@@ -91,16 +95,18 @@ pluginBundle {
9195
website = 'https://github.com/pdvrieze/gradle-codegen.git'
9296
vcsUrl = 'https://github.com/pdvrieze/gradle-codegen.git'
9397
description = "A plugin to aid with codeGeneration without using buildSrc. It provides an additional generate section to sourceSets. In this section individual files to be generated can be specified. Each sourceset has an accompanying ...generator sourceSet where the actual generator source can live."
94-
tags = [ 'generate', 'codegen', 'code-generation' ]
98+
tags = ['generate', 'codegen', 'code-generation']
99+
95100
plugins {
96101
gradlecodegen {
97102
id = 'net.devrieze.gradlecodegen'
98103
displayName = 'Code generation plugin for gradle'
99104
}
100105
}
106+
101107
mavenCoordinates {
102108
groupId = group
103-
artifactId = "gradle-codegen"
109+
artifactId = "gradle-codegen"
104110
}
105111
}
106112

@@ -109,7 +115,7 @@ dependencies {
109115
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
110116
}
111117

112-
task sourceJar(type:Jar) {
118+
task sourceJar(type: Jar) {
113119
from sourceSets.main.allSource
114120
}
115121

src/main/kotlin/net/devrieze/gradlecodegen/plugin.kt

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ open class GenerateTask: DefaultTask() {
6161

6262
var classpath: FileCollection? = null
6363

64+
val dirGenerator = GenerateDirSpec()
65+
66+
fun dirGenerator(closure: Closure<Any?>?) {
67+
ConfigureUtil.configure(closure, dirGenerator)
68+
}
69+
6470
@Input
6571
internal var container: NamedDomainObjectContainer<GenerateSpec>? = null
6672

@@ -70,17 +76,44 @@ open class GenerateTask: DefaultTask() {
7076
container?.all { spec: GenerateSpec ->
7177
val specClasspath = spec.classpath
7278
if (specClasspath ==null || specClasspath.isEmpty) {
73-
generateSpec(spec, joinedLoader)
79+
generateFile(spec, joinedLoader)
7480
} else {
7581
URLClassLoader(combinedClasspath(spec.classpath)).use { classLoader ->
76-
generateSpec(spec, classLoader)
82+
generateFile(spec, classLoader)
83+
}
84+
}
85+
}
86+
87+
if (dirGenerator.generator!=null) {
88+
val outDir = if (dirGenerator.outputDir ==null) project.file(outputDir) else File(project.file(outputDir),dirGenerator.outputDir)
89+
outDir.mkdirs() // ensure the output directory exists
90+
if (dirGenerator.classpath!=null) {
91+
URLClassLoader(combinedClasspath(dirGenerator.classpath)). use {
92+
generateDir(outDir, it)
7793
}
94+
} else {
95+
generateDir(outDir, joinedLoader)
7896
}
7997
}
98+
8099
}
81100
}
82101

83-
private fun generateSpec(spec: GenerateSpec, classLoader: ClassLoader) {
102+
private fun generateDir(outDir: File, classLoader: ClassLoader) {
103+
val generatorClass = classLoader.loadClass(dirGenerator.generator)
104+
val m = generatorClass.getGenerateDirMethod(dirGenerator.input)
105+
106+
val generatorInst = if (Modifier.isStatic(m.modifiers)) null else generatorClass.newInstance()
107+
if (m.parameterCount==1) {
108+
m.invoke(generatorInst, outDir)
109+
} else {
110+
m.invoke(generatorInst, outDir, dirGenerator.input)
111+
}
112+
113+
}
114+
115+
116+
private fun generateFile(spec: GenerateSpec, classLoader: ClassLoader) {
84117
if (spec.output != null) {
85118
val outFile = File(project.file(outputDir), spec.output)
86119

@@ -92,12 +125,13 @@ open class GenerateTask: DefaultTask() {
92125
if (spec.generator != null) {
93126
val gname = spec.generator
94127
val generatorClass = classLoader.loadClass(gname)
95-
val generatorInst = generatorClass.newInstance()
96128
if (!outFile.isFile) {
97129
outFile.parentFile.mkdirs()
98130
outFile.createNewFile()
99131
}
132+
100133
val m = generatorClass.getGenerateMethod(spec.input)
134+
val generatorInst = if (Modifier.isStatic(m.modifiers)) null else generatorClass.newInstance()
101135
outFile.writer().use { writer ->
102136
if (m.parameterCount == 2) {
103137
m.invoke(generatorInst, writer, spec.input)
@@ -120,7 +154,29 @@ open class GenerateTask: DefaultTask() {
120154
.filter { Appendable::class.java.isAssignableFrom(it.parameterTypes[0]) && it.parameterTypes[0].isAssignableFrom(Writer::class.java) }
121155
.filter { if (it.parameterCount==1) true else it.parameterTypes[1].isInstance(input) }
122156
.singleOrNull() ?: throw NoSuchMethodError("Generators must have a unique public method \"doGenerate(Appendable|Writer, " +
123-
"[Object])\" where the second parameter is optional iff the input is null" )
157+
"[Object])\" where the second parameter is optional iff the input is null. If not a static method," +
158+
"the class must have a noArg constructor" )
159+
}
160+
161+
private fun Class<*>.getGenerateDirMethod(input: Any?):Method {
162+
return methods.asSequence()
163+
.filter { it.name=="doGenerate" }
164+
.filter { Modifier.isPublic(it.modifiers) }
165+
.filter { if (input==null) it.parameterCount in 1..2 else it.parameterCount==2 }
166+
.let {
167+
val candidates = it.toList()
168+
candidates.filter { (File::class.java==it.parameterTypes[0].apply { project.logger.debug("Rejecting $it as the first parameter is not a file") }) }
169+
.filter { if (it.parameterCount==1) true else it.parameterTypes[1].isInstance(input) }
170+
.singleOrNull() ?: throw NoSuchMethodError("""
171+
Generators must have a unique public method "doGenerate(File, [Object])"
172+
where the second parameter is optional iff the input is null. If not a static
173+
method, the class must have a noArg constructor.
174+
175+
Candidates were:
176+
${candidates.joinToString("\n ") { it.toString() }}
177+
""".trimIndent() )
178+
179+
}
124180
}
125181

126182
private fun combinedClasspath(others: FileCollection?): Array<out URL>? {
@@ -140,7 +196,7 @@ public const val OUTPUT_SOURCE_SET = "generatedSources"
140196
public const val DEFAULT_GEN_DIR = "gen"
141197

142198
interface GenerateImpl {
143-
fun doGenerate(output: Writer, input: Iterable<out File>?)
199+
fun doGenerate(output: Writer, input: Iterable<File>?)
144200
}
145201

146202
class GenerateSpec(val name: String) {
@@ -150,7 +206,14 @@ class GenerateSpec(val name: String) {
150206
var input: Any?=null
151207
}
152208

153-
open class GenerateSourceSet(val name:String, val generate: NamedDomainObjectContainer<GenerateSpec>) {
209+
class GenerateDirSpec() {
210+
var input: Any?=null
211+
var generator: String?=null
212+
var classpath: FileCollection? = null
213+
var outputDir: String?=null
214+
}
215+
216+
open class GenerateSourceSet(val generate: NamedDomainObjectContainer<GenerateSpec>) {
154217

155218
fun generate(configureClosure: Closure<Any?>?): GenerateSourceSet {
156219
ConfigureUtil.configure(configureClosure, generate)
@@ -161,11 +224,10 @@ open class GenerateSourceSet(val name:String, val generate: NamedDomainObjectCon
161224
class CodegenPlugin : Plugin<Project> {
162225

163226
override fun apply(project: Project) {
164-
val javaBasePlugin = project.plugins.apply(JavaBasePlugin::class.java)
165-
project.plugins.apply(JavaPlugin::class.java)
227+
project.plugins.apply(JavaBasePlugin::class.java)
166228

167229
val sourceSetsToSkip = mutableSetOf<String>("generators")
168-
val sourceSets = project.sourceSets.all {sourceSet ->
230+
project.sourceSets.all {sourceSet ->
169231
if (! sourceSetsToSkip.contains(sourceSet.name)) {
170232
if (sourceSet.name.endsWith("enerators")) {
171233
project.logger.error("Generators sourceSet (${sourceSet.name}) not registered in ${sourceSetsToSkip}")
@@ -196,7 +258,7 @@ class CodegenPlugin : Plugin<Project> {
196258

197259
val generateExt = project.container(GenerateSpec::class.java)
198260
if (sourceSet is HasConvention) {
199-
sourceSet.convention.plugins.put("net.devrieze.gradlecodegen", GenerateSourceSet("generate", generateExt))
261+
sourceSet.convention.plugins.put("net.devrieze.gradlecodegen", GenerateSourceSet(generateExt))
200262
} else {
201263
project.extensions.add(generateTaskName, generateExt)
202264
}

0 commit comments

Comments
 (0)