Skip to content

Commit

Permalink
Merge pull request #419 from ysb33r/dep-report-393
Browse files Browse the repository at this point in the history
Report dependencies for any Asciidoctor task (#393)
  • Loading branch information
ysb33r committed Jun 30, 2019
2 parents e63b8e7 + 1eb3058 commit 5cd7a8b
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.InvalidUserDataException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.CopySpec
import org.gradle.api.file.FileTree
import org.gradle.api.provider.Provider
Expand Down Expand Up @@ -562,6 +563,15 @@ abstract class AbstractAsciidoctorBaseTask extends DefaultTask {
@Internal
abstract List<AsciidoctorAttributeProvider> getAttributeProviders()

/** Configurations for which dependencies should be reported.
*
* @return Set of configurations. Can be empty, but never {@code null}.
*
* @since 2.3.0 (Moved from org.asciidoctor.gradle.jvm)
*/
@Internal
abstract Set<Configuration> getReportableConfigurations()

protected AbstractAsciidoctorBaseTask() {
super()
inputs.files { filesFromCopySpec(getResourceCopySpec(Optional.empty())) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,67 @@
*/
package org.asciidoctor.gradle.base

import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.UnknownTaskException
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.diagnostics.DependencyReportTask
import org.ysb33r.grolifant.api.TaskProvider

import java.util.regex.Matcher
import java.util.regex.Pattern

/** Base plugin for all Asciidoctor plugins (J & JS).
*
* @since 2.0.0
* @author Schalk W. Cronjé
*
* @since 2.0.0
*/
@CompileStatic
class AsciidoctorBasePlugin implements Plugin<Project> {
private static final Pattern DEPS_TASK_PATTERN = ~/^(.+)Dependencies$/

void apply(Project project) {
project.apply plugin: 'base'
registerDependencyReportRules(project)
}

private void registerDependencyReportRules(Project project) {
TaskContainer tasks = project.tasks
tasks.addRule(
'<asciidocTaskName>Dependencies: Report dependencies for AsciidoctorJ tasks'
) { String targetTaskName ->
Matcher matcher = targetTaskName =~ DEPS_TASK_PATTERN
if (matcher.matches()) {
try {
TaskProvider associate = TaskProvider.taskByTypeAndName(
project,
AbstractAsciidoctorBaseTask,
taskBaseName(matcher)
)

tasks.create(targetTaskName, DependencyReportTask, new Action<Task>() {
@Override
void execute(Task task) {
AbstractAsciidoctorBaseTask asciidoctorTask = (AbstractAsciidoctorBaseTask) associate.get()
DependencyReportTask reportTask = (DependencyReportTask) task
reportTask.configurations = asciidoctorTask.reportableConfigurations
}
})
} catch (UnknownTaskException e) {
return
}
}
}
}

@CompileDynamic
private String taskBaseName(Matcher matcher) {
matcher[0][1]
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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.asciidoctor.gradle.base.Transform
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.provider.Provider
import org.ysb33r.grolifant.api.StringUtils

/** Utilities for dealing with Configurations
*
* @since 3.0.0
*/
@CompileStatic
class ConfigurationUtils {

/** Extracts a {@link Configuration} if possible.
*
* @param project Associated project
* @param sourceConfig Item that could be a source of a configuration
* @return {@link Configuration} instance
*
* @throw {@code UnknownConfigurationException}
*/
static Configuration asConfiguration(Project project, Object sourceConfig) {
switch (sourceConfig) {
case Configuration:
return (Configuration) sourceConfig
case Provider:
return asConfiguration(project, ((Provider) sourceConfig).get())
default:
project.configurations.getByName(StringUtils.stringize(sourceConfig))
}
}

/** Extracts a list of {@link Configuration} instances.
*
* @param project Associated project.
* @param sourceConfigs Collection of items that could be sources of configurations.
* @return List of {@link Configuration} instances.
*
* @throw {@code UnknownConfigurationException}
*/
static List<Configuration> asConfigurations(Project project, Collection<Object> sourceConfigs) {
Transform.toList(sourceConfigs) {
asConfiguration(project, it)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.Specification

class AsciidoctorBasePluginSpec extends Specification {
Project project = ProjectBuilder.builder().build()

void 'Applying the plugin will add a report task rule'() {
given:
project.allprojects {
apply plugin: 'org.asciidoctor.base'
tasks.create 'foo', TestTask
}

when:
project.tasks.getByName('fooDependencies')

then:
noExceptionThrown()
}

static class TestTask extends AbstractAsciidoctorBaseTask {
Map<String, Object> attributes
List<AsciidoctorAttributeProvider> attributeProviders
Set<Configuration> reportableConfigurations = []

@Override
void attributes(Map<String, Object> m) {
}

@Override
protected String getEngineName() {
null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.asciidoctor.gradle.base.AsciidoctorAttributeProvider
import org.asciidoctor.gradle.base.internal.Workspace
import org.asciidoctor.gradle.js.base.AbstractAsciidoctorTask
import org.asciidoctor.gradle.js.nodejs.internal.AsciidoctorJSRunner
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
Expand Down Expand Up @@ -89,6 +90,15 @@ class AbstractAsciidoctorNodeJSTask extends AbstractAsciidoctorTask {
asciidoctorjs.attributeProviders
}

/** Configurations for which dependencies should be reported.
*
* @return Set of configurations. Can be empty, but never {@code null}.
*/
@Override
Set<Configuration> getReportableConfigurations() {
[asciidoctorjs.configuration].toSet()
}

@TaskAction
void processAsciidocSources() {
validateConditions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ import org.gradle.process.JavaForkOptions
import org.gradle.util.GradleVersion
import org.gradle.workers.WorkerConfiguration
import org.gradle.workers.WorkerExecutor
import org.ysb33r.grolifant.api.StringUtils

import static org.asciidoctor.gradle.base.AsciidoctorUtils.executeDelegatingClosure
import static org.asciidoctor.gradle.base.AsciidoctorUtils.getClassLocation
import static org.asciidoctor.gradle.base.internal.ConfigurationUtils.asConfiguration
import static org.asciidoctor.gradle.base.internal.ConfigurationUtils.asConfigurations
import static org.gradle.workers.IsolationMode.CLASSLOADER
import static org.gradle.workers.IsolationMode.PROCESS

Expand Down Expand Up @@ -235,14 +236,10 @@ class AbstractAsciidoctorTask extends AbstractAsciidoctorBaseTask {
@Classpath
@SuppressWarnings('Instanceof')
FileCollection getConfigurations() {
FileCollection fc = asciidoctorj.configuration
FileCollection precompiledExtensions = findDependenciesInExtensions()
this.asciidocConfigurations.each {
if (it instanceof Configuration) {
fc = fc + (FileCollection) it
} else {
fc = fc + (FileCollection) (project.configurations.getByName(StringUtils.stringize(it)))
}
FileCollection fc = this.asciidocConfigurations.inject(asciidoctorj.configuration) {
FileCollection seed, Object it ->
seed + asConfiguration(project, it)
}
precompiledExtensions ? fc + precompiledExtensions : fc
}
Expand Down Expand Up @@ -274,6 +271,17 @@ class AbstractAsciidoctorTask extends AbstractAsciidoctorBaseTask {
this.asciidocConfigurations.addAll(configs)
}

/** Configurations for which dependencies should be reported.
*
* @return Set of configurations. Can be empty, but never {@code null}.
*
* @since 2.3.0
*/
@Override
Set<Configuration> getReportableConfigurations() {
([asciidoctorj.configuration] + asConfigurations(project, asciidocConfigurations)).toSet()
}

@SuppressWarnings('UnnecessaryGetter')
@TaskAction
void processAsciidocSources() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,13 @@ package org.asciidoctor.gradle.jvm

import groovy.transform.CompileStatic
import org.asciidoctor.gradle.base.AsciidoctorBasePlugin
import org.gradle.api.Action
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.diagnostics.DependencyReportTask

import static org.ysb33r.grolifant.api.TaskProvider.registerTask

/**
* @author Schalk W. Cronjé
*
* @since 2.0.0
* @author Schalk W. Cronjé
*
* @since 2.0.0
*/
@CompileStatic
class AsciidoctorJBasePlugin implements Plugin<Project> {
Expand All @@ -40,18 +35,11 @@ class AsciidoctorJBasePlugin implements Plugin<Project> {
project.with {
apply plugin: AsciidoctorBasePlugin

AsciidoctorJExtension asciidoctorj = extensions.create(
extensions.create(
AsciidoctorJExtension.NAME,
AsciidoctorJExtension,
project
)

registerTask(project, DEPS_REPORT, DependencyReportTask, new Action<Task>() {
@Override
void execute(Task task) {
((DependencyReportTask) task).configurations = [asciidoctorj.configuration].toSet()
}
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ package org.asciidoctor.gradle.jvm
import org.asciidoctor.gradle.base.ModuleVersionLoader
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.diagnostics.DependencyReportTask
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.Shared
import spock.lang.Specification

class AsciidoctorJBasePluginSpec extends Specification {

@Shared
Map<String,String> versionMap = ModuleVersionLoader.load('asciidoctorj-extension')
Map<String, String> versionMap = ModuleVersionLoader.load('asciidoctorj-extension')

Project project = ProjectBuilder.builder().build()

Expand All @@ -47,19 +46,6 @@ class AsciidoctorJBasePluginSpec extends Specification {
}
}

void 'Apply the plugin will add a report task for AsciidoctorJ'() {
when:
project.allprojects {
apply plugin: 'org.asciidoctor.jvm.base'
}

project.evaluate()
DependencyReportTask task = project.tasks.getByName(AsciidoctorJBasePlugin.DEPS_REPORT)

then:
!task.configurations.first().dependencies.empty
}

void 'Adding extension will set GroovyDSL'() {
when:
project.allprojects {
Expand Down

0 comments on commit 5cd7a8b

Please sign in to comment.