diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..a2830836a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,191 @@ +stages: + - build + - testInfra + - test +# - reports +# - release + +cache: + key: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME-$CI_JOB_STAGE-$CI_JOB_NAME" + paths: + - $HOME/.gradle + +jdk8: + stage: build + image: openjdk:8 + script: ./gradlew -i -S --console=plain --no-build-cache assemble codenarcAll license + artifacts: + paths: + - .gradle/ + - '*/build/' + expire_in: 60min + when: always + except: + - pages + - gh-pages + - tags + +jdk11: + stage: build + image: openjdk:11 + script: ./gradlew -i -S --console=plain --no-build-cache assemble + artifacts: + paths: + - .gradle/ + - '*/build/' + expire_in: 60min + when: always + except: + - pages + - gh-pages + - tags + +test:integration: + stage: test + image: openjdk:8 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk8 + script: ./gradlew -i -s --console=plain --no-build-cache test intTest remoteTest + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_4.0.2,4.1,4.2.1: + stage: test + image: openjdk:8 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk8 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_4.3.1,4.4.1,4.5.1: + stage: test + image: openjdk:8 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk8 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_4.6,4.7,4.8.1: + stage: test + image: openjdk:8 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk8 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_4.9,4.10.2: + stage: test + image: openjdk:11 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk11 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_5.0,5.1.1: + stage: test + image: openjdk:11 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk11 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +test:gradle_5.3: + stage: test + image: openjdk:11 + except: + - pages + - gh-pages + - tags + dependencies: + - jdk11 + script: ./run-compatibility-test-on-ci.sh + artifacts: + paths: + - '*/build/reports' + - '*/build/jacoco' + expire_in: 10 days + when: on_failure + +#jacoco: +# stage: reports +# image: openjdk:11 +# dependencies: +# - test:integration +# - test:gradle_5.0,5.1.1 +# except: +# - pages +# - gh-pages +# - tags +# script: ./gradlew --console=plain jacocoRootReport coveralls + +#publish: +# stage: release +# image: openjdk:8 +# script: ./gradlew -s -i --console=plain --no-build-cache installDocs publishPlugins gitPublishPush -i -Dgradle.publish.key=$GRADLE_PORTAL_KEY -Dgradle.publish.secret=$GRADLE_PORTAL_SECRET -Dorg.ajoberstar.grgit.auth.username=$PAGES_PUBLISH_USER -Dorg.ajoberstar.grgit.auth.password=$PAGES_PUBLISH_KEY -Dorg.ajoberstar.grgit.auth.force=hardcoded +# dependencies: +# - jdk8 +# only: +# - release +# +#pages: +# stage: release +# script: ls -la +# artifacts: +# paths: +# - public +# only: +# - pages + diff --git a/.travis.yml b/.travis.yml index c6b355209..b0b4be9e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,16 +6,23 @@ cache: - $HOME/.gradle - .gradle/ - testfixtures/offline-repo/build/root +matrix: + include: + - jdk: openjdk11 -before_script: - - ./gradlew --version +stages: + - quality + - check + - report -script: - - ./gradlew --console=plain --warning-mode=all --scan build jacocoRootReport - -jdk: - - openjdk8 - - openjdk11 - -after_success: - - ./gradlew coveralls +jobs: + include: + - stage: quality + script: ./gradlew --console=plain license + name: 'Licensing' + - script: ./gradlew --console=plain codenarcAll + name: 'Coding style' + - stage: check + name: 'Build and test' + script: ./gradlew --console=plain --scan test intTest remoteTest gradleTest jacocoRootReport + after_success: ./gradlew coveralls diff --git a/HACKING.adoc b/HACKING.adoc deleted file mode 100644 index a224f11de..000000000 --- a/HACKING.adoc +++ /dev/null @@ -1,44 +0,0 @@ -= Asciidoctor Hacking Guide -:version: 1.6.0-SNAPSHOT -:project-name: asciidoctor-gradle-plugin - -This is a guide to developing locally and contributing to the Aciidoctor plugin for Gradle. (It is still very much work-in-progress) - -== Branches - -The default branch in github is `development` which is our working branch. `master` is set as the stable branch from -which we make our releases. We made `development` the default because people kept sending PRs targeting `master` instead. - -== Snapshots - -We do not publish snapshot releases because plugin snapshots break one very important tenet from `Gradle`: reproducible builds. -If a developer requires a snapshot release then we think this has to be a very conscious decision and they must bear -the responsibility of building said snapshot. In this way they can be sure it's their version and not someone else's -which might bring incompatibility problems. - -If you need to work with snapshots consider building locally and publishing to your local `~/.m2`. This can be achieved -by running `./gradlew publishToMavenLocal`. -You can then use the snapshot in your Gradle build as follows: - -If you want to change the version, you can edit it in `gradle.properties`. - -[source,groovy] -[subs="attributes,specialcharacters"] -.build.gradle ----- -buildscript { - repositories { - mavenLocal() - } - - dependencies { - classpath 'org.asciidoctor:{project-name}:{version}' - } -} - -apply plugin: 'org.asciidoctor.convert' ----- - -== Developing -* './gradlew build' - run tests and checks that everything is ok. -* './gradlew test' - run tests. \ No newline at end of file diff --git a/README.adoc b/README.adoc index 68e2c9f42..1a2be7918 100644 --- a/README.adoc +++ b/README.adoc @@ -1,6 +1,6 @@ = Asciidoctor Gradle Plugin Andres Almiray -:version: 2.0.0-rc.1 +:version: 2.0.0 :version-published: 2.0.0-rc.1 :asciidoc-url: http://asciidoc.org :asciidoctor-url: http://asciidoctor.org @@ -37,7 +37,6 @@ ifdef::env-github[] NOTE: `master` now represents the code for the latest 2.x release of these plugins. Development for for 2.x is against the link:https://github.com/asciidoctor/asciidoctor-gradle-plugin/tree/development-2.0[development-2.0] branch. PRs are preferably taking against that branch. The 1.5.x series of the plugin is now in maintenance only mode. PRs for that should be raised against the https://github.com/asciidoctor/asciidoctor-gradle-plugin/tree/maintenance-1.5[maintenance-1.5] branch. endif::[] - ifdef::status[] image:http://img.shields.io/travis/{project-full-path}/{github-branch}.svg[Build Status, link=https://travis-ci.org/{project-full-path}] image:https://ci.appveyor.com/api/projects/status/db102rphsu5lviv6/branch/{github-branch}?svg=true&passingText={github-branch}%20-%20OK&failingText={github-branch}%20-%20Fails&pendingText={github-branch}%20-%20Pending[Build Status, link=https://ci.appveyor.com/project/{project-full-path}/branch/{github-branch}] @@ -50,9 +49,7 @@ The {doctitle} is the official means of using {asciidoctor-url}[Asciidoctor] to NOTE: This started as a port of the {asciidoctor-maven-plugin}[Asciidoctor Maven Plugin] project founded by {lightguard}[@LightGuard] and relies on {asciidoctorj}[{asciidoctorj-name}] founded by {lordofthejars}[@lordofthejars]. In fact the 1.5.x series of the {plugin-name} can still be considered a port. However the 2.x series and beyond is a complete departure with functionality far exceeding any plugins for another build tool. This new series allows for the creations of a true DocuOps pipeline by bringing together Gradle as a powerful and generic build tool and Asciidoctor as an agile and lightweight document generator. -NOTE: The https://github.com/gradle/kotlin-dsl[Gradle Kotlin DSL] is not properly supported by this plugin yet but it can be used with the GKD. Examples and workarounds are described below. - -NOTE: This collection of plugins requires at least Gradle 4.0 & JDK 8.0 to run. If you need prior Gradle or JDK support please use a plugin from the 1.5.x release series. +NOTE: This collection of plugins requires at least Gradle 4.0, JDK 8.0 and AsciidoctorJ 1.6.0 to run. If you need prior Gradle, JDK or AsciidoctorJ support please use a plugin from the 1.5.x or 1.6.x release series. == Known Issues @@ -62,13 +59,7 @@ This is still an alpha development, so expect some issues. These are the main on (KF8+EPUB3 or EPUB3+KF8) the conversion takes place in. * KF8 conversions fails under Windows. (Related to asciidoctor/asciidoctorj#659 & jruby/jruby#4943) * Does not work with JDK9 (but does with JDK10). - -ifndef::env-site[] -== Contributing - -Are you interested in contributing to this project? If so please read link:HACKING.adoc[HACKING] before sending in a patch. -Thank you! -endif::[] +* Not compatible with {kotlindsl} on Gradle *5.2.1* and *5.3*. See https://github.com/gradle/kotlin-dsl/issues/1353[KOTLIN-DSL-1353]. == Installation @@ -228,7 +219,7 @@ asciidoctorj { <1> ---- <1> This can be globally on the project extension or locally on the task's extension. -Or in the Gradle Kotlin DSL: +Or in the {kotlindsl}: [source,kotlin] .build.gradle.kts @@ -248,7 +239,7 @@ tasks { } } ---- -<1> This is an example of setting ti on the task extension in Kotlin. +<1> This is an example of setting it on the task extension in Kotlin. The following attributes are automatically set by the `asciidoctorj` extension: @@ -364,7 +355,7 @@ asciidoctor { Paths defined in this PatternSet are resolved relative to the `sourceDir`. -For the Gradle Kotlin DSL a workaround is needed:footnoteref:[kotlin-delegate,The method delegates to a type that Kotlin cannot infer that from the byte-code. The function `delegateClosureOf()` from the GKD is used to provide the information to Kotlin.] +For the {kotlindsl} a workaround is needed:footnoteref:[kotlin-delegate,The method delegates to a type that Kotlin cannot infer that from the byte-code. The function `delegateClosureOf()` from the GKD is used to provide the information to Kotlin.] [source,kotlin] .build.gradle.kts @@ -407,7 +398,8 @@ Files will be copied to below `+${outputDir}/${backend}+` (or just `+${outputDir Unlike `sourceDir` files can be copied from anywhere in the filesystem. -For the Gradle Kotlin DSL, the example above looks like this:footnoteref:[kotlin-delegate] +For the {kotlindsl}, the example above looks like this:footnoteref:[kotlin-delegate] + [source,kotlin] .build.gradle.kts ---- @@ -448,8 +440,8 @@ copyNoResources() All tasks can control how Asciidoctor conversions are being run via the `inProcess` property. This is early days, an choose for your build will depend very much on your context, but the following has already become clear: -* `IN_PROCESS` and `OUT_OF_PROCESS` shuold theoretically run faster, especially if you continuously rebuild the same documentation. Gradle workers are the underlying implementation for these two options -* The safe option is always `JAVA_EXEC`. For lower memory consumption this is by far the safer option. It is also the only way we can get the Windows-based tests for tjhis plugin completed on Appveyor. It you run a lot of builds the penalty statr-up time might become an issue for you. +* `IN_PROCESS` and `OUT_OF_PROCESS` should theoretically run faster, especially if you continuously rebuild the same documentation. Gradle workers are the underlying implementation for these two options +* The safe option is always `JAVA_EXEC`. For lower memory consumption this is by far the safer option. (It is also the only way we can get the Windows-based tests for this plugin to complete on Appveyor & Travis CI). It you run a lot of builds the penalty start-up time might become an issue for you. NOTE: In certain cases the plugin will overrule your choice as it has some built-in rules for special cases. In such cases it will log a warning that it has done that. @@ -564,7 +556,7 @@ Caused by: java.lang.UnsatisfiedLinkError: /path/to/openjdk10/lib/libfontmanager Reason: image not found ---- -The solutionn is to install `freetype` via HomeBrew or MacPorts. You might also need to do something (ridiculous) such as +The solution is to install `freetype` via HomeBrew or MacPorts. You might also need to do something (ridiculous) such as [source,bash] ---- @@ -601,7 +593,7 @@ asciidoctorj { When applying `org.asciidoctor.jvm.revealjs` support is added for creating slides using Asciidoctor & Reveal.js. The plugin configures: * Create a task called `asciidoctorRevealJs`. -* Create an extension called `revealjs` which i s sued for configuring the version of Reveal.js as well as a template. +* Create an extension called `revealjs` which is used for configuring the version of Reveal.js as well as a template. * Create an extension called `revealjsPlugins` which will allow for downloading additional Reveal.js plugins. * Output source to "${buildDir}/docs/asciidocRevealJs" * Copy all resources to the output directory including Reveal.js templates. @@ -612,7 +604,7 @@ The `AsciidoctorRevealJSTask` task type has the following additional methods: [horizontal] revealjsOptions:: Configure special Reveal.js options. Can be configured via Closure or Action. See <> for more details. -templateDir:: Location where the template directory will be locate don disk before Asciidoctor processing starts. +templateDir:: Location where the template directory will be located on disk before Asciidoctor processing starts. theme:: The Reveal.js theme to use. The theme must match one from the template. @@ -620,7 +612,7 @@ The version of the Reveal.js GEM and the Reveal.js template is configured via th [source,groovy] ---- -revealsjs { +revealjs { version = '1.1.3' // <1> templateGitHub { // <2> @@ -640,6 +632,16 @@ If not specified, sensible defaults are provided. Various options can be configured for Reveal.js. Although these can be set as attributes directly, it is far better to set them on the task as advantage can be taken of Gradle task caching and file resolving. +[source,groovy] +---- +asciidoctorRevealJs { + revealjsOptions { // <1> + controls = true + } +} +---- +<1> Use `revealjsOptions` block for configuration with any of the below options. + [horizontal] autoslideInterval:: Delay in milliseconds between automatically proceeding to the next slide. Disabled when set to `0` (the default). This value can still be overwritten on a per-slide basis by setting a `data-autoslide` attribute on a slide. @@ -658,7 +660,7 @@ flagEmbedded:: Flags if the presentation is running in an embedded mode ( contai Type is boolean. fragments:: Use fragments globally. Type is boolean. -highlightJsThemeLocation:: Highlight.js theme loca`tion. +highlightJsThemeLocation:: Highlight.js theme location. Can be anything convertible to a file or URI. keyboardShortcuts::Enable keyboard shortcuts for navigation. Type is boolean. @@ -783,11 +785,11 @@ sourceDir:: where the asciidoc sources are. sources:: specify which Asciidoctor source files to include by using an http://www.gradle.org/docs/current/javadoc/org/gradle/api/tasks/util/PatternSet.html[Ant-style PatternSet]. -NOTE: Even though the DSL remains the same with this task, the internals have been changed to use the same `JAVA_EXEC` mechanism of the `org.asciidoctor.jvm.convert` plugins. The problems which the 1.5.x series suffered with classpaths anions disappearing shuol dnow be a thing of the past. +NOTE: Even though the DSL remains the same with this task, the internals have been changed to use the same `JAVA_EXEC` mechanism of the `org.asciidoctor.jvm.convert` plugins. The problems which the 1.5.x series suffered with classpaths anions disappearing should now be a thing of the past. == Kindlegen plugin -Producing KF* formats via the EPUB extension requires `kindlegen` to be installed. This plugin provides the capability of bootstrapping `kindlegen` on Windows, MAx & Linux without the user having to do anything. +Producing KF* formats via the EPUB extension requires `kindlegen` to be installed. This plugin provides the capability of bootstrapping `kindlegen` on Windows, Mac & Linux without the user having to do anything. There is a base plugin `org.asciidoctor.kindlegen.base` which just provides a `kindlegen` extension. In order to use it you will need to agree to the Amazon terms of usage. To confirm this you need to configure @@ -795,13 +797,13 @@ you will need to agree to the Amazon terms of usage. To confirm this you need to [source,groovy] ---- kindlegen { - agreeTotermsOfUse = true + agreeToTermsOfUse = true } ---- -If you do not them the plugin will refuse to botostrap `kindlegen`. +If you do not, then the plugin will refuse to bootstrap `kindlegen`. -NOTE: The base plugin is automatically applied by the EPUB plugin. If you only produce EPUB3 formats with the EPUB plugin you do not have to agree to usage of `kindlegen`. +NOTE: The base plugin is automatically applied by the EPUB plugin. If you only produce EPUB3 formats with the EPUB plugin you do not have to agree to the usage of `kindlegen`. ifndef::env-site[] == Development @@ -812,7 +814,7 @@ endif::[] == Adding Custom Extensions Starting with version 1.5.0 you were able to write your own Asciidoctor extensions in Groovy, or any other JVM language -for that matter. Now with the 2.0.0 you are even more flixibility in allowsin extensions to be applied on a per task basis on globally. There are several options for you to make it happen. +for that matter. Now with the 2.0.0 you have even more flexibility in that extensions can be applied on a per task basis on globally. There are several options available to make it happen. === As External Library diff --git a/asciidoctor-gradle-base/build.gradle b/asciidoctor-gradle-base/build.gradle index 415dfbcc1..e018c19d8 100644 --- a/asciidoctor-gradle-base/build.gradle +++ b/asciidoctor-gradle-base/build.gradle @@ -23,8 +23,10 @@ configurePlugin 'org.asciidoctor.base', pluginManager.withPlugin('jacoco') { jacocoTestReport { - executionData = (fileTree('.') { exclude '**' }) + executionData.setFrom(fileTree('.') { exclude '**' }) executionData test dependsOn test } } + +configurations.gradleTestCompile.transitive = false diff --git a/asciidoctor-gradle-base/src/gradleTest/apply-the-base-plugin/build.gradle.kts b/asciidoctor-gradle-base/src/gradleTest/apply-the-base-plugin/build.gradle.kts new file mode 100644 index 000000000..acb1d7dc6 --- /dev/null +++ b/asciidoctor-gradle-base/src/gradleTest/apply-the-base-plugin/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id ("org.asciidoctor.base") +} + +tasks.register("runGradleTest") { + doLast { + println("hello") + } +} diff --git a/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/ApplyPluginSpec.groovy b/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/ApplyPluginSpec.groovy new file mode 100644 index 000000000..4060d2a31 --- /dev/null +++ b/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/ApplyPluginSpec.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.gradle.base + +import org.asciidoctor.gradle.base.internal.FunctionalSpecification + +class ApplyPluginSpec extends FunctionalSpecification { + + void 'Apply the base plugin in a Kotlin DSL'() { + + given: + getKotlinBuildFile('') + + when: + getGradleRunnerForKotlin(['tasks', '-s']).build() + + then: + noExceptionThrown() + } + + void 'Apply the base plugin in a Groovy DSL'() { + + given: + getGroovyBuildFile('', 'base') + + when: + getGradleRunner(['tasks']).build() + + then: + noExceptionThrown() + } +} \ No newline at end of file diff --git a/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/internal/FunctionalSpecification.groovy b/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/internal/FunctionalSpecification.groovy new file mode 100644 index 000000000..e1559265d --- /dev/null +++ b/asciidoctor-gradle-base/src/intTest/groovy/org/asciidoctor/gradle/base/internal/FunctionalSpecification.groovy @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.gradle.base.internal + +import groovy.transform.CompileStatic +import org.apache.commons.io.FileUtils +import org.asciidoctor.gradle.testfixtures.jvm.DslType +import org.asciidoctor.gradle.testfixtures.jvm.FunctionalTestSetup +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import static org.asciidoctor.gradle.testfixtures.jvm.DslType.GROOVY_DSL +import static org.asciidoctor.gradle.testfixtures.jvm.DslType.KOTLIN_DSL +import static org.asciidoctor.gradle.testfixtures.jvm.FunctionalTestSetup.getOfflineRepositoriesGroovyDsl +import static org.asciidoctor.gradle.testfixtures.jvm.FunctionalTestSetup.getOfflineRepositoriesKotlinDsl + +class FunctionalSpecification extends Specification { + + static + final String TEST_PROJECTS_DIR = System.getProperty('TEST_PROJECTS_DIR') ?: './asciidoctor-gradle-base/src/intTest/projects' + static + final String TEST_REPO_DIR = System.getProperty('OFFLINE_REPO') ?: './testfixtures/offline-repo/build/repo' + + @Rule + TemporaryFolder testProjectDir + + @CompileStatic + GradleRunner getGradleRunner(List taskNames = ['tasks']) { + FunctionalTestSetup.getGradleRunner(testProjectDir.root, taskNames) + } + + @CompileStatic + GradleRunner getGradleRunnerForKotlin(List taskNames = ['tasks']) { + getGradleRunner(taskNames).withDebug(false) + } + + @SuppressWarnings(['FactoryMethodName', 'BuilderMethodWithSideEffects']) + void createTestProject(String docGroup = 'normal') { + FileUtils.copyDirectory(new File(TEST_PROJECTS_DIR, docGroup), testProjectDir.root) + } + + @CompileStatic + String getOfflineRepositories(DslType dslType = GROOVY_DSL) { + dslType == GROOVY_DSL ? getOfflineRepositoriesGroovyDsl(new File(TEST_REPO_DIR)) : + getOfflineRepositoriesKotlinDsl(new File(TEST_REPO_DIR)) + } + + File getGroovyBuildFile(String extraContent, String plugin = 'org.asciidoctor.base') { + File buildFile = testProjectDir.newFile('build.gradle') + buildFile << """ + plugins { + id '${plugin}' + } + + ${offlineRepositories} + + ${extraContent} + """ + buildFile + } + + File getKotlinBuildFile(String extraContent, String plugin = 'org.asciidoctor.base') { + File buildFile = testProjectDir.newFile('build.gradle.kts') + buildFile << """ + plugins { + id("${plugin}") + } + + ${getOfflineRepositories(KOTLIN_DSL)} + + ${extraContent} +""" + buildFile + } + +} \ No newline at end of file diff --git a/asciidoctor-gradle-base/src/main/groovy/org/asciidoctor/gradle/base/Transform.groovy b/asciidoctor-gradle-base/src/main/groovy/org/asciidoctor/gradle/base/Transform.groovy new file mode 100644 index 000000000..169a87fa8 --- /dev/null +++ b/asciidoctor-gradle-base/src/main/groovy/org/asciidoctor/gradle/base/Transform.groovy @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.gradle.base + +import groovy.transform.CompileStatic + +import java.util.function.Function +import java.util.stream.Collectors + +/** Transforms a collection to another collection. + * + * @since 2.0 + */ +@CompileStatic +class Transform { + static List toList(final Collection collection, Function tx ) { + collection.stream().map(tx).collect(Collectors.toList()) + } + + static Set toSet(final Collection collection, Function tx ) { + collection.stream().map(tx).collect(Collectors.toSet()) + } + + static Set toSet(final Iterable collection, Function tx ) { + collection.toList().stream().map(tx).collect(Collectors.toSet()) + } +} diff --git a/asciidoctor-gradle-jvm-epub/src/intTest/groovy/org/asciidoctor/gradle/jvm/epub/internal/FunctionalSpecification.groovy b/asciidoctor-gradle-jvm-epub/src/intTest/groovy/org/asciidoctor/gradle/jvm/epub/internal/FunctionalSpecification.groovy index f31df78db..ba8ede803 100644 --- a/asciidoctor-gradle-jvm-epub/src/intTest/groovy/org/asciidoctor/gradle/jvm/epub/internal/FunctionalSpecification.groovy +++ b/asciidoctor-gradle-jvm-epub/src/intTest/groovy/org/asciidoctor/gradle/jvm/epub/internal/FunctionalSpecification.groovy @@ -20,7 +20,6 @@ import org.gradle.testkit.runner.GradleRunner import org.junit.Rule import org.junit.rules.TemporaryFolder import org.ysb33r.grolifant.api.OperatingSystem -import spock.lang.Shared import spock.lang.Specification class FunctionalSpecification extends Specification { @@ -32,7 +31,7 @@ class FunctionalSpecification extends Specification { final OperatingSystem OS = OperatingSystem.current() @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() + TemporaryFolder testProjectDir GradleRunner getGradleRunner(List taskNames = ['asciidoctor']) { GradleRunner.create() @@ -43,7 +42,7 @@ class FunctionalSpecification extends Specification { .withDebug(true) } - @SuppressWarnings(['FactoryMethodName','BuilderMethodWithSideEffects']) + @SuppressWarnings(['FactoryMethodName', 'BuilderMethodWithSideEffects']) void createTestProject(String docGroup = 'epub3') { FileUtils.copyDirectory(new File(TEST_PROJECTS_DIR, docGroup), testProjectDir.root) } @@ -54,7 +53,7 @@ class FunctionalSpecification extends Specification { throw new FileNotFoundException("${repo} not found. Run ':testfixture-offline-repo:buildOfflineRepositories' build task") } - if(OS.windows) { + if (OS.windows) { "apply from: /${repo.absolutePath}/" } else { "apply from: '${repo.absolutePath}'" diff --git a/asciidoctor-gradle-jvm-epub/src/main/groovy/org/asciidoctor/gradle/jvm/epub/AsciidoctorEpubTask.groovy b/asciidoctor-gradle-jvm-epub/src/main/groovy/org/asciidoctor/gradle/jvm/epub/AsciidoctorEpubTask.groovy index 9a3a79caa..488c33ae2 100644 --- a/asciidoctor-gradle-jvm-epub/src/main/groovy/org/asciidoctor/gradle/jvm/epub/AsciidoctorEpubTask.groovy +++ b/asciidoctor-gradle-jvm-epub/src/main/groovy/org/asciidoctor/gradle/jvm/epub/AsciidoctorEpubTask.groovy @@ -17,6 +17,7 @@ package org.asciidoctor.gradle.jvm.epub import groovy.transform.CompileStatic import org.asciidoctor.gradle.internal.ExecutorConfiguration +import org.asciidoctor.gradle.base.Transform import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask import org.asciidoctor.gradle.jvm.AsciidoctorExecutionException import org.asciidoctor.gradle.jvm.ProcessMode @@ -83,7 +84,7 @@ class AsciidoctorEpubTask extends AbstractAsciidoctorTask { @SuppressWarnings('UnnecessaryCollectCall') void setEbookFormats(Iterable formats) { this.ebookFormats.clear() - this.ebookFormats.addAll(formats.collect { String it -> it.toLowerCase() } as Set) + this.ebookFormats.addAll(Transform.toSet(formats) { String it -> it.toLowerCase() }) } /** Adds aditional eBook formats @@ -93,7 +94,7 @@ class AsciidoctorEpubTask extends AbstractAsciidoctorTask { */ @SuppressWarnings('ConfusingMethodName') void ebookFormats(String... formats) { - this.ebookFormats.addAll(formats*.toLowerCase()) + this.ebookFormats.addAll(formats*.toLowerCase() as List) } @Override @@ -152,7 +153,7 @@ echo %1 %2 %3 %4 55 %6 %7 %8 %9 > ${tmpKindleGenLogFileForWindows} } else if (this.ebookFormats.size() == 1) { executorConfigurations.collectEntries { configName, config -> config.attributes[ebookAttr] = this.ebookFormats.first() - [backendName(this.ebookFormats.first()), config] + [backendName(this.ebookFormats.first().toString()), config] } as Map } else { Map newConfigurations = [:] diff --git a/asciidoctor-gradle-jvm-slides/src/gradleTest/basic-slides/build.gradle b/asciidoctor-gradle-jvm-slides/src/gradleTest/basic-slides/build.gradle index d8b3df048..338244ece 100644 --- a/asciidoctor-gradle-jvm-slides/src/gradleTest/basic-slides/build.gradle +++ b/asciidoctor-gradle-jvm-slides/src/gradleTest/basic-slides/build.gradle @@ -41,12 +41,3 @@ task runGradleTest { assert file("build/docs/asciidocRevealJs/revealjs.html").text.contains('World') } } - -// This is to work around a bug in Gradle. It is not part of normal build script. -// The side affect of this is that we actually get better code coverage as the process mode -// changes depending on which version of Gradle is being tested. -if(System.getProperty('CALLING_GRADLETEST_USES_GROOVY_VERSION') != GroovySystem.version) { - asciidoctorRevealJs { - inProcess JAVA_EXEC - } -} \ No newline at end of file diff --git a/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorRevealJSTaskFunctionalSpec.groovy b/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorRevealJSTaskFunctionalSpec.groovy index ff3069b6f..030c4794a 100644 --- a/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorRevealJSTaskFunctionalSpec.groovy +++ b/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorRevealJSTaskFunctionalSpec.groovy @@ -20,7 +20,7 @@ import org.asciidoctor.gradle.testfixtures.jvm.JRubyTestVersions import org.gradle.testkit.runner.BuildResult import spock.lang.PendingFeature -@SuppressWarnings(['DuplicateStringLiteral', 'MethodName', 'DuplicateListLiteral']) +@SuppressWarnings(['DuplicateStringLiteral', 'DuplicateListLiteral']) class AsciidoctorRevealJSTaskFunctionalSpec extends FunctionalSpecification { final static String JRUBY_TEST_VERSION = JRubyTestVersions.AJ16_SAFE_MAXIMUM @@ -34,7 +34,7 @@ class AsciidoctorRevealJSTaskFunctionalSpec extends FunctionalSpecification { getBuildFile('') when: - BuildResult result = build() + build() then: verifyAll { @@ -60,7 +60,7 @@ class AsciidoctorRevealJSTaskFunctionalSpec extends FunctionalSpecification { ''') when: - BuildResult result = build() + build() then: verifyAll { @@ -92,10 +92,10 @@ class AsciidoctorRevealJSTaskFunctionalSpec extends FunctionalSpecification { ''') when: - BuildResult result = build() + build() File revealjsHtml = new File(testProjectDir.root, 'build/docs/asciidocRevealJs/revealjs.html') - File pluginList = new File(testProjectDir.root,"build/docs/asciidocRevealJs/reveal.js/revealjs-plugins.js") - File pluginConfig = new File(testProjectDir.root,"build/docs/asciidocRevealJs/reveal.js/revealjs-plugin-configuration.js") + File pluginList = new File(testProjectDir.root, 'build/docs/asciidocRevealJs/reveal.js/revealjs-plugins.js') + File pluginConfig = new File(testProjectDir.root, 'build/docs/asciidocRevealJs/reveal.js/revealjs-plugin-configuration.js') then: verifyAll { @@ -108,6 +108,7 @@ class AsciidoctorRevealJSTaskFunctionalSpec extends FunctionalSpecification { } + @SuppressWarnings('FactoryMethodName') BuildResult build() { getGradleRunner(['asciidoctorRevealJs', '-s']).build() } diff --git a/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/internal/FunctionalSpecification.groovy b/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/internal/FunctionalSpecification.groovy index 4884532c4..3f4459ab0 100644 --- a/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/internal/FunctionalSpecification.groovy +++ b/asciidoctor-gradle-jvm-slides/src/intTest/groovy/org/asciidoctor/gradle/jvm/slides/internal/FunctionalSpecification.groovy @@ -20,7 +20,6 @@ import org.gradle.testkit.runner.GradleRunner import org.junit.Rule import org.junit.rules.TemporaryFolder import org.ysb33r.grolifant.api.OperatingSystem -import spock.lang.Shared import spock.lang.Specification class FunctionalSpecification extends Specification { @@ -32,7 +31,7 @@ class FunctionalSpecification extends Specification { final OperatingSystem OS = OperatingSystem.current() @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() + TemporaryFolder testProjectDir GradleRunner getGradleRunner(List taskNames) { GradleRunner.create() @@ -43,8 +42,8 @@ class FunctionalSpecification extends Specification { .withDebug(true) } - @SuppressWarnings(['FactoryMethodName','BuilderMethodWithSideEffects']) - void createTestProject(String docGroup ) { + @SuppressWarnings(['FactoryMethodName', 'BuilderMethodWithSideEffects']) + void createTestProject(String docGroup) { FileUtils.copyDirectory(new File(TEST_PROJECTS_DIR, docGroup), testProjectDir.root) } @@ -54,7 +53,7 @@ class FunctionalSpecification extends Specification { throw new FileNotFoundException("${repo} not found. Run ':testfixture-offline-repo:buildOfflineRepositories' build task") } - if(OS.windows) { + if (OS.windows) { "apply from: /${repo.absolutePath}/" } else { "apply from: '${repo.absolutePath}'" diff --git a/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorJRevealJSTask.groovy b/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorJRevealJSTask.groovy index 720d3e55e..42bd7584a 100644 --- a/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorJRevealJSTask.groovy +++ b/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/AsciidoctorJRevealJSTask.groovy @@ -17,6 +17,7 @@ package org.asciidoctor.gradle.jvm.slides import groovy.transform.CompileStatic import org.asciidoctor.gradle.base.AsciidoctorUtils +import org.asciidoctor.gradle.base.Transform import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask import org.gradle.api.Action import org.gradle.api.file.CopySpec @@ -263,6 +264,7 @@ class AsciidoctorJRevealJSTask extends AbstractAsciidoctorTask { } } + attrs.put 'source-highlighter@', 'highlightjs' attrs } @@ -333,9 +335,9 @@ class AsciidoctorJRevealJSTask extends AbstractAsciidoctorTask { private void generatePluginList(File targetFile,String relativePath) { targetFile.parentFile.mkdirs() - String pluginList = plugins.collect { String fullName -> + String pluginList = Transform.toList(plugins,{ String fullName -> "{ src: '${relativePath}/${fullName}' }" - }.join(',\n') + }).join(',\n') targetFile.withWriter { Writer w -> w.println pluginList @@ -361,9 +363,9 @@ class AsciidoctorJRevealJSTask extends AbstractAsciidoctorTask { } private Set getPluginBundles() { - plugins.collect { + Transform.toSet(plugins) { it.split('/', 2)[0] - } as Set + } } private Set getResolvedPlugins() { diff --git a/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtension.groovy b/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtension.groovy index 88ffab6fe..4f20379f7 100644 --- a/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtension.groovy +++ b/asciidoctor-gradle-jvm-slides/src/main/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtension.groovy @@ -50,6 +50,10 @@ class RevealJSExtension { } } + /** Template is specified locally + * + * @param location Anything convertible to a local file. + */ void templateLocal(Object location) { resolveRevealJs = { -> project.file(location) @@ -72,10 +76,18 @@ class RevealJSExtension { this.resolveRevealJs = revealJsProvider } + /** Set the version of the Reveal.JS backend + * + * @param v Dotted version string. + */ void setVersion(final String v) { this.version = v } + /** The version of the Reveal.js backend. + * + * @return Version string. + */ String getVersion() { this.version } diff --git a/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtensionSpec.groovy b/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtensionSpec.groovy index c244d8cd7..ee8e26f38 100644 --- a/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtensionSpec.groovy +++ b/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSExtensionSpec.groovy @@ -129,6 +129,11 @@ class RevealJSExtensionSpec extends Specification { null } + @Override + def Provider flatMap(Transformer, ? super File> transformer) { + null + } + @Override boolean isPresent() { false diff --git a/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSOptionsSpec.groovy b/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSOptionsSpec.groovy index 9e6dab8f3..b5c92f1a2 100644 --- a/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSOptionsSpec.groovy +++ b/asciidoctor-gradle-jvm-slides/src/test/groovy/org/asciidoctor/gradle/jvm/slides/RevealJSOptionsSpec.groovy @@ -21,7 +21,7 @@ import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification import spock.lang.Unroll -@SuppressWarnings(['MethodName','DuplicateStringLiteral']) +@SuppressWarnings(['MethodName', 'DuplicateStringLiteral']) class RevealJSOptionsSpec extends Specification { Project project = ProjectBuilder.builder().build() @@ -106,7 +106,7 @@ class RevealJSOptionsSpec extends Specification { void 'Set transition to #transition'() { when: - final String attribute = 'transition' + String attribute = 'transition' then: getStringFlag(attribute) == null @@ -137,7 +137,7 @@ class RevealJSOptionsSpec extends Specification { void 'Set background transition to #transition'() { when: - final String attribute = 'backgroundTransition' + String attribute = 'backgroundTransition' then: getStringFlag(attribute) == null @@ -168,7 +168,7 @@ class RevealJSOptionsSpec extends Specification { void 'Set transition speed to #transition'() { when: - final String attribute = 'transitionSpeed' + String attribute = 'transitionSpeed' then: getStringFlag(attribute) == null @@ -198,7 +198,7 @@ class RevealJSOptionsSpec extends Specification { @SuppressWarnings('DuplicateStringLiteral') void 'Set Parallax background size'() { when: - final String attribute = 'parallaxBackgroundSize' + String attribute = 'parallaxBackgroundSize' then: getStringFlag(attribute) == null @@ -294,10 +294,10 @@ class RevealJSOptionsSpec extends Specification { options.asAttributeMap[attribute] == "${relPath}${File.separator}file.img" where: - base | attribute | description + base | attribute | description 'ParallaxBackgroundImage' | 'revealjs_parallaxBackgroundImage' | 'Parallax background image location' 'CustomTheme' | 'revealjs_customtheme' | 'Custom theme location' - 'HighlightJsTheme' | 'highlightjs-theme' | 'Highlight.js theme location' + 'HighlightJsTheme' | 'highlightjs-theme' | 'Highlight.js theme location' } diff --git a/asciidoctor-gradle-jvm/build.gradle b/asciidoctor-gradle-jvm/build.gradle index f5ba6287f..c4d350ab3 100644 --- a/asciidoctor-gradle-jvm/build.gradle +++ b/asciidoctor-gradle-jvm/build.gradle @@ -27,13 +27,10 @@ dependencies { compile project(':asciidoctor-gradle-base') - // This the default jruby-complete version for whichever the default AsciidoctorJ version is - // If the tests start failing becasue the default was changed, then consider changing this. - // It is necessary to have this here as we need tests that simply assume the defaults and we - // need to cater for those offline dependencies. - intTestOfflineRepo "org.jruby:jruby-complete:9.1.12.0", { - transitive = false - } + // These three are used in the compatibility tests for extensions + intTestOfflineRepo "org.codehaus.groovy:groovy:${GroovySystem.version}" + intTestOfflineRepo "org.codehaus.groovy:groovy-ant:${GroovySystem.version}" + intTestOfflineRepo "org.codehaus.groovy:groovy-groovydoc:${GroovySystem.version}" intTestOfflineRepo "org.asciidoctor:asciidoctorj-pdf:${downloadOnlyPdfVersion}" intTestOfflineRepo "org.asciidoctor:asciidoctorj-epub3:${downloadOnlyEpubVersion}" @@ -62,7 +59,7 @@ configurePlugin 'org.asciidoctor.jvm.convert', configurePlugin 'org.asciidoctor.jvm.pdf', 'AsciidoctorJ PDF Conversion Plugin', - 'Simplifies convesion of asciidoc documetns to PDF', + 'Simplifies conversion of asciidoc documents to PDF', ['asciidoctorj', 'pdf'] test { @@ -80,7 +77,7 @@ gradleTest { systemProperties ASCIIDOCTORJ_VERSION: compileOnlyAsciidoctorJVersion systemProperties GROOVY_VERSION: GroovySystem.version - gradleArguments '-i' + gradleArguments '-i', '-s' } // Adding a third test set so that remote execution can be tested using a separate classpath diff --git a/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle b/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle index 922c089df..0ab7813b8 100644 --- a/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle +++ b/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle @@ -45,13 +45,3 @@ asciidoctorPdf { task runGradleTest { dependsOn asciidoctor, asciidoctorPdf } - - -// This is to work around a bug in Gradle. It is not part of normal build script. -// The side affect of this is that we actually get better code coverage as the process mode -// changes depending on which version of Gradle is being tested. -if(System.getProperty('CALLING_GRADLETEST_USES_GROOVY_VERSION') != GroovySystem.version) { - asciidoctorPdf { - inProcess JAVA_EXEC - } -} \ No newline at end of file diff --git a/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle.kts b/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle.kts new file mode 100644 index 000000000..c08daed46 --- /dev/null +++ b/asciidoctor-gradle-jvm/src/gradleTest/complex-jvm-setup/build.gradle.kts @@ -0,0 +1,52 @@ +import org.asciidoctor.gradle.jvm.AsciidoctorPdfTask +import org.asciidoctor.gradle.jvm.AsciidoctorTask +import org.asciidoctor.gradle.jvm.OutputOptions +import org.asciidoctor.gradle.jvm.ProcessMode + +// tag::using-two-plugins-three-backends[] +plugins { + id("org.asciidoctor.jvm.convert") + id("org.asciidoctor.jvm.pdf") +// id("com.gradle.build-scan") version "1.16" +} + +repositories { + jcenter() +} + +asciidoctorj { + setDiagramVersion("1.5.4.1") + logLevel = LogLevel.INFO +} + +tasks.named("asciidoctor") { + outputOptions { + backends("html5", "docbook") + } + + sources ("sample.asciidoc") + resources { + include("images/**") + } + copyResourcesOnlyIf("html5") + useIntermediateWorkDir() +} + +tasks.named("asciidoctorPdf") { + inProcess = ProcessMode.OUT_OF_PROCESS + logDocuments = true + setSourceDir("src/docs/asciidoc") + + sources ("subdir/sample2.ad") + + +// if (findProperty("CALLING_GRADLETEST_USES_GROOVY_VERSION") == "GroovySystem.version") { +// inProcess = ProcessMode.JAVA_EXEC +// } +} +// end::using-two-plugins-three-backends[] + +tasks.register("runGradleTest") { + group = "Custom" + dependsOn("asciidoctor", "asciidoctorPdf") +} diff --git a/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/docs-using-configuration-in-process/build.gradle b/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/docs-using-configuration-in-process/build.gradle index fedce4fe8..532525a39 100644 --- a/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/docs-using-configuration-in-process/build.gradle +++ b/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/docs-using-configuration-in-process/build.gradle @@ -1,4 +1,4 @@ -apply plugin : 'org.asciidoctor.jvm.convert' +apply plugin: 'org.asciidoctor.jvm.convert' configurations { asciidocExt @@ -18,10 +18,10 @@ asciidoctor { } -// This is to work around a bug in Gradle. It is not part of normal build script. -// The side affect of this is that we actually get better code coverage as the process mode -// changes depending on which version of Gradle is being tested. -if(System.getProperty('CALLING_GRADLETEST_USES_GROOVY_VERSION') != GroovySystem.version) { +// Gradle leak unnecessary JARs onto the classpath. Since this project is now +// built with Gradle 5.x, we are swapping back to JAVA_EXEC if testing against +// Gradle 4.x +if (gradle.gradleVersion.startsWith('4.')) { asciidoctor { inProcess JAVA_EXEC } diff --git a/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/extension/build.gradle b/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/extension/build.gradle index b21d3c60d..6dc123a25 100644 --- a/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/extension/build.gradle +++ b/asciidoctor-gradle-jvm/src/gradleTest/extension-in-subproject/extension/build.gradle @@ -4,7 +4,7 @@ plugins { dependencies { - compileOnly "org.codehaus.groovy:groovy-all:${System.getProperty('GROOVY_VERSION')}" + compileOnly "org.codehaus.groovy:groovy:${System.getProperty('GROOVY_VERSION')}" compileOnly "org.asciidoctor:asciidoctorj:${System.getProperty('ASCIIDOCTORJ_VERSION')}" } diff --git a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/internal/FunctionalSpecification.groovy b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/internal/FunctionalSpecification.groovy index 5504f4560..bdfb7faff 100644 --- a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/internal/FunctionalSpecification.groovy +++ b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/internal/FunctionalSpecification.groovy @@ -22,7 +22,6 @@ import org.asciidoctor.gradle.testfixtures.jvm.FunctionalTestSetup import org.gradle.testkit.runner.GradleRunner import org.junit.Rule import org.junit.rules.TemporaryFolder -import spock.lang.Shared import spock.lang.Specification import static org.asciidoctor.gradle.testfixtures.jvm.DslType.GROOVY_DSL @@ -38,7 +37,7 @@ class FunctionalSpecification extends Specification { final String TEST_REPO_DIR = System.getProperty('OFFLINE_REPO') ?: './testfixtures/offline-repo/build/repo' @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() + TemporaryFolder testProjectDir @CompileStatic GradleRunner getGradleRunner(List taskNames = ['asciidoctor']) { @@ -85,7 +84,7 @@ class FunctionalSpecification extends Specification { } String getDefaultProcessModeForAppveyor(final DslType dslType = GROOVY_DSL) { - if(System.getenv('APPVEYOR')) { + if (System.getenv('APPVEYOR')) { dslType == GROOVY_DSL ? 'inProcess = JAVA_EXEC' : 'inProcess = ProcessMode.JAVA_EXEC' } else { '' diff --git a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/ExtensionsFunctionalSpec.groovy b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/ExtensionsFunctionalSpec.groovy index 17cb8a473..d934f3785 100644 --- a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/ExtensionsFunctionalSpec.groovy +++ b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/ExtensionsFunctionalSpec.groovy @@ -30,7 +30,7 @@ import static org.asciidoctor.gradle.testfixtures.jvm.AsciidoctorjTestVersions.* @SuppressWarnings(['MethodName', 'DuplicateStringLiteral']) class ExtensionsFunctionalSpec extends FunctionalSpecification { - static final List DEFAULT_ARGS = ['asciidoctor', '-s'] + static final List DEFAULT_ARGS = ['asciidoctor', '-s', '-i'] static final String ASCIIDOC_INLINE_EXTENSIONS_FILE = 'inlineextensions.asciidoc' static final String GLOBAL = 'project' diff --git a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/RequiresFunctionalSpec.groovy b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/RequiresFunctionalSpec.groovy index d00f9ffe6..36c086867 100644 --- a/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/RequiresFunctionalSpec.groovy +++ b/asciidoctor-gradle-jvm/src/intTest/groovy/org/asciidoctor/gradle/jvm/RequiresFunctionalSpec.groovy @@ -91,7 +91,7 @@ class RequiresFunctionalSpec extends FunctionalSpecification { """) when: - final BuildResult firstInvocationResult = getGradleRunner(DEFAULT_ARGS).build() + final BuildResult firstInvocationResult = getGradleRunner(['-i'] + DEFAULT_ARGS).build() File outputFolder = new File(testProjectDir.root, 'build/docs/asciidoc') File outputFile = new File(outputFolder, 'ditaa.html') diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/compat/AsciidoctorCompatibilityTask.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/compat/AsciidoctorCompatibilityTask.groovy index 427816d46..b985751cf 100755 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/compat/AsciidoctorCompatibilityTask.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/compat/AsciidoctorCompatibilityTask.groovy @@ -22,6 +22,7 @@ import org.asciidoctor.gradle.internal.ExecutorConfiguration import org.asciidoctor.gradle.internal.ExecutorConfigurationContainer import org.asciidoctor.gradle.internal.ExecutorLogLevel import org.asciidoctor.gradle.internal.JavaExecUtils +import org.asciidoctor.gradle.base.Transform import org.asciidoctor.gradle.remote.AsciidoctorJavaExec import org.gradle.api.DefaultTask import org.gradle.api.InvalidUserDataException @@ -37,6 +38,8 @@ import org.gradle.internal.FileUtils import org.gradle.process.JavaExecSpec import org.ysb33r.grolifant.api.OperatingSystem +import java.util.stream.Collectors + import static org.asciidoctor.gradle.base.AsciidoctorUtils.* import static org.asciidoctor.gradle.jvm.AsciidoctorJExtension.GUAVA_REQUIRED_FOR_EXTERNALS import static org.asciidoctor.gradle.internal.JavaExecUtils.getJavaExecClasspath @@ -424,7 +427,9 @@ class AsciidoctorCompatibilityTask extends DefaultTask { @OutputDirectories Set getOutputDirectories() { if (separateOutputDirs) { - backends.collect { new File(outputDir, it) } as Set + backends.stream().map({ + new File(outputDir, it) + }).collect(Collectors.toSet()) } else { [outputDir] as Set } @@ -550,7 +555,7 @@ class AsciidoctorCompatibilityTask extends DefaultTask { } finalAttributes.putAll(attributes) - ExecutorConfigurationContainer ecc = new ExecutorConfigurationContainer(activeBackends().collect { backend -> + ExecutorConfigurationContainer ecc = new ExecutorConfigurationContainer(activeBackends().stream().map( { backend -> new ExecutorConfiguration( sourceDir: sourceDir, outputDir: outputBackendDir(output, backend), @@ -571,13 +576,13 @@ class AsciidoctorCompatibilityTask extends DefaultTask { asciidoctorExtensions: dehydrateExtensions(getAsciidoctorExtensions()), executorLogLevel: ExecutorLogLevel.WARN ) - }) + }).collect(Collectors.toList())) Set closurePaths = getAsciidoctorExtensions().findAll { it instanceof Closure - }.collect { + }.stream().map({ getClassLocation(it.class) - }.toSet() + }).collect(Collectors.toSet()) closurePaths.add(getClassLocation(org.gradle.internal.scripts.ScriptOrigin)) FileCollection javaExecClasspath = project.files( @@ -650,8 +655,8 @@ class AsciidoctorCompatibilityTask extends DefaultTask { } } - private List dehydrateExtensions(final Iterable exts) { - exts.collect { + private List dehydrateExtensions(final List exts) { + Transform.toList(exts){ switch (it) { case Closure: ((Closure) it).dehydrate() @@ -659,12 +664,12 @@ class AsciidoctorCompatibilityTask extends DefaultTask { default: it } - } as List + } } @CompileDynamic private static List stringifyList(List input) { - input.collect { element -> + Transform.toList(input) { element -> if (element instanceof CharSequence) { element.toString() } else if (element instanceof List) { @@ -720,7 +725,7 @@ class AsciidoctorCompatibilityTask extends DefaultTask { transformedMap = attributes break case CharSequence: - attributes.replaceAll('([^\\\\]) ', '$1\0').replaceAll('\\\\ ', ' ').split('\0').collect { + Transform.toList(attributes.replaceAll('([^\\\\]) ', '$1\0').replaceAll('\\\\ ', ' ').split('\0') as List) { def split = it.split('=') if (split.size() < 2) { throw new InvalidUserDataException("Unsupported format for attributes: ${attributes}") diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/internal/JavaExecUtils.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/internal/JavaExecUtils.groovy index 20ce14ccc..012dc9d88 100644 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/internal/JavaExecUtils.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/internal/JavaExecUtils.groovy @@ -20,18 +20,23 @@ import org.asciidoctor.gradle.remote.AsciidoctorJavaExec import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.FileCollection +import org.gradle.util.GradleVersion import org.ysb33r.grolifant.api.FileUtils import static org.asciidoctor.gradle.base.AsciidoctorUtils.getClassLocation /** Utilities for dealing with Asciidoctor in an external JavaExec process. * - * @since 2.0 - * @author Sdhalk W. Cronjé + * @since 2.0* @author Sdhalk W. Cronjé */ @CompileStatic class JavaExecUtils { + /** The name of the Guava JAR used internally by Gradle. + * + */ + public static final String INTERNAL_GUAVA_NAME = internalGuavaName() + /** Get the classpath that needs to be passed to the external Java process. * * @param project Current Gradle project @@ -49,7 +54,7 @@ class JavaExecUtils { FileCollection fc = project.files(entryPoint, groovyJar, asciidoctorClasspath) - addInternalGuava ? project.files(fc, new File(project.gradle.gradleHomeDir, 'lib/guava-jdk5-17.0.jar')) : fc + addInternalGuava ? project.files(fc, new File(project.gradle.gradleHomeDir, "lib/${INTERNAL_GUAVA_NAME}")) : fc } /** The file to which execution configuration data can be serialised to. @@ -74,4 +79,20 @@ class JavaExecUtils { ExecutorConfigurationContainer.toFile(execConfigurationData, executorConfigurations) execConfigurationData } + + /** Returns the location of the local Groovy Jar that is used by Gradle. + * + * @return Location on filesysetm where the Groovy Jar is located. + */ + static File getLocalGroovy() { + getClassLocation(GroovyObject) + } + + private static String internalGuavaName() { + if (GradleVersion.current() >= GradleVersion.version('5.0')) { + 'guava-26.0-android.jar' + } else { + 'guava-jdk5-17.0.jar' + } + } } diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AbstractAsciidoctorTask.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AbstractAsciidoctorTask.groovy index e9ca84a32..08313bbf7 100644 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AbstractAsciidoctorTask.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AbstractAsciidoctorTask.groovy @@ -22,6 +22,7 @@ import org.asciidoctor.gradle.internal.ExecutorConfiguration import org.asciidoctor.gradle.internal.ExecutorConfigurationContainer import org.asciidoctor.gradle.internal.ExecutorUtils import org.asciidoctor.gradle.internal.JavaExecUtils +import org.asciidoctor.gradle.base.Transform import org.asciidoctor.gradle.remote.AsciidoctorJExecuter import org.asciidoctor.gradle.remote.AsciidoctorJavaExec import org.gradle.api.Action @@ -69,7 +70,7 @@ class AbstractAsciidoctorTask extends DefaultTask { final static ProcessMode JAVA_EXEC = ProcessMode.JAVA_EXEC @Internal - protected final static GradleVersion LAST_GRADLE_WITH_CLASSPATH_LEAKAGE = GradleVersion.version(('5.0')) + protected final static GradleVersion LAST_GRADLE_WITH_CLASSPATH_LEAKAGE = GradleVersion.version(('5.99')) @Nested protected final OutputOptions configuredOutputOptions = new OutputOptions() @@ -100,7 +101,7 @@ class AbstractAsciidoctorTask extends DefaultTask { /** Run Asciidoctor conversions in or out of process * * Valid options are {@link #IN_PROCESS}, {@link #OUT_OF_PROCESS} and {@link #JAVA_EXEC}. - * + * The default mode is {@link #JAVA_EXEC}. */ @Internal ProcessMode inProcess = JAVA_EXEC @@ -276,7 +277,9 @@ class AbstractAsciidoctorTask extends DefaultTask { */ @OutputDirectories Set getBackendOutputDirectories() { - configuredOutputOptions.backends.collect { getOutputDirFor(it) } as Set + Transform.toSet(configuredOutputOptions.backends) { + String it -> getOutputDirFor(it) + } } /** Base directory (current working directory) for a conversion. @@ -285,7 +288,7 @@ class AbstractAsciidoctorTask extends DefaultTask { */ // IMPORTANT: Do not change this to @InputDirectory as it can lead to file locking issues on // Windows. In reality we do not need to track contents of the directory - // simply the value change, we tarck this via a normal property + // simply the value change - we achieve that via a normal property. @Internal File getBaseDir() { this.baseDir != null ? project.file(this.baseDir) : project.projectDir @@ -293,12 +296,10 @@ class AbstractAsciidoctorTask extends DefaultTask { /** Sets the base directory for a conversion. * - * The base directory is used by AsciidoctorJ to set a curretn working directory for + * The base directory is used by AsciidoctorJ to set a current working directory for * a conversion. * - * If never set, then {@code project.projectDir ( )} will be assumed to be the base directory. - * - * WHen {@link} + * If never set, then {@code project.projectDir} will be assumed to be the base directory. * * @param f Base directory */ @@ -377,8 +378,8 @@ class AbstractAsciidoctorTask extends DefaultTask { /** Additional providers of attributes. * - * NOTE: Attributes added via providers do no change th up-to-date status of the task. - * Providers are therefore usfeul to add attributes such as build time. + * NOTE: Attributes added via providers do no change the up-to-date status of the task. + * Providers are therefore useful to add attributes such as build time. * * @return List of attribute providers. */ @@ -447,7 +448,7 @@ class AbstractAsciidoctorTask extends DefaultTask { /** Returns all of the specified configurations as a collections of files. * - * If any extensions are dependencies then they w2ill be included here too. + * If any extensions are dependencies then they will be included here too. * * @return FileCollection */ @@ -785,7 +786,7 @@ class AbstractAsciidoctorTask extends DefaultTask { * * Some incompatibilities can cause certain process mode to fail given a combination of factors. * - * Task implementations can override this method to select a safte process mode, than the one provided by the + * Task implementations can override this method to select a safe process mode, than the one provided by the * build script author. The default implementation will simply return whatever what was configured, except in the * case for Gradle 4.3 or older in which case it will always return {@link #JAVA_EXEC}. * @@ -943,15 +944,14 @@ class AbstractAsciidoctorTask extends DefaultTask { it instanceof Dependency } as List - Set closurePaths = asciidoctorj.extensions.findAll { - it instanceof Closure - }.collect { + Set closurePaths = Transform.toSet(findExtensionClosures()){ getClassLocation(it.class) - }.toSet() + } if (!closurePaths.empty) { // Jumping through hoops to make extensions based upon closures to work. closurePaths.add(getClassLocation(org.gradle.internal.scripts.ScriptOrigin)) + closurePaths.addAll(ifNoGroovyAddLocal(deps)) } if (deps.empty && closurePaths.empty) { @@ -965,6 +965,16 @@ class AbstractAsciidoctorTask extends DefaultTask { } } + private List ifNoGroovyAddLocal(final List deps) { + if(deps.find { + it.name == 'groovy-all' || it.name == 'groovy' + }) { + [] + } else { + [JavaExecUtils.localGroovy] + } + } + @CompileDynamic private Configuration jrubyLessConfiguration(List deps) { Configuration cfg = project.configurations.detachedConfiguration(deps.toArray() as Dependency[]) @@ -999,10 +1009,16 @@ class AbstractAsciidoctorTask extends DefaultTask { Map defaultAttrs = getTaskSpecificDefaultAttributes(workingSourceDir).findAll { k,v -> !userDefinedAttrKeys.contains(k) }.collectEntries { k,v -> - [ "${k}@".toString(), v ] + [ "${k}@".toString(), v instanceof Serializable ? v : StringUtils.stringize(v) ] } as Map attrs.putAll(defaultAttrs) evaluateProviders(attrs) } + + private List findExtensionClosures() { + asciidoctorj.extensions.findAll { + it instanceof Closure + } as List + } } diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorJExtension.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorJExtension.groovy index 366660bb8..2c09f4b0c 100644 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorJExtension.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorJExtension.groovy @@ -19,8 +19,10 @@ import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import org.asciidoctor.gradle.base.AsciidoctorAttributeProvider import org.asciidoctor.gradle.base.SafeMode +import org.asciidoctor.gradle.base.Transform import org.gradle.api.Action import org.gradle.api.GradleException +import org.gradle.api.NonExtensible import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.Configuration @@ -46,6 +48,7 @@ import static org.ysb33r.grolifant.api.StringUtils.stringize */ @CompileStatic @SuppressWarnings('MethodCount') +@NonExtensible class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { // ------------------------------------------------------------------------ @@ -54,11 +57,11 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { // It is also a good idea that DEFAULT_ASCIIDOCTORJ_VERSION matches one of // the values in testfixtures-jvm. // ------------------------------------------------------------------------ - final static String DEFAULT_ASCIIDOCTORJ_VERSION = '1.6.1' - final static String DEFAULT_GROOVYDSL_VERSION = '1.6.0-alpha.2' + final static String DEFAULT_ASCIIDOCTORJ_VERSION = '1.6.2' + final static String DEFAULT_GROOVYDSL_VERSION = '1.6.0' final static String DEFAULT_PDF_VERSION = '1.5.0-alpha.16' final static String DEFAULT_EPUB_VERSION = '1.5.0-alpha.8.1' - final static String DEFAULT_DIAGRAM_VERSION = '1.5.8' + final static String DEFAULT_DIAGRAM_VERSION = '1.5.16' // ------------------------------------------------------------------------ static final String ASCIIDOCTORJ_GROUP = 'org.asciidoctor' @@ -129,7 +132,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { super(task, NAME) } - /** Whether the Guava JAR that ships with the Gradle sustribution should be injected into the + /** Whether the Guava JAR that ships with the Gradle distribution should be injected into the * classpath for external AsciidoctorJ processes. * * If not set previously via {@link #setInjectInternalGuavaJar} then a default version depending of the version of @@ -145,7 +148,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { } } - /** Whether the Guava JAR that ships with the Gradle sustribution should be injected into the + /** Whether the Guava JAR that ships with the Gradle distribution should be injected into the * classpath for external AsciidoctorJ processes. * * @param inject {@code true} if JAR should be injected. @@ -535,8 +538,6 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { final String jrubyVer = getJrubyVersion() ?: minimumSafeJRubyVersion(getVersion()) final String jrubyCompleteDep = "${JRUBY_COMPLETE_DEPENDENCY}:${jrubyVer}" - final boolean isAsciidoctor15series = getVersion().startsWith('1.5') - List deps = [createDependency("${ASCIIDOCTORJ_CORE_DEPENDENCY}:${getVersion()}")] if (gDslVer != null) { @@ -565,13 +566,9 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { deps.toArray() as Dependency[] ) - if (!isAsciidoctor15series) { - configuration.resolutionStrategy.eachDependency { DependencyResolveDetails dsr -> - dsr.with { - if (target.name == 'jruby' && target.group == 'org.jruby') { - useTarget "${JRUBY_COMPLETE_DEPENDENCY}:${target.version}" - } - } + configuration.resolutionStrategy.eachDependency { DependencyResolveDetails dsr -> + if (dsr.target.name == 'jruby' && dsr.target.group == 'org.jruby') { + dsr.useTarget "${JRUBY_COMPLETE_DEPENDENCY}:${dsr.target.version}" } } @@ -585,7 +582,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { /** Return extensionRegistry. * * These extensionRegistry are not registered at this call. That action is left - * to the specific task at i'ts execution time. + * to the specific task at its execution time. * * @return */ @@ -614,7 +611,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { */ void setExtensions(Iterable newExtensions) { asciidoctorExtensions.clear() - addExtensions(newExtensions) + addExtensions(newExtensions as List) onlyTaskExtensions = true } @@ -696,7 +693,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { /** Provide patterns for Asciidoctor messages that are treated as failures. * - * Clears any existing message patterns. If this ethid is called on a task extension, + * Clears any existing message patterns. If this method is called on a task extension, * the patterns from the project extension will be ignored. * * @param patterns @@ -753,7 +750,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { } private List stringizeScalarListItems(List list) { - list.collect { item -> + Transform.toList(list) { item -> switch (item) { case List: return stringizeScalarListItems((List) item) @@ -804,13 +801,13 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { } } - /** Adds extensions to the existig container. + /** Adds extensions to the existing container. * * Also sets the Groovy DSL version if required. * * @param newExtensions List of new extensiosn to add */ - private void addExtensions(Iterable newExtensions) { + private void addExtensions(List newExtensions) { setDefaultGroovyDslVersionIfRequired() asciidoctorExtensions.addAll(dehydrateExtensions(newExtensions)) } @@ -823,8 +820,8 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { * @return List of extensions suitable for serialization. * */ - private List dehydrateExtensions(final Iterable exts) { - exts.collect { + private List dehydrateExtensions(final List exts) { + Transform.toList(exts){ switch (it) { case Closure: ((Closure) it).dehydrate() @@ -835,7 +832,7 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { default: it } - } as List + } } @SuppressWarnings('UnusedPrivateMethodParameter') @@ -845,9 +842,9 @@ class AsciidoctorJExtension extends AbstractCombinedProjectTaskExtension { @SuppressWarnings('Instanceof') private List patternize(final List patterns) { - patterns.collect { - it instanceof Pattern ? it : ~/${stringize(it)}/ - } as List + Transform.toList(patterns){ + (Pattern)(it instanceof Pattern ? it : ~/${stringize(it)}/) + } } @CompileDynamic diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorPdfTask.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorPdfTask.groovy index 9b95d09bb..cdb53ac4d 100644 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorPdfTask.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorPdfTask.groovy @@ -67,7 +67,7 @@ class AsciidoctorPdfTask extends AbstractAsciidoctorTask { this.fontsDir = f } - /** Set the tehem to be used from the {@code pdfThemes} extension. + /** Set the theme to be used from the {@code pdfThemes} extension. * * @param themeName */ diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorTask.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorTask.groovy index 8231a2099..f673c9dbf 100755 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorTask.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/jvm/AsciidoctorTask.groovy @@ -91,7 +91,7 @@ class AsciidoctorTask extends AbstractAsciidoctorTask { * If the backends contain {@code docbook} then {@code *docbook*.xml} is added. * If the backend contain {@code html5} then {@code *docbook*.html} is added. * - * @return Defaui + * @return Default pattern set. */ @Override protected PatternSet getDefaultSecondarySourceDocumentPattern() { diff --git a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/remote/ExecutorBase.groovy b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/remote/ExecutorBase.groovy index 8afafdb8e..50e2c9a1f 100644 --- a/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/remote/ExecutorBase.groovy +++ b/asciidoctor-gradle-jvm/src/main/groovy/org/asciidoctor/gradle/remote/ExecutorBase.groovy @@ -87,12 +87,10 @@ abstract class ExecutorBase { mergedOptions[Options.TO_FILE] = new File(toDir, toFile.name).absolutePath } - // Note: Directories passed as relative to work around issue #83 - // Asciidoctor cannot handle absolute paths in Windows properly Map newAttrs = [:] newAttrs.putAll(attributes) - newAttrs['gradle-projectdir'] = getRelativePath(projectDir, file.parentFile) - newAttrs['gradle-rootdir'] = getRelativePath(rootDir, file.parentFile) + newAttrs['gradle-projectdir'] = projectDir.absolutePath + newAttrs['gradle-rootdir'] = rootDir.absolutePath if(legacyAttributes) { newAttrs['projectdir'] = newAttrs['gradle-projectdir'] @@ -124,17 +122,19 @@ abstract class ExecutorBase { * @return */ protected List rehydrateExtensions(final Object registry, final List exts) { - exts.collect { - switch (it) { + final List availableExtensions = [] + for( Object ext in exts) { + switch (ext) { case Closure: - Closure rehydrated = ((Closure) it).rehydrate(registry, null, null) + Closure rehydrated = ((Closure) ext).rehydrate(registry, null, null) rehydrated.resolveStrategy = Closure.DELEGATE_ONLY - (Object) rehydrated + availableExtensions.add((Object) rehydrated) break default: - it + availableExtensions.add(ext) } - } as List + } + availableExtensions } /** Creates a log handler for Asciidoctor diff --git a/asciidoctor-gradle-jvm/src/remoteTest/groovy/org/asciidoctor/gradle/remote/internal/RemoteSpecification.groovy b/asciidoctor-gradle-jvm/src/remoteTest/groovy/org/asciidoctor/gradle/remote/internal/RemoteSpecification.groovy index 483ec181c..616007246 100644 --- a/asciidoctor-gradle-jvm/src/remoteTest/groovy/org/asciidoctor/gradle/remote/internal/RemoteSpecification.groovy +++ b/asciidoctor-gradle-jvm/src/remoteTest/groovy/org/asciidoctor/gradle/remote/internal/RemoteSpecification.groovy @@ -34,7 +34,7 @@ class RemoteSpecification extends Specification { static final String DOCBOOK = 'docbook' @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() + TemporaryFolder testProjectDir Map getProject(File base) { File src = new File(base, 'src') diff --git a/build.gradle b/build.gradle index 642b35a71..c6bb986d5 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id 'com.gradle.build-scan' version '1.16' + id 'com.gradle.build-scan' version '2.0.2' id 'com.jfrog.bintray' version '1.8.0' apply false id 'net.nemerosa.versioning' version '2.6.1' apply false id 'com.github.ben-manes.versions' version '0.17.0' apply false @@ -25,11 +25,12 @@ plugins { id 'net.ossindex.audit' version '0.1.1' apply false id 'org.kordamp.jdeps' version '0.2.0' apply false id 'fi.linuxbox.download.worker' version '0.3' apply false - id 'org.ysb33r.ivypot' version '0.8' apply false + id 'org.ysb33r.ivypot' version '0.9' apply false id 'org.ysb33r.os' version '0.9' apply false - id 'org.ysb33r.cloudci' version '2.3' apply false - id 'org.ysb33r.cloudci.appveyor.testreporter' version '2.3' apply false - id 'org.ysb33r.gradletest' version '2.0-beta.3' apply false + id 'org.ysb33r.cloudci' version '2.5' apply false + id 'org.ysb33r.cloudci.appveyor.testreporter' version '2.5' apply false + id 'org.ysb33r.gradletest' version '2.0-rc.4' apply false + id 'idea' } buildScan { @@ -63,13 +64,11 @@ allprojects { offlineRepoDescriptionFile = file("${offlineRepoRoot}/repositories.gradle") withoutIntegrationTests = [ - 'asciidoctor-gradle-base', 'asciidoctor-gradle-jvm-gems', 'kindlegen-gradle' ] withoutCompatibilityTests = [ - 'asciidoctor-gradle-base', 'kindlegen-gradle' ] @@ -167,3 +166,8 @@ subprojects { apply from : 'gradle/coveralls.gradle' +//idea { +// extended { +// workspace.junit.tasks = ['classes', 'pluginUnderTestMetadata'] +// } +//} diff --git a/config/codenarc/codenarc.groovy b/config/codenarc/codenarc.groovy index 33bd184c6..504f52f3b 100755 --- a/config/codenarc/codenarc.groovy +++ b/config/codenarc/codenarc.groovy @@ -24,17 +24,18 @@ ruleset { } ruleset('rulesets/naming.xml') { exclude 'PropertyName' - 'ClassName' { + ClassName { regex = '^[A-Z][a-zA-Z0-9]*$' } - 'FieldName' { + FieldName { finalRegex = '^_?[a-z][a-zA-Z0-9]*$' staticFinalRegex = '^[A-Z][A-Z_0-9]*$' } - 'MethodName' { + MethodName { regex = '^[a-z][a-zA-Z0-9_]*$' + doNotApplyToFileNames = '*/test/*/*Spec.groovy,*/*Test/*/*Spec.groovy,*/test/*/*Specification.groovy,*/*Test/*/*Specification.groovy' } - 'VariableName' { + VariableName { finalRegex = '^_?[a-z][a-zA-Z0-9]*$' } } @@ -47,9 +48,21 @@ ruleset { ruleset('rulesets/size.xml') { exclude 'CrapMetric' } - ruleset('rulesets/junit.xml') ruleset('rulesets/unnecessary.xml') - ruleset('rulesets/dry.xml') + ruleset('rulesets/dry.xml') { + DuplicateListLiteral { + doNotApplyToFileNames = '*/test/*/*Spec.groovy,*/*Test/*/*Spec.groovy,*/test/*/*Specification.groovy,*/*Test/*/*Specification.groovy' + } + DuplicateMapLiteral { + doNotApplyToFileNames = '*/test/*/*Spec.groovy,*/*Test/*/*Spec.groovy,*/test/*/*Specification.groovy,*/*Test/*/*Specification.groovy' + } + DuplicateNumberLiteral { + doNotApplyToFileNames = '*/test/*/*Spec.groovy,*/*Test/*/*Spec.groovy,*/test/*/*Specification.groovy,*/*Test/*/*Specification.groovy' + } + DuplicateStringLiteral { + doNotApplyToFileNames = '*/test/*/*Spec.groovy,*/*Test/*/*Spec.groovy,*/test/*/*Specification.groovy,*/*Test/*/*Specification.groovy' + } + } ruleset('rulesets/design.xml') { exclude 'Instanceof' } diff --git a/gradle.properties b/gradle.properties index 63c975aca..c9d574814 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,7 +16,7 @@ bintray_dryRun = false cglibVersion = 3.2.6 jsoupVersion = 1.11.2 -spockVersion = 1.2-groovy-2.4 +spockVersion = 1.2-groovy-2.5 grolifantVersion = 0.10 jacocoVersion = 0.8.1 jrubyGradleVersion = 1.6.0 diff --git a/gradle/ci.gradle b/gradle/ci.gradle index ee0742c1f..71eac7fd2 100644 --- a/gradle/ci.gradle +++ b/gradle/ci.gradle @@ -1,6 +1,7 @@ -apply plugin : 'org.ysb33r.cloudci' +apply plugin: 'org.ysb33r.cloudci' -cloudci.any { +ci { + any_ci { ext { logBeforeTest = { desc -> project.logger.lifecycle "Running: ${desc.name} (${desc.className})" @@ -8,19 +9,19 @@ cloudci.any { logAfterTest = { testTracker, descriptor, result -> String key = "${descriptor.name} (${descriptor.className})" long time = result.endTime - result.startTime - if(result.resultType == org.gradle.api.tasks.testing.TestResult.ResultType.FAILURE) { - project.logger.lifecycle "FAILED (${time}s): ${key}", + if (result.resultType == org.gradle.api.tasks.testing.TestResult.ResultType.FAILURE) { + project.logger.lifecycle " FAILED (${time}s): ${key}", result.exceptions, testTracker.containsKey(key) ? testTracker[key] : '' } else { - project.logger.lifecycle "Completed (${time}s): ${key}" + project.logger.lifecycle " Completed (${time}s): ${key}" } } testOutputListener = { testTracker, descriptor, outputEvent -> String n = "${descriptor.name} (${descriptor.className})" - if(testTracker.containsKey(n)) { + if (testTracker.containsKey(n)) { testTracker[n] = "${testTracker[n]}\n${outputEvent.message}" } else { testTracker[n] = outputEvent.message @@ -35,8 +36,8 @@ cloudci.any { } beforeTest logBeforeTest afterTest logAfterTest.curry(testTracker) - addTestOutputListener (testOutputListener.curry(testTracker) as TestOutputListener) + addTestOutputListener(testOutputListener.curry(testTracker) as TestOutputListener) } } } - +} diff --git a/gradle/code-quality.gradle b/gradle/code-quality.gradle index 5a796546b..fa79c9707 100644 --- a/gradle/code-quality.gradle +++ b/gradle/code-quality.gradle @@ -35,6 +35,14 @@ codenarc { sourceSets = [project.sourceSets.main] } +// +//tasks.withType(CodeNarc) { codenarcSourceSetTask -> +// def reportName = (codenarcSourceSetTask.name - "codenarc").uncapitalize() +// def ideReport = reports.add(org.gradle.api.reporting.internal.TaskGeneratedSingleFileReport.TaskGeneratedSingleFileReport, "ide", reports.task) +// ideReport.enabled = true +// ideReport.destination = file( "${project.codenarc.reportsDir}/${reportName}.ide.txt") +//} + pluginManager.withPlugin('jacoco') { jacocoTestReport { reports { @@ -45,3 +53,16 @@ pluginManager.withPlugin('jacoco') { } } + +task codenarcAll { + group 'verification' + description 'Lifecycle task for all codenarc tasks' +} + +tasks.withType(CodeNarc) { t -> + tasks.codenarcAll.dependsOn t + + if(t.name =~ /.+GradleTest.*/) { + t.enabled = false + } +} diff --git a/gradle/compatibility-tests.gradle b/gradle/compatibility-tests.gradle index 87e21b364..a7d76f69c 100644 --- a/gradle/compatibility-tests.gradle +++ b/gradle/compatibility-tests.gradle @@ -1,18 +1,37 @@ -apply plugin : 'org.ysb33r.gradletest' - -gradleTest { - - versions '4.10.2', '5.0-rc-5' - - if(JavaVersion.current().java11) { - versions '4.8.1' - } else if(JavaVersion.current().java10) { - versions '4.7' - } else { - versions '4.0.2', '4.3.1', '4.6' +apply plugin: 'org.ysb33r.gradletest' + +pluginManager.withPlugin('org.ysb33r.cloudci') { + ci { + travisci { + gradleTest { + if (JavaVersion.current().java11) { + versions '4.8.1', '5.3' + } else { + versions '4.0.2', '5.1.1' + } + } + } + appveyor { + gradleTest { + versions '4.0.2', '4.10.2', '5.0', '5.3' + } + } + no_ci { + gradleTest { + if (JavaVersion.current().java11) { + versions '4.8.1', '5.0', '5.1.1', '5.3' + } else if (JavaVersion.current().java10) { + versions '4.7', '5.0', '5.1.1' + } else { + versions '4.0.2', '5.0', '5.1.1', '5.3' + } + } + } } +} - if(tasks.findByName('intTest')) { +gradleTest { + if (tasks.findByName('intTest')) { mustRunAfter 'intTest' } @@ -20,11 +39,6 @@ gradleTest { dependsOn ':testfixtures-offline-repo:buildOfflineRepositories' systemProperties OFFLINE_REPO: offlineRepoRoot.absolutePath - systemProperties CALLING_GRADLETEST_USES_GROOVY_VERSION: GroovySystem.version -} - -configurations { - gradleTestRuntime.extendsFrom testRuntime } @@ -35,4 +49,4 @@ pluginManager.withPlugin('jacoco') { executionData gradleTest mustRunAfter gradleTest } -} \ No newline at end of file +} diff --git a/gradle/coveralls.gradle b/gradle/coveralls.gradle index 327aff7c0..ce0588c64 100644 --- a/gradle/coveralls.gradle +++ b/gradle/coveralls.gradle @@ -20,7 +20,7 @@ task jacocoRootReport(dependsOn: jacocoRootMerge, type: JacocoReport) { group = 'Reporting' description = 'Aggregate Jacoco coverage reports.' - executionData = files(jacocoRootMerge.destinationFile) + executionData.setFrom(jacocoRootMerge.destinationFile) reports { html.enabled = true @@ -37,6 +37,8 @@ coveralls { subprojects { pluginManager.withPlugin('jacoco') { + + rootProject.jacocoRootMerge.dependsOn jacocoTestReport rootProject.jacocoRootMerge.executionData jacocoTestReport.executionData rootProject.jacocoRootReport.sourceSets sourceSets.main diff --git a/gradle/gradle-plugin-dependencies.gradle b/gradle/gradle-plugin-dependencies.gradle index 8027d9100..ef6193722 100644 --- a/gradle/gradle-plugin-dependencies.gradle +++ b/gradle/gradle-plugin-dependencies.gradle @@ -1,12 +1,6 @@ import org.gradle.util.GradleVersion dependencies { - // BUG: https://github.com/gradle/gradle/issues/3698 - // TODO: We use a dependency on groovy-all rather than localGroovy. This - // works around a bug in the worker API known to be in Gradle 4.0-4.9 - //compile localGroovy() - compile "org.codehaus.groovy:groovy-all:${GroovySystem.version}" - compile gradleApi() compile "org.ysb33r.gradle:grolifant:${grolifantVersion}" @@ -14,7 +8,6 @@ dependencies { if(configurations.findByName('intTestCompile')) { intTestCompile project(':testfixtures-jvm') -// intTestRuntime files(createClasspathManifest) } } diff --git a/gradle/standard-repositories.gradle b/gradle/standard-repositories.gradle index 7291a6734..5ac120fa9 100644 --- a/gradle/standard-repositories.gradle +++ b/gradle/standard-repositories.gradle @@ -1,5 +1,6 @@ repositories { jcenter() + mavenCentral() if(version.endsWith('-SNAPSHOT')) { mavenLocal() } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 758de960e..87b738cbd 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0b3fb8d7..558870dad 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d51..af6708ff2 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index e95643d6a..0f8d5937c 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/kindlegen-gradle/build.gradle b/kindlegen-gradle/build.gradle index 8ed3cf92d..6aa0eff5b 100644 --- a/kindlegen-gradle/build.gradle +++ b/kindlegen-gradle/build.gradle @@ -19,7 +19,7 @@ test { pluginManager.withPlugin('jacoco') { jacocoTestReport { - executionData = (fileTree('.') { exclude '**' }) + executionData.setFrom(fileTree('.') { exclude '**' }) executionData test } } diff --git a/kindlegen-gradle/src/test/groovy/org/asciidoctor/gradle/kindlegen/internal/FunctionalSpecification.groovy b/kindlegen-gradle/src/test/groovy/org/asciidoctor/gradle/kindlegen/internal/FunctionalSpecification.groovy index ce975508b..a4d5b58a5 100644 --- a/kindlegen-gradle/src/test/groovy/org/asciidoctor/gradle/kindlegen/internal/FunctionalSpecification.groovy +++ b/kindlegen-gradle/src/test/groovy/org/asciidoctor/gradle/kindlegen/internal/FunctionalSpecification.groovy @@ -23,7 +23,7 @@ import spock.lang.Specification class FunctionalSpecification extends Specification { @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() + TemporaryFolder testProjectDir @Shared List pluginClasspath diff --git a/run-compatibility-test-on-ci.sh b/run-compatibility-test-on-ci.sh new file mode 100755 index 000000000..3bb95fa56 --- /dev/null +++ b/run-compatibility-test-on-ci.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [[ -z CI_JOB_NAME ]] ; then + echo "CI_JOB_NAME not set. Exiting" + exit 1 +fi + +GRADLE_VERS=${CI_JOB_NAME/test:gradle_/} + +if [[ -z GRADLE_VERS ]] ; then + echo No Gradle versions could be extracted from CI_JOB_NAME. Exiting + exit 1 +fi + +export JAVA_OPTS=-XX:+UnlockExperimentalVMOptions +exec ./gradlew -i -s --console=plain --no-build-cache gradleTest \ + -DgradleTest.versions=${GRADLE_VERS} diff --git a/settings.gradle b/settings.gradle index 572226305..698bfe18c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,5 +12,3 @@ include 'asciidoctor-gradle-jvm-slides' include "testfixtures/${it}" project(":testfixtures/${it}").name = "testfixtures-${it}" } - -enableFeaturePreview('STABLE_PUBLISHING') \ No newline at end of file diff --git a/src/intTest/groovy/org/asciidoctor/gradle/AsciidoctorExtensionFunctionalSpec.groovy b/src/intTest/groovy/org/asciidoctor/gradle/AsciidoctorExtensionFunctionalSpec.groovy deleted file mode 100644 index affba1a4e..000000000 --- a/src/intTest/groovy/org/asciidoctor/gradle/AsciidoctorExtensionFunctionalSpec.groovy +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle - -import org.apache.commons.io.FileUtils -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome -import org.junit.Ignore -import org.junit.Rule -import org.junit.rules.TemporaryFolder -import spock.lang.Specification - -@SuppressWarnings(['DuplicateStringLiteral','DuplicateNumberLiteral','MethodName','ClassSize','DuplicateMapLiteral', 'UnnecessaryGString']) -class AsciidoctorExtensionFunctionalSpec extends Specification { - public static final String TEST_PROJECTS_DIR = "src/intTest/projects" - @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() - - List pluginClasspath - - def setup() { - def pluginClasspathResource = getClass().classLoader.getResource("plugin-classpath.txt") - if (pluginClasspathResource == null) { - throw new IllegalStateException("Did not find plugin classpath resource, run `testClasses` build task.") - } - - pluginClasspath = pluginClasspathResource.readLines().collect { new File(it) } - } - - def "Postprocessor extensions are registered and preserved across multiple builds"() { - given: "A build file that declares extensions" - def buildFile = testProjectDir.newFile("build.gradle") - buildFile << """\ - plugins { - id "org.asciidoctor.convert" - } - - asciidoctor { - extensions { - postprocessor { document, output -> - return "Hi, Mom" + output - } - } - } - """ - - and: "Some source files" - FileUtils.copyDirectory(new File(TEST_PROJECTS_DIR, "extension"), testProjectDir.root) - final buildDir = new File(testProjectDir.root, "build") - - when: - final BuildResult firstInvocationResult = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments("asciidoctor") - .withPluginClasspath(pluginClasspath) - .withDebug(true) - .build() - - then: - firstInvocationResult.task(":asciidoctor").outcome == TaskOutcome.SUCCESS - File sampleHtmlOutput = new File(buildDir, "asciidoc/html5/sample.html") - sampleHtmlOutput.exists() - sampleHtmlOutput.text.startsWith("Hi, Mom") - - when: - new File(testProjectDir.root, "src/docs/asciidoc/sample.asciidoc") << "changes" - final BuildResult secondInvocationResult = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments("asciidoctor") - .withPluginClasspath(pluginClasspath) - .withDebug(true) - .build() - - then: - secondInvocationResult.task(":asciidoctor").outcome == TaskOutcome.SUCCESS - new File(buildDir, "asciidoc/html5/sample.html").text.startsWith("Hi, Mom") - } - - @spock.lang.Ignore - def "require modules are registered and preserved across multiple builds"() { - given: "A build file that declares a required module" - def buildFile = testProjectDir.newFile("build.gradle") - buildFile << """ - plugins { - id "org.asciidoctor.convert" - } - - repositories { - jcenter() - } - - dependencies { - asciidoctor("org.asciidoctor:asciidoctorj-diagram:1.5.4.1"){ - exclude( group: "org.asciidoctor", module: "asciidoctorj" ) - } - } - asciidoctor { - requires( 'asciidoctor-diagram' ) - backends( 'html5' ) - } - """ - - and: "source file with graphviz" - def folder = testProjectDir.newFolder("src") - def folder2 = new File(folder, "docs/asciidoc") - folder2.mkdirs() - new File(folder2, "graph.asciidoc").text = """ - -== Diagrams - -["graphviz", format="svg", align="center"] -.Some graphviz ----- -digraph { - compound=true - layout=dot - edge [ dir = none, arrowhead = none, arrowtail = none ] - node [ shape = square ] - //billing_domain [ label = none, style = invisible ] - subgraph cluster_3gpp_network { - label = "3GPP\nnetwork" - - ctf [ label = "CTF\n(Charging\nTrigger\nFunction)" ] - cdf [ label = "CDF\n(Charging\nData\nFunction)" ] - cgf [ label = "CGF\n(Charging\nGateway\nFunction)" ] - - ctf -> cdf [ label = "Rf", dir = forward, arrowhead = normal ] - cdf -> cgf [ label = "Ga", dir = forward, arrowhead = normal ] - - { rank=same; ctf cdf cgf } - } - /* - subgraph cluster_billing_domain { - label = "Billing\nDomain" - billing_domain [ label = none, style = invisible ] - { rank=same; billing_domain } - } - */ - billing_domain [ label = "Billing\nDomain" ] - cgf -> billing_domain [ constraint = false, label = "Bx", dir = forward, arrowhead = normal ] -} ----- -""" - final buildDir = new File(testProjectDir.root, "build") - - when: - final BuildResult firstInvocationResult = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments("clean", "asciidoctor") - .withPluginClasspath(pluginClasspath) - .forwardOutput() - .withDebug(true) - .build() - - then: - firstInvocationResult.task(":asciidoctor").outcome == TaskOutcome.SUCCESS - File outputFolder = new File(buildDir, "asciidoc/html5") - File outputFile = new File(outputFolder, "graph.html") - outputFile.exists() - outputFolder.listFiles().findAll { it.name.endsWith(".svg") }.size() == 1 - - when: - new File(testProjectDir.root, "src/docs/asciidoc/sample.asciidoc") << "changes" - final BuildResult secondInvocationResult = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments("clean", "asciidoctor") - .withPluginClasspath(pluginClasspath) - .forwardOutput() - .withDebug(true) - .build() - - then: - secondInvocationResult.task(":asciidoctor").outcome == TaskOutcome.SUCCESS - outputFile.exists() - outputFolder.parentFile.listFiles().findAll { it.name.endsWith(".svg") }.size() == 1 - } -} diff --git a/src/intTest/projects/extension/src/docs/asciidoc/sample.asciidoc b/src/intTest/projects/extension/src/docs/asciidoc/sample.asciidoc deleted file mode 100644 index 51e1e45eb..000000000 --- a/src/intTest/projects/extension/src/docs/asciidoc/sample.asciidoc +++ /dev/null @@ -1,25 +0,0 @@ -Document Title -============== -Doc Writer -:idprefix: id_ - -Preamble paragraph. - -NOTE: This is test, only a test. - -== Section A - -*Section A* paragraph. - -=== Section A Subsection - -*Section A* 'subsection' paragraph. - -== Section B - -*Section B* paragraph. - -.Section B list -* Item 1 -* Item 2 -* Item 3 diff --git a/src/main/groovy/org/asciidoctor/gradle/backported/AsciidoctorJavaExec.groovy b/src/main/groovy/org/asciidoctor/gradle/backported/AsciidoctorJavaExec.groovy deleted file mode 100644 index 9f82888c6..000000000 --- a/src/main/groovy/org/asciidoctor/gradle/backported/AsciidoctorJavaExec.groovy +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle.backported - -import groovy.transform.CompileDynamic -import groovy.transform.CompileStatic -import org.asciidoctor.Asciidoctor -import org.asciidoctor.Options -import org.asciidoctor.groovydsl.AsciidoctorExtensions - -/** Runs Asciidoctor as an externally invoked Java process. - * - * @since 1.5.9 (Backported from 2.0) - * @author Schalk W. Cronjé - */ -@CompileStatic -class AsciidoctorJavaExec { - - AsciidoctorJavaExec(ExecutorConfigurationContainer ecc) { - this.runConfigurations = ecc.configurations - } - - void run() { - - Thread.currentThread().contextClassLoader = this.class.classLoader - Asciidoctor asciidoctor = asciidoctorInstance - addRequires(asciidoctor) - - runConfigurations.each { runConfiguration -> - if (runConfiguration.asciidoctorExtensions?.size()) { - registerExtensions(asciidoctor, runConfiguration.asciidoctorExtensions) - } - } - - runConfigurations.each { runConfiguration -> - runConfiguration.outputDir.mkdirs() - convertFiles(asciidoctor, runConfiguration) - } - } - - @SuppressWarnings(['Println', 'CatchThrowable']) - private void convertFiles(Asciidoctor asciidoctor, ExecutorConfiguration runConfiguration) { - runConfiguration.sourceTree.each { File file -> - try { - if (runConfiguration.logDocuments) { - println("Converting ${file}") - } - asciidoctor.convertFile(file, normalisedOptionsFor(file, runConfiguration)) - } catch (Throwable t) { - throw new AsciidoctorRemoteExecutionException("Error running Asciidoctor whilst attempting to process ${file} using backend ${runConfiguration.backendName}", t) - } - } - } - - private Asciidoctor getAsciidoctorInstance() { - String combinedGemPath = runConfigurations*.gemPath.join(File.pathSeparator) - if (combinedGemPath.empty || combinedGemPath == File.pathSeparator) { - Asciidoctor.Factory.create() - } else { - Asciidoctor.Factory.create(combinedGemPath) - } - } - - private void addRequires(Asciidoctor asciidoctor) { - runConfigurations.each { runConfiguration -> - for (require in runConfiguration.requires) { - asciidoctor.requireLibrary(require) - } - } - } - - @CompileDynamic - private void registerExtensions(Asciidoctor asciidoctor, List exts) { - - AsciidoctorExtensions extensionRegistry = new AsciidoctorExtensions() - - for (Object ext in rehydrateExtensions(extensionRegistry, exts)) { - extensionRegistry.addExtension(ext) - } - extensionRegistry.registerExtensionsWith((Asciidoctor) asciidoctor) - } - - /** Normalises Asciidoctor options for a given source file. - * - * Relativizes certain attributes and ensure specific options for backend, sage mode and output - * directory are in place. - * - * @param file Source file to be converted - * @param runConfiguration The current executor configuration - * @return Asciidoctor options - */ - @SuppressWarnings(['Instanceof','Println','DuplicateStringLiteral']) - protected - Map normalisedOptionsFor(final File file, ExecutorConfiguration runConfiguration) { - - Map mergedOptions = [:] - - runConfiguration.with { - final String srcRelative = getRelativePath(file.parentFile, sourceDir) - - mergedOptions.putAll(options) - mergedOptions.putAll([ - (Options.BACKEND) : backendName, - (Options.IN_PLACE): false, - (Options.SAFE) : safeModeLevel, - (Options.TO_DIR) : (srcRelative.empty ? outputDir : new File(outputDir, srcRelative)).absolutePath, - (Options.MKDIRS) : true - ]) - - mergedOptions[Options.BASEDIR] = (baseDir ?: file.parentFile).absolutePath - - if (mergedOptions.containsKey(Options.TO_FILE)) { - Object toFileValue = mergedOptions[Options.TO_FILE] - Object toDirValue = mergedOptions.remove(Options.TO_DIR) - File toFile = toFileValue instanceof File ? (File) toFileValue : new File(toFileValue.toString()) - File toDir = toDirValue instanceof File ? (File) toDirValue : new File(toDirValue.toString()) - mergedOptions[Options.TO_FILE] = new File(toDir, toFile.name).absolutePath - } - - // Note: Directories passed as relative to work around issue #83 - // Asciidoctor cannot handle absolute paths in Windows properly - Map newAttrs = [:] - newAttrs.putAll(attributes) - newAttrs.projectdir = getRelativePath(projectDir, file.parentFile) - newAttrs.rootdir = getRelativePath(rootDir, file.parentFile) - - newAttrs['gradle-projectdir'] = getRelativePath(projectDir, file.parentFile) - newAttrs['gradle-rootdir'] = getRelativePath(rootDir, file.parentFile) - mergedOptions[Options.ATTRIBUTES] = newAttrs - } - - mergedOptions - } - - /** - * Returns the path of one File relative to another. - * - * @param target the target directory - * @param base the base directory - * @return target's path relative to the base directory - * @throws IOException if an error occurs while resolving the files' canonical names - */ - protected String getRelativePath(File target, File base) throws IOException { - base.toPath().relativize(target.toPath()).toFile().toString() - } - - /** Rehydrates extensions that were serialised. - * - * @param registry Asciidoctor GroovyDSL registry instance. - * @param exts List of extensions to rehydrate. - * @return - */ - protected List rehydrateExtensions(final Object registry, final List exts) { - exts.collect { - switch (it) { - case Closure: - Closure rehydrated = ((Closure) it).rehydrate(registry, null, null) - rehydrated.resolveStrategy = Closure.DELEGATE_ONLY - (Object) rehydrated - break - default: - it - } - } as List - } - - private final List runConfigurations - - static void main(String[] args) { - if (args.size() != 1) { - throw new AsciidoctorRemoteExecutionException('No serialised location specified') - } - - ExecutorConfigurationContainer ecc - new File(args[0]).withInputStream { input -> - new ObjectInputStream(input).withCloseable { ois -> - ecc = (ExecutorConfigurationContainer) ois.readObject() - } - } - - new AsciidoctorJavaExec(ecc).run() - } - -} diff --git a/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfiguration.groovy b/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfiguration.groovy deleted file mode 100644 index 9f587d018..000000000 --- a/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfiguration.groovy +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle.backported - -import groovy.transform.CompileStatic -import groovy.transform.TupleConstructor - -import java.util.regex.Pattern - -/** Configuration for running Asciidoctor - * - * @since 1.5.9 (Backported from 2.0) - * @author Schalk W. Cronjé - */ -@CompileStatic -@SuppressWarnings(['ClassName','CloneableWithoutClone']) -@TupleConstructor -class ExecutorConfiguration implements Serializable, Cloneable { - File sourceDir - File outputDir - File projectDir - File rootDir - File baseDir - Set sourceTree - List fatalMessagePatterns - - String backendName - String gemPath - - boolean logDocuments - boolean copyResources - - int safeModeLevel - - Set requires - Map options - Map attributes - - List asciidoctorExtensions - String toString() { - """backend(s) = ${backendName} - -File locations: - sourceDir = ${sourceDir} - outputDir = ${outputDir} - projectDir = ${projectDir} - rootProjectDir = ${rootDir} - baseDir = ${baseDir} - -JRuby: - GEMPATH = ${gemPath} - requires = ${requires} - -Asciidoctor: - ${options.size()} options - ${attributes.size()} attributes - ${asciidoctorExtensions?.size() ?: 0} extensions - logDocuments = ${logDocuments}, copyReources = ${copyResources}, safeMode = ${safeModeLevel} -""" - } -} - diff --git a/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfigurationContainer.groovy b/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfigurationContainer.groovy deleted file mode 100644 index e6974f9bf..000000000 --- a/src/main/groovy/org/asciidoctor/gradle/backported/ExecutorConfigurationContainer.groovy +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle.backported - -import groovy.transform.CompileStatic - -/** Contains a number of executor configurations. - * - * @since 1.5.9 (Backported from 2.0) - * @author Schalk W. Cronjé - */ -@CompileStatic -class ExecutorConfigurationContainer implements Serializable { - final List configurations - - ExecutorConfigurationContainer(Iterable list) { - this.configurations = list as List - } - - ExecutorConfigurationContainer(ExecutorConfiguration single) { - this.configurations = [single] - } - - /** Writes a collection of {@link ExecutorConfiguration} to a file. - * - * @param destinationFile File to serialise exector configurations. - * @param configs Executor configurations. - */ - static void toFile(final File destinationFile,final Iterable configs) { - destinationFile.withOutputStream { fout -> - new ObjectOutputStream(fout).withCloseable { oos -> - oos.writeObject( - new ExecutorConfigurationContainer(configs) - ) - } - } - } -} - diff --git a/src/main/groovy/org/asciidoctor/gradle/backported/JavaExecUtils.groovy b/src/main/groovy/org/asciidoctor/gradle/backported/JavaExecUtils.groovy deleted file mode 100644 index b345f0b2e..000000000 --- a/src/main/groovy/org/asciidoctor/gradle/backported/JavaExecUtils.groovy +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle.backported - -import groovy.transform.CompileStatic -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.file.FileCollection - -import static org.asciidoctor.gradle.AsciidoctorUtils.getClassLocation -import static org.ysb33r.grolifant.api.FileUtils.toSafeFileName - -/** Utilities for dealing with Asciidoctor in an external JavaExec process. - * - * @since 1.5.9 (Backported from 2.0) - * @author Schalk W. Cronjé - */ -@CompileStatic -class JavaExecUtils { - - /** Get the classpath that needs to be passed to the external Java process. - * - * @param project Current Gradle project - * @param asciidoctorClasspath External asciidoctor dependencies - * @return A computed classpath that can be given to an external Java process. - */ - static FileCollection getJavaExecClasspath(final Project project, final FileCollection asciidoctorClasspath) { - File entryPoint = getClassLocation(AsciidoctorJavaExec) - File groovyJar = getClassLocation(GroovyObject) - project.files(entryPoint, groovyJar, asciidoctorClasspath, org.asciidoctor.gradle.AsciidoctorUtils.contextClasspath) - } - - /** The file to which execution configuration data can be serialised to. - * - * @param task Task for which execution data will be serialised. - * @return File that will (eventually) contain the execution data. - */ - static File getExecConfigurationDataFile(final Task task) { - task.project.file("${task.project.buildDir}/tmp/${toSafeFileName(task.name)}.javaexec-data") - } - - /** Serializes execution configuration data. - * - * @param task Task for which execution data will be serialised. - * @param executorConfigurations Executor configuration to be serialised - * @return File that the execution data was written to. - */ - - static File writeExecConfigurationData(final Task task, Iterable executorConfigurations) { - File execConfigurationData = getExecConfigurationDataFile(task) - execConfigurationData.parentFile.mkdirs() - ExecutorConfigurationContainer.toFile(execConfigurationData, executorConfigurations) - execConfigurationData - } -} diff --git a/src/main/groovy/org/asciidoctor/gradle/backported/SafeMode.groovy b/src/main/groovy/org/asciidoctor/gradle/backported/SafeMode.groovy deleted file mode 100644 index 1228e597c..000000000 --- a/src/main/groovy/org/asciidoctor/gradle/backported/SafeMode.groovy +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle.backported - -import groovy.transform.CompileStatic - -/** Describes Asciidoc sefty modes. - * - * (This has been ported to the plugin from the AscidoctorJ code base). - * - * @author Alex Soto - * @author Schalk W. Cronjé - * - */ -@CompileStatic -enum SafeMode { - - /** - * A safe mode level that disables any of the security features enforced by Asciidoctor (Ruby is still subject to - * its own restrictions). - */ - UNSAFE(0), - /** - * A safe mode level that closely parallels safe mode in AsciiDoc. This value prevents access to files which reside - * outside of the parent directory of the source file and disables any macro other than the include::[] macro. - */ - SAFE(1), - /** - * A safe mode level that disallows the document from setting attributes that would affect the rendering of the - * document, in addition to all the security features of SafeMode::SAFE. For instance, this level disallows changing - * the backend or the source-highlighter using an attribute defined in the source document. This is the most - * fundamental level of security for server-side deployments (hence the name). - */ - SERVER(10), - /** - * A safe mode level that disallows the document from attempting to read files from the file system and including - * the contents of them into the document, in additional to all the security features of SafeMode::SERVER. For - * instance, this level disallows use of the include::[] macro and the embedding of binary content (data uri), - * stylesheets and JavaScripts referenced by the document.(Asciidoctor and trusted extensions may still be allowed - * to embed trusted content into the document). - * - * Since Asciidoctor is aiming for wide adoption, this level is the default and is recommended for server-side - * deployments. - */ - SECURE(20) - - final private int level - - private SafeMode(int level) { - this.level = level - } - - int getLevel() { - this.level - } - - static final SafeMode safeMode(int level) { - switch(level) { - case 0: return UNSAFE - case 1: return SAFE - case 10: return SERVER - default: return SECURE - } - } - -} diff --git a/src/test/groovy/org/asciidoctor/gradle/AsciidoctorTaskExecutedSpec.groovy b/src/test/groovy/org/asciidoctor/gradle/AsciidoctorTaskExecutedSpec.groovy deleted file mode 100755 index 0f09934da..000000000 --- a/src/test/groovy/org/asciidoctor/gradle/AsciidoctorTaskExecutedSpec.groovy +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor.gradle - -import org.gradle.api.GradleException -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.testfixtures.ProjectBuilder -import spock.lang.Specification -import spock.lang.Unroll - -/** - * Asciidoctor task specification - * - * @author Benjamin Muschko - * @author Stephan Classen - * @author Marcus Fihlon - * @author Schalk W. Cronjé - */ -// We suppress a lot of warnings as this test will be removed at some stage. -@SuppressWarnings(['DuplicateStringLiteral', 'MethodName', 'MethodCount', 'DuplicateNumberLiteral', 'DuplicateMapLiteral', 'UnusedPrivateField']) -class AsciidoctorTaskExecutedSpec extends Specification { - private static final String ASCIIDOCTOR = 'asciidoctor' - private static final String ASCIIDOC_RESOURCES_DIR = 'build/resources/test/src/asciidoc' - private static final String ASCIIDOC_BUILD_DIR = 'build/asciidoc' - private static final String ASCIIDOC_SAMPLE_FILE = 'sample.asciidoc' - private static final String ASCIIDOC_SAMPLE2_FILE = 'subdir/sample2.ad' - private static final String ASCIIDOC_INVALID_FILE = 'subdir/_include.adoc' - private static final String HTML5 = 'html5' - - Project project - File testRootDir - File srcDir - File outDir - ByteArrayOutputStream systemOut - - PrintStream originSystemOut - - def setup() { - project = ProjectBuilder.builder().withName('test').build() - project.configurations.create(ASCIIDOCTOR) - testRootDir = new File('.') - srcDir = new File(testRootDir, ASCIIDOC_RESOURCES_DIR).absoluteFile - outDir = new File(project.projectDir, ASCIIDOC_BUILD_DIR) - systemOut = new ByteArrayOutputStream() - originSystemOut = System.out - System.out = new PrintStream(systemOut) - } - - def cleanup() { - System.out = originSystemOut - } - - void 'Files starting with _ should not be included'() { - when: - AsciidoctorTask task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - sourceDir = srcDir - outputDir = outDir - } - - Set files = task.sourceFileTree.files - - then: - files.find { it.name == '_include.adoc' } == null - } - - def "Allow setting of options via method"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options eruby: 'erb' - options eruby: 'erubis' - options doctype: 'book', toc: 'right' - } - - then: - !systemOut.toString().contains('deprecated') - task.options['eruby'] == 'erubis' - task.options['doctype'] == 'book' - task.options['toc'] == 'right' - } - - @SuppressWarnings('MethodName') - def "Allow setting of options via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [eruby: 'erb', toc: 'right'] - options = [eruby: 'erubis', doctype: 'book'] - } - - then: - !systemOut.toString().contains('deprecated') - task.options['eruby'] == 'erubis' - task.options['doctype'] == 'book' - !task.options.containsKey('toc') - } - - @SuppressWarnings('MethodName') - def "Allow setting of attributes via method (Map variant)"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - attributes 'source-highlighter': 'foo' - attributes 'source-highlighter': 'coderay' - attributes idprefix: '$', idseparator: '-' - } - - then: - !systemOut.toString().contains('deprecated') - task.attributes['source-highlighter'] == 'coderay' - task.attributes['idprefix'] == '$' - task.attributes['idseparator'] == '-' - } - - @SuppressWarnings('MethodName') - def "Allow setting of attributes via method (List variant)"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - attributes(['source-highlighter=foo', 'source-highlighter=coderay', 'idprefix=$', 'idseparator=-']) - } - - then: - !systemOut.toString().contains('deprecated') - task.attributes['source-highlighter'] == 'coderay' - task.attributes['idprefix'] == '$' - task.attributes['idseparator'] == '-' - } - - @SuppressWarnings('MethodName') - def "Allow setting of attributes via method (String variant)"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - attributes 'source-highlighter=foo source-highlighter=coderay idprefix=$ idseparator=-' - } - - then: - !systemOut.toString().contains('deprecated') - task.attributes['source-highlighter'] == 'coderay' - task.attributes['idprefix'] == '$' - task.attributes['idseparator'] == '-' - } - - @SuppressWarnings('MethodName') - def "Allow setting of attributes via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - attributes = ['source-highlighter': 'foo', idprefix: '$'] - attributes = ['source-highlighter': 'coderay', idseparator: '-'] - } - - then: - !systemOut.toString().contains('deprecated') - task.attributes['source-highlighter'] == 'coderay' - task.attributes['idseparator'] == '-' - !task.attributes.containsKey('idprefix') - } - - @SuppressWarnings('MethodName') - def "Mixing attributes with options, should produce a warning, but updates should be appended"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options eruby: 'erubis', attributes: ['source-highlighter': 'foo', idprefix: '$'] - options doctype: 'book', attributes: [idseparator: '-'] - } - - then: - !task.attributes.containsKey('attributes') - task.attributes['source-highlighter'] == 'foo' - task.attributes['idseparator'] == '-' - task.attributes['idprefix'] == '$' - task.options['eruby'] == 'erubis' - task.options['doctype'] == 'book' - } - - @SuppressWarnings('MethodName') - def "Mixing attributes with options with assignment, should produce a warning, and attributes will be replaced"() { - when: - Map tmpStore = [eruby: 'erubis', attributes: ['source-highlighter': 'foo', idprefix: '$']] - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = tmpStore - options = [doctype: 'book', attributes: [idseparator: '-']] - } - - then: - !task.attributes.containsKey('attributes') - task.attributes['idseparator'] == '-' - !task.attributes.containsKey('source-highlighter') - !task.attributes.containsKey('idprefix') - !task.options.containsKey('eruby') - task.options['doctype'] == 'book' - // @Ignore('Wrong sysout capture') - // systemOut.toString().contains('Attributes found in options.') - } - - @SuppressWarnings('MethodName') - def "Mixing string legacy form of attributes with options with assignment, should produce a warning, and attributes will be replaced"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [doctype: 'book', attributes: 'toc=right source-highlighter=coderay toc-title=Table\\ of\\ Contents'] - } - - then: - task.options['doctype'] == 'book' - !task.attributes.containsKey('attributes') - task.attributes['toc'] == 'right' - task.attributes['source-highlighter'] == 'coderay' - task.attributes['toc-title'] == 'Table of Contents' - } - - @SuppressWarnings('MethodName') - def "Mixing list legacy form of attributes with options with assignment, should produce a warning, and attributes will be replaced"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [doctype: 'book', attributes: [ - 'toc=right', - 'source-highlighter=coderay', - 'toc-title=Table of Contents' - ]] - } - - then: - task.options['doctype'] == 'book' - !task.attributes.containsKey('attributes') - task.attributes['toc'] == 'right' - task.attributes['source-highlighter'] == 'coderay' - task.attributes['toc-title'] == 'Table of Contents' - // @Ignore('Wrong sysout capture') - // systemOut.toString().contains('Attributes found in options.') - } - - @SuppressWarnings('MethodName') - def "Allow setting of backends via method"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - backends 'foo', 'bar' - backends 'pdf' - } - - then: - !systemOut.toString().contains('deprecated') - task.backends.contains('pdf') - task.backends.contains('foo') - task.backends.contains('bar') - } - - @SuppressWarnings('MethodName') - def "Allow setting of backends via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - backends = ['pdf'] - backends = ['foo', 'bar'] - } - - then: - !systemOut.toString().contains('deprecated') - !task.backends.contains('pdf') - task.backends.contains('foo') - task.backends.contains('bar') - } - - @SuppressWarnings('MethodName') - def "Allow setting of requires via method"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - requires 'slim', 'tilt' - requires 'asciidoctor-pdf' - } - - then: - !systemOut.toString().contains('deprecated') - task.requires.contains('asciidoctor-pdf') - task.requires.contains('tilt') - task.requires.contains('slim') - } - - @SuppressWarnings('MethodName') - def "Allow setting of requires via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - requires = ['asciidoctor-pdf'] - requires = ['slim', 'tilt'] - } - - then: - !systemOut.toString().contains('deprecated') - !task.requires.contains('asciidoctor-pdf') - task.requires.contains('tilt') - task.requires.contains('slim') - } - - @SuppressWarnings('MethodName') - def "Allow setting of sourceDir via method"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - sourceDir project.projectDir - } - - then: - !systemOut.toString().contains('deprecated') - task.sourceDir.absolutePath == project.projectDir.absolutePath - task.sourceDir.absolutePath == project.projectDir.absolutePath - } - - - @SuppressWarnings('MethodName') - def "When setting sourceDir via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - sourceDir = project.projectDir - } - - then: - task.sourceDir.absolutePath == project.projectDir.absolutePath - task.sourceDir.absolutePath == project.projectDir.absolutePath - - } - - @SuppressWarnings('MethodName') - def "When setting sourceDir via setSourceDir"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - sourceDir = project.projectDir - } - - then: - task.sourceDir.absolutePath == project.projectDir.absolutePath - task.sourceDir.absolutePath == project.projectDir.absolutePath - !systemOut.toString().contains('deprecated') - } - - @SuppressWarnings('MethodName') - def "Allow setting of gemPath via method"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - gemPath project.projectDir - } - - then: - !systemOut.toString().contains('deprecated') - task.gemPath.files[0].absolutePath == project.projectDir.absolutePath - } - - @SuppressWarnings('MethodName') - def "When setting gemPath via assignment"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - gemPath = project.projectDir - } - - then: - task.gemPath.files[0].absolutePath == project.projectDir.absolutePath - !systemOut.toString().contains('deprecated') - } - - @SuppressWarnings('MethodName') - def "When setting gemPath via setGemPath"() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - gemPath = project.projectDir - } - - then: - task.gemPath.files[0].absolutePath == project.projectDir.absolutePath - !systemOut.toString().contains('deprecated') - } - - void "Method `sourceDocumentNames` should resolve descendant files of `sourceDir` if supplied as relatives"() { - when: 'I specify two files relative to sourceDir,including one in a subfolder' - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - sourceDir srcDir - sources { - include ASCIIDOC_SAMPLE_FILE - include ASCIIDOC_SAMPLE2_FILE - } - } - def fileCollection = task.sourceFileTree - - then: 'both files should be in collection, but any other files found in folder should be excluded' - fileCollection.contains(new File(srcDir, ASCIIDOC_SAMPLE_FILE).canonicalFile) - fileCollection.contains(new File(srcDir, ASCIIDOC_SAMPLE2_FILE).canonicalFile) - !fileCollection.contains(new File(srcDir, 'sample-docinfo.xml').canonicalFile) - fileCollection.files.size() == 2 - } - - void 'sanity test for default configuration'() { - when: - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) - - then: - task.sourceDir.absolutePath.replace('\\', '/').endsWith('src/docs/asciidoc') - task.outputDir.absolutePath.replace('\\', '/').endsWith('build/asciidoc') - } - - void 'Files in the resources copyspec should be recognised as input files'() { - given: - File imagesDir = new File(outDir, 'images') - File imageFile = new File(imagesDir, 'fake.txt') - imagesDir.mkdirs() - imageFile.text = 'foo' - - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - - sourceDir srcDir - outputDir "${outDir}/foo" - backends HTML5 - - sources { - include ASCIIDOC_SAMPLE_FILE - } - - resources { - from(outDir) { - include 'images/**' - } - } - } - - when: - project.evaluate() - - then: - task.inputs.files.contains(project.file("${srcDir}/sample.asciidoc")) - task.inputs.files.contains(project.file("${imagesDir}/fake.txt")) - } - - static final String ATTRS_AS_STRING = 'toc=right source-highlighter=coderay' - static final String HIGHLIGTHER = 'coderay' - - @Unroll - void 'Should support #type value for attributes embedded in options'() { - given: - AsciidoctorTask task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [ - attributes: data - ] - } - - Map options = task.options - Map attrs = task.attributes - - expect: - verifyAll { - options.isEmpty() - attrs.containsKey('toc') - attrs.containsKey('source-highlighter') - } - verifyAll { - attrs.toc == 'right' - attrs.'source-highlighter' == HIGHLIGTHER - } - - where: - type | data - 'String' | 'toc=right source-highlighter=coderay' - 'GString' | "${ATTRS_AS_STRING}" - 'List' | ['toc=right', "source-highlighter=${HIGHLIGTHER}"] - } - - void "Throws exception when attributes embedded in options is an unsupported type"() { - when: - project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [ - attributes: 23 - ] - } - - then: - thrown(GradleException) - } - - void 'GStrings in options and attributes are converted into Strings'() { - given: - String variable = 'bar' - Task task = project.tasks.create(name: ASCIIDOCTOR, type: AsciidoctorTask) { - options = [ - template_dirs: ["${project.projectDir}/templates/haml"] - ] - attributes = [ - foo: "${variable}" - ] - } - - Map options = task.options - Map attrs = task.attributes - - expect: - verifyAll { - options.containsKey('template_dirs') - attrs.containsKey('foo') - } - verifyAll { - options.template_dirs[0].endsWith('haml') - attrs.'foo' == variable - } - } - - -} diff --git a/testfixtures/jvm/build.gradle b/testfixtures/jvm/build.gradle index 0ebe307f1..c14efc61e 100644 --- a/testfixtures/jvm/build.gradle +++ b/testfixtures/jvm/build.gradle @@ -8,7 +8,7 @@ dependencies { compile "org.jsoup:jsoup:$jsoupVersion" compile "cglib:cglib-nodep:$cglibVersion" compile("org.spockframework:spock-core:$spockVersion") { - exclude group:'org.codehaus.groovy' + exclude group: 'org.codehaus.groovy' exclude group: 'org.hamcrest', module: 'hamcrest-core' } } diff --git a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/AsciidoctorjTestVersions.groovy b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/AsciidoctorjTestVersions.groovy index d89cc7533..ab07ae044 100644 --- a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/AsciidoctorjTestVersions.groovy +++ b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/AsciidoctorjTestVersions.groovy @@ -25,10 +25,10 @@ import groovy.transform.CompileStatic class AsciidoctorjTestVersions { // These lines are read by the build script. - public final static String SERIES_16 = '1.6.1' + public final static String SERIES_16 = '1.6.2' public final static String SERIES_20 = '1.6.0-RC.2' - public final static String GROOVYDSL_SERIES_16 = '1.6.0-alpha.2' + public final static String GROOVYDSL_SERIES_16 = '1.6.0' public final static String GROOVYDSL_SERIES_20 = '1.6.0-alpha.2' - public final static String DIAGRAM_SERIES_16 = '1.5.8' + public final static String DIAGRAM_SERIES_16 = '1.5.12' public final static String DIAGRAM_SERIES_20 = '1.5.8' } diff --git a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/FunctionalTestSetup.groovy b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/FunctionalTestSetup.groovy index fc9dfe46e..453aa048c 100644 --- a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/FunctionalTestSetup.groovy +++ b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/FunctionalTestSetup.groovy @@ -76,7 +76,6 @@ class FunctionalTestSetup { .withProjectDir(projectDir) .withArguments(taskNames) .forwardOutput() - .withDebug(true) pluginClasspath ? runner.withPluginClasspath(pluginClasspath) : runner.withPluginClasspath() } @@ -113,9 +112,9 @@ class FunctionalTestSetup { } if (OS.windows) { - "apply( from = \"${repo.absolutePath.replaceAll(BACKSLASH, DOUBLE_BACKSLASH)}\")" + $/apply( from = "${repo.absolutePath.replace(BACKSLASH, DOUBLE_BACKSLASH)}")/$ } else { - "apply( from = \"${repo.absolutePath}\")" + $/apply( from = "${repo.absolutePath}")/$ } } diff --git a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/JRubyTestVersions.groovy b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/JRubyTestVersions.groovy index 2f308c57a..0d4cb3ca6 100644 --- a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/JRubyTestVersions.groovy +++ b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/JRubyTestVersions.groovy @@ -39,8 +39,8 @@ class JRubyTestVersions { public final static String AJ16_ABSOLUTE_MINIMUM = '9.2.5.0' public final static String AJ16_SAFE_MINIMUM = '9.2.5.0' - public final static String AJ16_SAFE_MAXIMUM = '9.2.5.0' - public final static String AJ16_ABSOLUTE_MAXIMUM = '9.2.5.0' + public final static String AJ16_SAFE_MAXIMUM = '9.2.6.0' + public final static String AJ16_ABSOLUTE_MAXIMUM = '9.2.6.0' // ---------------------------------------------------------- } diff --git a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/generators/AsciidoctorjVersionProcessModeGenerator.groovy b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/generators/AsciidoctorjVersionProcessModeGenerator.groovy index 2d3b91829..b6b0ff586 100644 --- a/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/generators/AsciidoctorjVersionProcessModeGenerator.groovy +++ b/testfixtures/jvm/src/main/groovy/org/asciidoctor/gradle/testfixtures/jvm/generators/AsciidoctorjVersionProcessModeGenerator.groovy @@ -49,7 +49,7 @@ class AsciidoctorjVersionProcessModeGenerator { } static List get() { - if (System.getenv('APPVEYOR')) { + if (System.getenv('APPVEYOR') || System.getenv('TRAVIS')) { [AsciidoctorjTestVersions.SERIES_20, AsciidoctorjTestVersions.SERIES_16].collect { VersionProcess.of(it, JAVA_EXEC) }.toUnique() diff --git a/testfixtures/offline-repo/build.gradle b/testfixtures/offline-repo/build.gradle index ebf9fc8df..896bd628c 100644 --- a/testfixtures/offline-repo/build.gradle +++ b/testfixtures/offline-repo/build.gradle @@ -50,11 +50,11 @@ syncRemoteRepositories { w.print ' ' * 4 w.println 'ivy {' w.print ' ' * 8 - w.println "name 'OfflineRepo'" + w.println 'name = "OfflineRepo"' w.print ' ' * 8 - w.println "layout 'gradle'" + w.println 'layout("gradle")' w.print ' ' * 8 - w.println "url '${file(repoRoot).absoluteFile.toURI()}'" + w.println "url = uri(\"${file(repoRoot).absoluteFile.toURI()}\")" w.print ' ' * 4 w.println '}' w.println '}'