From 8bd6485ec0ab15ebe223514c3a36add9c005bb12 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 3 Oct 2014 20:03:52 +0200 Subject: [PATCH 1/8] apply base plugin. adds clean Task to the project. --- README.adoc | 3 ++ build.gradle | 3 ++ gradle/wrapper/gradle-wrapper.jar | Bin 50557 -> 51017 bytes gradle/wrapper/gradle-wrapper.properties | 4 +-- .../me/champeau/gradle/JBakePlugin.groovy | 6 +++- .../me/champeau/gradle/JBakePluginTest.groovy | 29 ++++++++++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy diff --git a/README.adoc b/README.adoc index 7f6fa122..d17d608c 100644 --- a/README.adoc +++ b/README.adoc @@ -19,6 +19,9 @@ buildscript { // optional, if you use asciidoctor markup classpath 'org.asciidoctor:asciidoctor-java-integration:0.1.4' + // optional, if you use markdown markup + classpath 'org.pegdown:pegdown:1.4.2' + // optional, if you use freemarker template engine classpath 'org.freemarker:freemarker:2.3.19' } diff --git a/build.gradle b/build.gradle index bf3fa134..084f7caf 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,9 @@ dependencies { compile gradleApi() compile localGroovy() compile 'org.jbake:jbake-core:2.3.0' + testCompile('org.spockframework:spock-core:0.7-groovy-2.0') { + exclude group:'org.codehaus.groovy' + } } project.version = '0.2.1-SNAPSHOT' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5838598129719e795cc5633f411468bdec311016..3d0dee6e8edfecc92e04653ec780de06f7b34f8b 100644 GIT binary patch delta 23550 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 delta 23009 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 lf4^v;R#q&{{ { + void apply(Project project) { - project.task('jbake', type:JBakeTask) + project.apply(plugin: 'base') + project.task('jbake', type: JBakeTask, group: 'Documentation', description: 'Bake jbake project') } } diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy new file mode 100644 index 00000000..c15f2f06 --- /dev/null +++ b/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy @@ -0,0 +1,29 @@ +package me.champeau.gradle + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.Specification +import spock.lang.Unroll + +/** + * Created by frank on 03.10.14. + */ +class JBakePluginTest extends Specification { + + + @Unroll + def "should have a Task called #taskName"(){ + + given: + + Project project = ProjectBuilder.builder().build() + project.apply plugin: 'me.champeau.jbake' + + expect: + project.tasks."${taskName}" + + where: + taskName << ['jbake', 'clean'] + } + +} From 1d7a48dd6762146d66183938d9cf16f85e18764f Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 12 Oct 2014 14:10:17 +0200 Subject: [PATCH 2/8] First attempt to make jbake version configuration dynamic Jbake switched to asciidoctorj library in Version 2.3.1 This must be handled. To be continued... --- build.gradle | 3 +- gradle/providedConfiguration.gradle | 20 ++++++++++ .../me/champeau/gradle/JBakeExtension.groovy | 11 ++++++ .../me/champeau/gradle/JBakePlugin.groovy | 28 +++++++++++++- .../me/champeau/gradle/JBakeProxy.groovy | 9 +++++ .../me/champeau/gradle/JBakeProxyImpl.groovy | 26 +++++++++++++ .../me/champeau/gradle/JBakeTask.groovy | 38 ++++++++++++++----- 7 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 gradle/providedConfiguration.gradle create mode 100644 src/main/groovy/me/champeau/gradle/JBakeExtension.groovy create mode 100644 src/main/groovy/me/champeau/gradle/JBakeProxy.groovy create mode 100644 src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy diff --git a/build.gradle b/build.gradle index 084f7caf..039558db 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ apply plugin: 'maven-publish' apply from: 'gradle/credentials.gradle' apply from: 'gradle/artifactory.gradle' apply from: 'gradle/bintray.gradle' +apply from: "gradle/providedConfiguration.gradle" buildscript { repositories { @@ -22,7 +23,7 @@ repositories { dependencies { compile gradleApi() compile localGroovy() - compile 'org.jbake:jbake-core:2.3.0' + provided 'org.jbake:jbake-core:2.3.2' testCompile('org.spockframework:spock-core:0.7-groovy-2.0') { exclude group:'org.codehaus.groovy' } diff --git a/gradle/providedConfiguration.gradle b/gradle/providedConfiguration.gradle new file mode 100644 index 00000000..923d2074 --- /dev/null +++ b/gradle/providedConfiguration.gradle @@ -0,0 +1,20 @@ +/** + * Adds a configuration named 'provided'. 'Provided' dependencies + * are incoming compile dependencies that aren't outgoing + * dependencies. In other words, they have no effect on transitive + * dependency management. + */ + +configurations { + provided + providedPlusCompile.extendsFrom(compile, provided) + testCompile.extendsFrom(providedPlusCompile) +} + +sourceSets.main { + compileClasspath = configurations.providedPlusCompile +} + +plugins.withType(IdeaPlugin) { + idea.module.scopes.PROVIDED.plus = [ configurations.provided ] +} diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy new file mode 100644 index 00000000..fa73d88b --- /dev/null +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -0,0 +1,11 @@ +package me.champeau.gradle + +import org.gradle.api.Project + +/** + * Created by frank on 12.10.14. + */ +class JBakeExtension { + + String version = '2.3.0' +} diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index 04ccbe9a..d2cd2520 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -22,8 +22,34 @@ import org.gradle.api.internal.project.ProjectInternal class JBakePlugin implements Plugin { + + public static final String JBAKE = "jbake" + void apply(Project project) { project.apply(plugin: 'base') - project.task('jbake', type: JBakeTask, group: 'Documentation', description: 'Bake jbake project') + + JBakeExtension extension = project.extensions.create(JBAKE, JBakeExtension) + + project.repositories { + jcenter() + } + + Configuration configuration = project.configurations.maybeCreate(JBAKE) + + project.afterEvaluate{ + project.dependencies { + jbake("org.jbake:jbake-core:${extension.version}") + //TODO remove hard coded Engine-Versions to JBakeExtension + //TODO jbake >= 2.3.1 switched to org.asciidoctor:asciidoctorj:1.5.+ + jbake("org.asciidoctor:asciidoctor-java-integration:0.1.4") + jbake("org.freemarker:freemarker:2.3.19") + jbake("org.pegdown:pegdown:1.4.2") + } + } + + project.task('jbake', type: JBakeTask, group: 'Documentation', description: 'Bake a jbake project'){ + classpath = configuration + } + } } diff --git a/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy b/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy new file mode 100644 index 00000000..10983bfc --- /dev/null +++ b/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy @@ -0,0 +1,9 @@ +package me.champeau.gradle + +/** + * Created by frank on 12.10.14. + */ +public interface JBakeProxy { + + def jbake() +} \ No newline at end of file diff --git a/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy b/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy new file mode 100644 index 00000000..b8ce7994 --- /dev/null +++ b/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy @@ -0,0 +1,26 @@ +package me.champeau.gradle + +import java.lang.reflect.Constructor + + +/** + * Created by frank on 12.10.14. + */ +class JBakeProxyImpl implements JBakeProxy{ + + Class delegate + def input + def output + def clearCache + + def jbake() { + + Constructor constructor = delegate.getConstructor(File.class,File.class,boolean) + + def instance = constructor.newInstance(input, output, clearCache) + instance.with { + setupPaths() + bake() + } + } +} diff --git a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy index 32a3d2b4..afb5923e 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy @@ -15,27 +15,47 @@ */ package me.champeau.gradle -import org.apache.commons.configuration.CompositeConfiguration -import org.apache.commons.configuration.MapConfiguration -import org.gradle.api.internal.AbstractTask +import org.gradle.api.DefaultTask +import org.gradle.api.artifacts.Configuration import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction -import org.jbake.app.Oven -class JBakeTask extends AbstractTask { +class JBakeTask extends DefaultTask { @InputDirectory File input = new File("$project.projectDir/src/jbake") @OutputDirectory File output = new File("$project.buildDir/jbake") @Input Map configuration = [:] boolean clearCache = false + Configuration classpath + private static ClassLoader cl + + JBakeProxy jbake + @TaskAction void bake() { - new Oven(input, output, clearCache).with { - config = new CompositeConfiguration([new MapConfiguration(configuration), config]) - setupPaths() - bake() + //TODO make it possible to change jbake configuration via extension?! + jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(),input: input,output: output,clearCache: clearCache) + jbake.jbake() + } + + private def loadOvenDynamic() { + setupClassLoader() + loadClass("org.jbake.app.Oven") + } + + private static Class loadClass(String className) { + cl.loadClass(className) + } + + private def setupClassLoader() { + if (classpath?.files) { + def urls = classpath.files.collect { it.toURI().toURL() } + cl = new URLClassLoader(urls as URL[], Thread.currentThread().contextClassLoader) + Thread.currentThread().contextClassLoader = cl + } else { + cl = Thread.currentThread().contextClassLoader } } From 38ac04df0818866065f43dc1d1ca3c7723223212 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 13 Oct 2014 02:04:14 +0200 Subject: [PATCH 3/8] added freemaker, pegdown and asciidoctor version into Extension --- .../me/champeau/gradle/JBakeExtension.groovy | 6 +- .../me/champeau/gradle/JBakePlugin.groovy | 36 ++++++---- .../me/champeau/gradle/JBakeTask.groovy | 8 ++- .../me/champeau/gradle/JBakePluginSpec.groovy | 71 +++++++++++++++++++ .../me/champeau/gradle/JBakePluginTest.groovy | 29 -------- 5 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy delete mode 100644 src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index fa73d88b..dbbe9144 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -1,11 +1,13 @@ package me.champeau.gradle -import org.gradle.api.Project - /** * Created by frank on 12.10.14. */ class JBakeExtension { String version = '2.3.0' + String pegdownVersion = '1.4.2' + String freemarkerVersion = '2.3.19' + String asciidoctorVersion = '0.1.4' + } diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index d2cd2520..bd2e071e 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -18,38 +18,48 @@ package me.champeau.gradle import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.internal.project.ProjectInternal class JBakePlugin implements Plugin { public static final String JBAKE = "jbake" + Project project + JBakeExtension extension void apply(Project project) { + this.project = project project.apply(plugin: 'base') - JBakeExtension extension = project.extensions.create(JBAKE, JBakeExtension) - project.repositories { jcenter() } Configuration configuration = project.configurations.maybeCreate(JBAKE) + extension = project.extensions.create(JBAKE, JBakeExtension) - project.afterEvaluate{ - project.dependencies { - jbake("org.jbake:jbake-core:${extension.version}") - //TODO remove hard coded Engine-Versions to JBakeExtension - //TODO jbake >= 2.3.1 switched to org.asciidoctor:asciidoctorj:1.5.+ - jbake("org.asciidoctor:asciidoctor-java-integration:0.1.4") - jbake("org.freemarker:freemarker:2.3.19") - jbake("org.pegdown:pegdown:1.4.2") - } - } + addDependenciesAfterEvaluate() project.task('jbake', type: JBakeTask, group: 'Documentation', description: 'Bake a jbake project'){ classpath = configuration } } + + def addDependenciesAfterEvaluate() { + project.afterEvaluate { + addDependencies() + } + } + + def addDependencies() { + project.dependencies { + jbake("org.jbake:jbake-core:${extension.version}") + //TODO remove hard coded Engine-Versions to JBakeExtension + //TODO jbake >= 2.3.1 switched to org.asciidoctor:asciidoctorj:1.5.+ + jbake("org.asciidoctor:asciidoctor-java-integration:${extension.asciidoctorVersion}") + jbake("org.freemarker:freemarker:${extension.freemarkerVersion}") + jbake("org.pegdown:pegdown:${extension.pegdownVersion}") + } + } + } diff --git a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy index afb5923e..3b75f5e3 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy @@ -36,10 +36,16 @@ class JBakeTask extends DefaultTask { @TaskAction void bake() { //TODO make it possible to change jbake configuration via extension?! - jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(),input: input,output: output,clearCache: clearCache) + createJbake() jbake.jbake() } + private def createJbake() { + if ( !jbake ) { + jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(), input: input, output: output, clearCache: clearCache) + } + } + private def loadOvenDynamic() { setupClassLoader() loadClass("org.jbake.app.Oven") diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy new file mode 100644 index 00000000..5f379676 --- /dev/null +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -0,0 +1,71 @@ +package me.champeau.gradle + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.Ignore +import spock.lang.Specification +import spock.lang.Unroll + +/** + * Created by frank on 03.10.14. + */ +class JBakePluginSpec extends Specification { + + public static final String PLUGIN_ID = 'me.champeau.jbake' + Project project + + def setup(){ + project = ProjectBuilder.builder().build() + project.apply plugin: PLUGIN_ID + } + + + def "should add a JBakeTask"(){ + + expect: + project.tasks.jbake instanceof JBakeTask + } + + def "should add jbake configuration"(){ + + expect: + project.configurations.jbake + } + + def "should define default jbake version"(){ + + expect: + project.jbake.version != null + } + + @Unroll + @Ignore + def "should add dependency #name #version"(){ + + expect: + project.configurations.jbake.dependencies.find { + it.name == name && it.version == version + } + + where: + group | name | version + 'org.jbake' | 'jbake-core' | '2.3.0' + 'org.freemarker' | 'freemarker' | '2.3.19' + 'org.pegdown' | 'pegdown' | '1.4.2' + 'org.asciidoctor' | 'asciidoctor-java-integration' | '0.1.4' + + } + + @Ignore + def "set dependency version by extension"(){ + when: + project.jbake.version = '2.3.2' + + then: + project.configurations.jbake.dependencies.find { + it.name == 'jbake-core' && it.version == '2.3.2' + } + + } + +} diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy deleted file mode 100644 index c15f2f06..00000000 --- a/src/test/groovy/me/champeau/gradle/JBakePluginTest.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package me.champeau.gradle - -import org.gradle.api.Project -import org.gradle.testfixtures.ProjectBuilder -import spock.lang.Specification -import spock.lang.Unroll - -/** - * Created by frank on 03.10.14. - */ -class JBakePluginTest extends Specification { - - - @Unroll - def "should have a Task called #taskName"(){ - - given: - - Project project = ProjectBuilder.builder().build() - project.apply plugin: 'me.champeau.jbake' - - expect: - project.tasks."${taskName}" - - where: - taskName << ['jbake', 'clean'] - } - -} From 9c82b01bf27fa966f9d459fc7eb78b7d43fe4421 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 13 Oct 2014 14:38:22 +0200 Subject: [PATCH 4/8] switch asciidoctor dependency if jbake version > 2.3.0 --- .../me/champeau/gradle/JBakeExtension.groovy | 3 +- .../me/champeau/gradle/JBakePlugin.groovy | 11 ++- .../groovy/me/champeau/gradle/Version.groovy | 51 +++++++++++ .../me/champeau/gradle/JBakePluginSpec.groovy | 29 ++++++- .../me/champeau/gradle/VersionTest.groovy | 84 +++++++++++++++++++ 5 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 src/main/groovy/me/champeau/gradle/Version.groovy create mode 100644 src/test/groovy/me/champeau/gradle/VersionTest.groovy diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index dbbe9144..94ba45c6 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -8,6 +8,7 @@ class JBakeExtension { String version = '2.3.0' String pegdownVersion = '1.4.2' String freemarkerVersion = '2.3.19' - String asciidoctorVersion = '0.1.4' + String asciidoctorJavaIntegrationVersion = '0.1.4' + String asciidoctorjVersion = '1.5.1' } diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index bd2e071e..18605404 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -54,9 +54,14 @@ class JBakePlugin implements Plugin { def addDependencies() { project.dependencies { jbake("org.jbake:jbake-core:${extension.version}") - //TODO remove hard coded Engine-Versions to JBakeExtension - //TODO jbake >= 2.3.1 switched to org.asciidoctor:asciidoctorj:1.5.+ - jbake("org.asciidoctor:asciidoctor-java-integration:${extension.asciidoctorVersion}") + + if ( new Version(extension.version) > new Version("2.3.0") ){ + jbake("org.asciidoctor:asciidoctorj:${extension.asciidoctorjVersion}") + } + else { + jbake("org.asciidoctor:asciidoctor-java-integration:${extension.asciidoctorJavaIntegrationVersion}") + } + jbake("org.freemarker:freemarker:${extension.freemarkerVersion}") jbake("org.pegdown:pegdown:${extension.pegdownVersion}") } diff --git a/src/main/groovy/me/champeau/gradle/Version.groovy b/src/main/groovy/me/champeau/gradle/Version.groovy new file mode 100644 index 00000000..6b9c8729 --- /dev/null +++ b/src/main/groovy/me/champeau/gradle/Version.groovy @@ -0,0 +1,51 @@ +package me.champeau.gradle + +/** + * Created by frank on 13.10.14. + */ +class Version implements Comparable { + + Integer major + Integer minor + Integer bugfix + + Version(String version) { + def tokens = version.tokenize('.') + + this.major = (tokens.size>=1)?tokens.get(0).toInteger():0 + this.minor = (tokens.size>=2)?tokens.get(1)?.toInteger():0 + this.bugfix = (tokens.size>=3)?tokens.get(2)?.toInteger():0 + } + + @Override + int compareTo(Object other) { + + def ret = 0 + + if ( this.major == other.major && this.minor == other.minor && this.bugfix == other.bugfix ){ + return 0 + } + + if ( this.major <= other.major ) { + if ( this.minor < other.minor ) { + ret = -1 + } + if ( this.bugfix < other.bugfix ) { + ret = -1 + } + } + + if ( this.major >= other.major ) { + if ( this.minor > other.minor ) { + ret = 1 + } + if ( this.bugfix > other.bugfix ) { + ret = 1 + } + } + + return ret + + } + +} diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy index 5f379676..bf49bffc 100644 --- a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -39,10 +39,12 @@ class JBakePluginSpec extends Specification { } @Unroll - @Ignore def "should add dependency #name #version"(){ - expect: + when: + project.evaluate() + + then: project.configurations.jbake.dependencies.find { it.name == name && it.version == version } @@ -56,11 +58,14 @@ class JBakePluginSpec extends Specification { } - @Ignore def "set dependency version by extension"(){ - when: + + given: project.jbake.version = '2.3.2' + when: + project.evaluate() + then: project.configurations.jbake.dependencies.find { it.name == 'jbake-core' && it.version == '2.3.2' @@ -68,4 +73,20 @@ class JBakePluginSpec extends Specification { } + def "switch to asciidoctorj if version > 2.3.0"(){ + + given: + project.jbake.version = '2.3.1' + + when: + project.evaluate() + + then: + project.configurations.jbake.dependencies.find { + it.group == 'org.asciidoctor' && + it.name == 'asciidoctorj' && + it.version == '1.5.1' + } + } + } diff --git a/src/test/groovy/me/champeau/gradle/VersionTest.groovy b/src/test/groovy/me/champeau/gradle/VersionTest.groovy new file mode 100644 index 00000000..977c1d0d --- /dev/null +++ b/src/test/groovy/me/champeau/gradle/VersionTest.groovy @@ -0,0 +1,84 @@ +package me.champeau.gradle + +import spock.lang.Specification +import spock.lang.Unroll + +/** + * Created by frank on 13.10.14. + */ +class VersionTest extends Specification { + + def "fill by string"(){ + given: + Version version = new Version("2.3.0") + + expect: + version.major == 2 + version.minor == 3 + version.bugfix == 0 + } + + def "ignore bugfix if not present"(){ + given: + Version version = new Version("2.0") + + expect: + version.major == 2 + version.minor == 0 + version.bugfix == 0 + } + + + def "should be equal"(){ + given: + Version one = new Version("1.1.1") + Version two = new Version("1.1.1") + + expect: + two == one + + } + + @Unroll + def "#versionOne should be less than #versionTwo"(){ + + given: + Version one = new Version(versionOne) + Version two = new Version(versionTwo) + + expect: + + one < two + + where: + versionOne | versionTwo + "1.0.0" | "1.0.1" + "1.0.0" | "1.1.0" + "1.0.0" | "1.1.1" + "0.0.0" | "0.0.1" + "10.0.12" | "11.11.11" + "10.11.10" | "10.12.10" + } + + @Unroll + def "#versionTwo should be bigger than #versionOne"(){ + + given: + Version one = new Version(versionTwo) + Version two = new Version(versionOne) + + expect: + + one > two + + where: + versionOne | versionTwo + "1.0.0" | "1.0.1" + "1.0.0" | "1.1.0" + "1.0.0" | "1.1.1" + "0.0.0" | "0.0.1" + "10.0.12" | "11.11.11" + "10.11.10" | "10.12.10" + } + +} From cefe3d11ce414705f4ff48a02c4599c8732c9d5f Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 13 Oct 2014 17:08:50 +0200 Subject: [PATCH 5/8] configure output and input via coventionMapping and extension properties --- .../me/champeau/gradle/JBakeExtension.groovy | 2 ++ .../me/champeau/gradle/JBakePlugin.groovy | 3 +++ .../me/champeau/gradle/JBakeTask.groovy | 6 ++--- .../me/champeau/gradle/JBakePluginSpec.groovy | 23 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index 94ba45c6..4075060f 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -10,5 +10,7 @@ class JBakeExtension { String freemarkerVersion = '2.3.19' String asciidoctorJavaIntegrationVersion = '0.1.4' String asciidoctorjVersion = '1.5.1' + String srcDirName = 'src/jbake' + String destDirName = 'jbake' } diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index 18605404..eb68e7b2 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -40,7 +40,10 @@ class JBakePlugin implements Plugin { addDependenciesAfterEvaluate() project.task('jbake', type: JBakeTask, group: 'Documentation', description: 'Bake a jbake project'){ + classpath = configuration + conventionMapping.input = { project.file("$project.projectDir/$project.jbake.srcDirName") } + conventionMapping.output = { project.file("$project.buildDir/$project.jbake.destDirName") } } } diff --git a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy index 3b75f5e3..2a2b14d2 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy @@ -23,8 +23,8 @@ import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction class JBakeTask extends DefaultTask { - @InputDirectory File input = new File("$project.projectDir/src/jbake") - @OutputDirectory File output = new File("$project.buildDir/jbake") + @InputDirectory File input + @OutputDirectory File output @Input Map configuration = [:] boolean clearCache = false @@ -42,7 +42,7 @@ class JBakeTask extends DefaultTask { private def createJbake() { if ( !jbake ) { - jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(), input: input, output: output, clearCache: clearCache) + jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(), input: getInput(), output: getOutput(), clearCache: clearCache) } } diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy index bf49bffc..ca95053d 100644 --- a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -89,4 +89,27 @@ class JBakePluginSpec extends Specification { } } + def "input dir should be configured by extension"(){ + given: + def srcDirName = "src/jbake-project" + def expectedFile = project.file("$project.rootDir/$srcDirName") + + when: + project.jbake.srcDirName = srcDirName + + then: + project.tasks.jbake.input == expectedFile + } + + def "output dir should be configured by extension"(){ + given: + def destDirName = "jbake-out" + def expectedFile = project.file("$project.buildDir/$destDirName") + + when: + project.jbake.destDirName = destDirName + + then: + project.tasks.jbake.output == expectedFile + } } From 39d0ccc62b556e8ae8aeb7540c898bda4c42220a Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 13 Oct 2014 17:58:12 +0200 Subject: [PATCH 6/8] configure clearCache via coventionMapping and extension properties --- .../groovy/me/champeau/gradle/JBakeExtension.groovy | 1 + .../groovy/me/champeau/gradle/JBakePlugin.groovy | 1 + src/main/groovy/me/champeau/gradle/JBakeTask.groovy | 4 ++-- .../me/champeau/gradle/JBakePluginSpec.groovy | 13 ++++++++++++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index 4075060f..d02ec003 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -12,5 +12,6 @@ class JBakeExtension { String asciidoctorjVersion = '1.5.1' String srcDirName = 'src/jbake' String destDirName = 'jbake' + boolean clearCache = false } diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index eb68e7b2..fc08cc77 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -44,6 +44,7 @@ class JBakePlugin implements Plugin { classpath = configuration conventionMapping.input = { project.file("$project.projectDir/$project.jbake.srcDirName") } conventionMapping.output = { project.file("$project.buildDir/$project.jbake.destDirName") } + conventionMapping.clearCache = { project.jbake.clearCache } } } diff --git a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy index 2a2b14d2..e07915c3 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy @@ -26,7 +26,7 @@ class JBakeTask extends DefaultTask { @InputDirectory File input @OutputDirectory File output @Input Map configuration = [:] - boolean clearCache = false + boolean clearCache Configuration classpath private static ClassLoader cl @@ -42,7 +42,7 @@ class JBakeTask extends DefaultTask { private def createJbake() { if ( !jbake ) { - jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(), input: getInput(), output: getOutput(), clearCache: clearCache) + jbake = new JBakeProxyImpl(delegate: loadOvenDynamic(), input: getInput(), output: getOutput(), clearCache: getClearCache()) } } diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy index ca95053d..78c39aa5 100644 --- a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -2,7 +2,6 @@ package me.champeau.gradle import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder -import spock.lang.Ignore import spock.lang.Specification import spock.lang.Unroll @@ -112,4 +111,16 @@ class JBakePluginSpec extends Specification { then: project.tasks.jbake.output == expectedFile } + + def "clearcache should be configured by extension"(){ + given: + def clearCache = true + + when: + project.jbake.clearCache = clearCache + + then: + project.tasks.jbake.clearCache == clearCache + } + } From 7b7cf1176462a4d868b9423d7e22f8f0e484ba67 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 13 Oct 2014 19:09:01 +0200 Subject: [PATCH 7/8] jbake configurable by extension configuration per reflection \o/ --- .../me/champeau/gradle/JBakeExtension.groovy | 1 + .../me/champeau/gradle/JBakePlugin.groovy | 1 + .../me/champeau/gradle/JBakeProxy.groovy | 3 +++ .../me/champeau/gradle/JBakeProxyImpl.groovy | 26 +++++++++++++++---- .../me/champeau/gradle/JBakeTask.groovy | 21 ++++++++++++++- .../me/champeau/gradle/JBakePluginSpec.groovy | 12 +++++++++ 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index d02ec003..a3672480 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -13,5 +13,6 @@ class JBakeExtension { String srcDirName = 'src/jbake' String destDirName = 'jbake' boolean clearCache = false + Map configuration = [:] } diff --git a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy index fc08cc77..efa469e7 100644 --- a/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakePlugin.groovy @@ -45,6 +45,7 @@ class JBakePlugin implements Plugin { conventionMapping.input = { project.file("$project.projectDir/$project.jbake.srcDirName") } conventionMapping.output = { project.file("$project.buildDir/$project.jbake.destDirName") } conventionMapping.clearCache = { project.jbake.clearCache } + conventionMapping.configuration = { project.jbake.configuration } } } diff --git a/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy b/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy index 10983bfc..052fc6a8 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeProxy.groovy @@ -6,4 +6,7 @@ package me.champeau.gradle public interface JBakeProxy { def jbake() + def prepare() + def getConfig() + def setConfig(Object config) } \ No newline at end of file diff --git a/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy b/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy index b8ce7994..5b7d85b8 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeProxyImpl.groovy @@ -1,5 +1,9 @@ package me.champeau.gradle +import groovy.transform.Field +import org.apache.commons.configuration.CompositeConfiguration +import org.apache.commons.configuration.MapConfiguration + import java.lang.reflect.Constructor @@ -13,14 +17,26 @@ class JBakeProxyImpl implements JBakeProxy{ def output def clearCache + def jbake + def jbake() { + if(jbake) { + jbake.bake() + } + } + def prepare() { Constructor constructor = delegate.getConstructor(File.class,File.class,boolean) - def instance = constructor.newInstance(input, output, clearCache) - instance.with { - setupPaths() - bake() - } + jbake = constructor.newInstance(input, output, clearCache) + jbake.setupPaths() + } + + def getConfig(){ + jbake.config + } + + def setConfig(Object config) { + jbake.config = config } } diff --git a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy index e07915c3..87c65008 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeTask.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeTask.groovy @@ -22,6 +22,8 @@ import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction +import java.lang.reflect.Constructor + class JBakeTask extends DefaultTask { @InputDirectory File input @OutputDirectory File output @@ -35,8 +37,9 @@ class JBakeTask extends DefaultTask { @TaskAction void bake() { - //TODO make it possible to change jbake configuration via extension?! createJbake() + jbake.prepare() + mergeConfiguration() jbake.jbake() } @@ -46,6 +49,22 @@ class JBakeTask extends DefaultTask { } } + private def mergeConfiguration(){ + + //config = new CompositeConfiguration([createMapConfiguration(), jbake.getConfig()]) + def delegate = loadClass('org.apache.commons.configuration.CompositeConfiguration') + Constructor constructor = delegate.getConstructor(Collection) + def config = constructor.newInstance([createMapConfiguration(), jbake.getConfig()]) + jbake.setConfig( config ) + + } + + private def createMapConfiguration(){ + def delegate = loadClass('org.apache.commons.configuration.MapConfiguration') + Constructor constructor = delegate.getConstructor(Map) + constructor.newInstance(getConfiguration()) + } + private def loadOvenDynamic() { setupClassLoader() loadClass("org.jbake.app.Oven") diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy index 78c39aa5..a5fe8d0e 100644 --- a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -123,4 +123,16 @@ class JBakePluginSpec extends Specification { project.tasks.jbake.clearCache == clearCache } + def "should be configurable by extension"(){ + given: + def configuration = [:] + configuration['render.tags'] = false + + when: + project.jbake.configuration = configuration + + then: + project.tasks.jbake.configuration['render.tags'] == false + } + } From fad1555d50d9885870bee2d8b650f21fe3562209 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Tue, 14 Oct 2014 13:32:38 +0200 Subject: [PATCH 8/8] bumped jbake version to 2.3.2. Extended Readme. --- README.adoc | 47 ++++++++++++++----- .../me/champeau/gradle/JBakeExtension.groovy | 2 +- .../me/champeau/gradle/JBakePluginSpec.groovy | 25 ++++++++-- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/README.adoc b/README.adoc index d17d608c..6f88370b 100644 --- a/README.adoc +++ b/README.adoc @@ -15,22 +15,13 @@ buildscript { dependencies { classpath 'me.champeau.gradle:jbake-gradle-plugin:0.2' - - // optional, if you use asciidoctor markup - classpath 'org.asciidoctor:asciidoctor-java-integration:0.1.4' - - // optional, if you use markdown markup - classpath 'org.pegdown:pegdown:1.4.2' - - // optional, if you use freemarker template engine - classpath 'org.freemarker:freemarker:2.3.19' } } apply plugin: 'me.champeau.jbake' ---- -This will add a `bake` task to your build, which will search for a standard http://www.jbake.org[JBake] source tree in +This will add a `jbake` task to your build, which will search for a standard http://www.jbake.org[JBake] source tree in `src/jbake` and generate content into `$buildDir/jbake` (typically `build/jbake`). == Configuration @@ -41,11 +32,43 @@ The default input and output directories can be changed using the `jbake` config [source,groovy] ---- jbake { - input = file('jbake-sources') - output = file("$buildDir/output") + srcDirName = 'jbake-sources' + destDirName = 'output' +} +---- +The generated output can then be found at `$buildDir/output`. + +The Version could be changed too: + +[source,groovy] +---- +jbake { + version = '2.3.0' +} +---- + +The default is 2.3.2. + +=== Render Engine configuration + +Jbake uses three engines. The library versions could be changed too: + +[source,groovy] +---- +jbake { + + pegdownVersion = '1.4.2' + freemarkerVersion = '2.3.19' + asciidoctorJavaIntegrationVersion = '0.1.4' + asciidoctorjVersion = '1.5.1' } ---- +Notice the `asciidoctorJavaIntegrationVersion` and `asciidoctorjVersion`. Since Version 2.3.1 jbake has changed +to the asciidoctorj library. + +This plugin handles this change internally. If you use a Version > 2.3.0 of jbake, the dependency switch to the new one. + === JBake configuration There are several options to configure http://www.jbake.org[JBake]. One is to have the regular `jbake.properties` file into the source directory. The other is to use the plugin configuration block: diff --git a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy index a3672480..1dab5af5 100644 --- a/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy +++ b/src/main/groovy/me/champeau/gradle/JBakeExtension.groovy @@ -5,7 +5,7 @@ package me.champeau.gradle */ class JBakeExtension { - String version = '2.3.0' + String version = '2.3.2' String pegdownVersion = '1.4.2' String freemarkerVersion = '2.3.19' String asciidoctorJavaIntegrationVersion = '0.1.4' diff --git a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy index a5fe8d0e..2fc72d0b 100644 --- a/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy +++ b/src/test/groovy/me/champeau/gradle/JBakePluginSpec.groovy @@ -50,24 +50,24 @@ class JBakePluginSpec extends Specification { where: group | name | version - 'org.jbake' | 'jbake-core' | '2.3.0' + 'org.jbake' | 'jbake-core' | '2.3.2' 'org.freemarker' | 'freemarker' | '2.3.19' 'org.pegdown' | 'pegdown' | '1.4.2' - 'org.asciidoctor' | 'asciidoctor-java-integration' | '0.1.4' + 'org.asciidoctor' | 'asciidoctorj' | '1.5.1' } def "set dependency version by extension"(){ given: - project.jbake.version = '2.3.2' + project.jbake.version = '2.3.0' when: project.evaluate() then: project.configurations.jbake.dependencies.find { - it.name == 'jbake-core' && it.version == '2.3.2' + it.name == 'jbake-core' && it.version == '2.3.0' } } @@ -88,6 +88,23 @@ class JBakePluginSpec extends Specification { } } + def "use asciidoctor-java-integration if version < 2.3.1"(){ + + given: + project.jbake.version = '2.3.0' + + when: + project.evaluate() + + then: + project.configurations.jbake.dependencies.find { + it.group == 'org.asciidoctor' && + it.name == 'asciidoctor-java-integration' && + it.version == '0.1.4' + } + + } + def "input dir should be configured by extension"(){ given: def srcDirName = "src/jbake-project"