Extensions - coding and testing
Starting with version 3
Coding the extension
Coding the extension is a little more difficult than normal, the recommended way is to split out the building of the extension and the testing of the extension. To this aim, we will look at the h2zero-extension-taglibs project which generates tag libraries from the h2zero object model.
There are multiple parts to this:
- The
build.gradlefile, - the
build.h2zerofile, and - the
.h2zerofile.
The build.gradle file
This file will compile, test and package the extension for use.
plugins {
id 'java'
id 'eclipse'
id "maven"
id "maven-publish"
id "com.github.ben-manes.versions" version "0.28.0"
id "com.jfrog.bintray" version "1.8.4"
id 'com.gradle.plugin-publish' version '0.11.0'
id 'co.riiid.gradle' version '0.4.2'
// id 'net.saliman.cobertura' version '2.5.4'
id 'synapticloop.copyrightr' version '1.3.1'
id 'synapticloop.documentr' version '3.0.0'
id 'synapticloop.h2zero' version '4.5.3'
}
group = 'synapticloop'
archivesBaseName = 'h2zero-extension-taglibs'
description = """Taglib extension for h2zero"""
version = '4.2.1'
tasks.withType(Javadoc).all { enabled = false }
sourceCompatibility = 1.9
targetCompatibility = 1.9
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
implementation 'synapticloop:h2zero:4.5.3'
implementation 'synapticloop:h2zero-extension-taglibs:4.2.1'
implementation 'javax.servlet.jsp:jsp-api:2.2'
implementation 'javax.servlet:javax.servlet-api:4.0.1'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-all:1.10.19'
testImplementation 'com.github.stefanbirkner:system-rules:1.16.1'
testImplementation 'mysql:mysql-connector-java:8.0.19'
testImplementation 'org.xerial:sqlite-jdbc:3.30.1'
testImplementation 'commons-io:commons-io:2.6'
testImplementation 'com.mashape.unirest:unirest-java:1.4.9'
}
configurations.all {
resolutionStrategy {
failOnVersionConflict()
force 'junit:junit:4.11',
'org.slf4j:slf4j-api:1.7.25',
'org.json:json:20180130',
'commons-logging:commons-logging:1.2',
'commons-collections:commons-collections:3.2.2',
'com.github.stefanbirkner:system-rules:1.17.1',
'org.apache.httpcomponents:httpclient:4.5.2'
}
}
//cobertura {
// coverageFormats = [ 'html', 'xml']
// coverageDirs = [
// project.sourceSets.main.output.classesDir,
// file("build/classes/test/")
// ]
// coverageSourceDirs = [
// project.sourceSets.main.java.srcDirs,
// file("src/test/java/")
// ]
//}
test {
include '**/*Test.class'
maxParallelForks = 1
}
def javaApiUrl = 'http://docs.oracle.com/javase/1.7.0/docs/api/'
def groovyApiUrl = 'http://groovy.codehaus.org/gapi/'
tasks.withType(Javadoc) {
options.links(javaApiUrl, groovyApiUrl)
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from 'build/docs/javadoc'
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
}
//test.finalizedBy(project.tasks.cobertura)
publishing {
publications {
Synapticloop(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
groupId group
artifactId archivesBaseName
pom.withXml {
configurations.compile.resolvedConfiguration.firstLevelModuleDependencies.each { dep ->
asNode().dependencies[0].dependency.find {
it.artifactId[0].text() == dep.moduleName &&
it.groupId[0].text() == dep.moduleGroup
}.scope[0].value = 'compile'
}
}
}
}
}
bintray {
user = System.getenv('BINTRAY_USER')
key = System.getenv('BINTRAY_PASSWORD')
publications = [ 'Synapticloop' ]
publish = true
pkg {
repo = 'maven'
name = 'h2zero-extension-taglibs'
}
}
github {
owner = group
repo = archivesBaseName
if(System.getenv('GITHUB_TOKEN')) {
token = System.getenv('GITHUB_TOKEN')
}
tagName = version
name = version
assets = [
'build/libs/' + archivesBaseName + '-' + version + '.jar',
'build/libs/' + archivesBaseName + '-' + version + '-all.jar'
]
}
copyrightr {
excludes [
]
dryRun = false
}
//task(dist).dependsOn( [ 'cobertura', 'jar', 'javadoc' ] )
task(dist).dependsOn( [ 'jar', 'javadoc' ] )
Notes:
- within the
dependenciessection, the reference to'synapticloop:h2zero:3.0.0', which is the minimum version to build against. - the
version = '1.0.0'of the code - which is what we reference in the next part.
To build and test the extension, you will need to either publish this to a maven repository, or to maven local. We use maven local to iterate through the development process, until we are ready to push the extension to the world. Try:
gradle build pTML
The build.h2zero.gradle file
This file is the test build file that generates the code, by default we generate to src/test/java - which is defined in the sample.h2zero file.
buildscript {
repositories {
mavenCentral()
jcenter()
mavenLocal()
maven {
url "https://plugins.gradle.org/"
}
}
dependencies {
classpath 'synapticloop:h2zero-extension-taglibs:4.2.1'
}
}
plugins {
id 'java'
id 'eclipse'
id 'synapticloop.h2zero' version '4.5.3'
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
h2zero {
inFile = 'src/test/resources/sample-include.h2zero'
outDir = '.'
verbose = 'true'
}
Notes:
- within the
buildscriptdependenciessection, the reference to'synapticloop:h2zero-extension-taglibs:1.0.0', which will pick up the maven local reference - the
version = '1.0.0'in thebuildscriptdependenciessection, this needs to be updated, every time that thebuild.gradleversion is updated
The command that we use is:
gradle -b build.h2zero.gradle h2zero
The sample.h2zero file
To test the generation of the code, we use a sample h2zero file as follows:
{
"options": {
"database": "mysql",
"metrics": false,
"generators": [ "java", "sql" ],
"extensions": [
"synapticloop.h2zero.extension.TaglibExtension"
],
"validators": {
"UpdaterNameValidator": {
"allowablePrefixes": "reset,"
},
"FinderNameValidator": {
"allowablePrefixes": "find,calculate"
}
},
"output": {
"code": "src/test/java/",
"resources": "src/test/resources/",
"build": "build/"
}
},
"database": {
"schema": "sample",
"package": "synapticloop.sample.h2zero.mysql",
"defaultStatementCacheSize": 1024,
"tables": [
{ "include": "./user_type.json" },
{ "include": "./user_title.json" },
{ "include": "./user.json" },
{ "include": "./pet.json" },
{ "include": "./user_pet.json" }
],
"views": [
{ "include": "./view-pet.json" },
]
}
}
Note the registration of the extension:
"extensions": [
"synapticloop.h2zero.extension.TaglibExtension"
],
and the output directories for testing
"output": {
"code": "src/test/java/",
"resources": "src/test/resources/",
"build": "build/"
}
Putting it all together
- Update the
versionnumber in thebuild.gradlefile - run
gradle build pTML - Update the
versionnumber in thebuild.h2zero.gradlein thedependenciessection - run
gradle -b build.h2zero.gradle h2zero
If you are just iterating over the development of the generated code - just run:
gradle build pTML; gradle -b build.h2zero.gradle h2zero
to build the extension and generate the code. If there is an error with the generated code, just delete the src/test/java/* contents and start again.