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.gradle
file, - the
build.h2zero
file, and - the
.h2zero
file.
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
dependencies
section, 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
buildscript
dependencies
section, the reference to'synapticloop:h2zero-extension-taglibs:1.0.0'
, which will pick up the maven local reference - the
version = '1.0.0'
in thebuildscript
dependencies
section, this needs to be updated, every time that thebuild.gradle
version 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
version
number in thebuild.gradle
file - run
gradle build pTML
- Update the
version
number in thebuild.h2zero.gradle
in thedependencies
section - 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.