ApidocPlugin.groovy
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2018-2019 Andres Almiray.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package org.kordamp.gradle.plugin.apidoc
019 
020 import groovy.transform.CompileStatic
021 import org.gradle.BuildAdapter
022 import org.gradle.api.DefaultTask
023 import org.gradle.api.JavaVersion
024 import org.gradle.api.Project
025 import org.gradle.api.Task
026 import org.gradle.api.invocation.Gradle
027 import org.gradle.api.plugins.JavaBasePlugin
028 import org.gradle.api.tasks.bundling.Jar
029 import org.gradle.api.tasks.javadoc.Groovydoc
030 import org.gradle.api.tasks.javadoc.Javadoc
031 import org.kordamp.gradle.plugin.AbstractKordampPlugin
032 import org.kordamp.gradle.plugin.base.BasePlugin
033 import org.kordamp.gradle.plugin.base.ProjectConfigurationExtension
034 import org.kordamp.gradle.plugin.groovydoc.GroovydocPlugin
035 import org.kordamp.gradle.plugin.javadoc.JavadocPlugin
036 
037 import static org.kordamp.gradle.PluginUtils.resolveEffectiveConfig
038 import static org.kordamp.gradle.plugin.base.BasePlugin.isRootProject
039 
040 /**
041  * Configures {@code aggregateApidocs} {@code aggregateApidocsJar} tasks on the root project.
042  *
043  @author Andres Almiray
044  @since 0.1.0
045  */
046 class ApidocPlugin extends AbstractKordampPlugin {
047     static final String AGGREGATE_APIDOCS_TASK_NAME = 'aggregateApidocs'
048     static final String AGGREGATE_JAVADOCS_TASK_NAME = 'aggregateJavadocs'
049     static final String AGGREGATE_JAVADOCS_JAR_TASK_NAME = 'aggregateJavadocsJar'
050     static final String AGGREGATE_GROOVYDOCS_TASK_NAME = 'aggregateGroovydocs'
051     static final String AGGREGATE_GROOVYDOCS_JAR_TASK_NAME = 'aggregateGroovydocsJar'
052 
053     Project project
054 
055     @CompileStatic
056     void apply(Project project) {
057         this.project = project
058 
059         if (isRootProject(project)) {
060             if (project.childProjects.size()) {
061                 project.childProjects.values().each {
062                     configureProject(it)
063                 }
064                 configureRootProject(project, true)
065             else {
066                 configureProject(project)
067                 configureRootProject(project, false)
068             }
069         else {
070             configureProject(project)
071         }
072     }
073 
074     @CompileStatic
075     static void applyIfMissing(Project project) {
076         if (!project.plugins.findPlugin(ApidocPlugin)) {
077             project.plugins.apply(ApidocPlugin)
078         }
079     }
080 
081     @CompileStatic
082     private void configureProject(Project project) {
083         if (hasBeenVisited(project)) {
084             return
085         }
086         setVisited(project, true)
087 
088         BasePlugin.applyIfMissing(project)
089         JavadocPlugin.applyIfMissing(project)
090         GroovydocPlugin.applyIfMissing(project)
091     }
092 
093     @CompileStatic
094     private void configureRootProject(Project project, boolean checkIfApplied) {
095         if (checkIfApplied && hasBeenVisited(project)) {
096             return
097         }
098         setVisited(project, true)
099 
100         BasePlugin.applyIfMissing(project)
101 
102         if (isRootProject(project&& !project.childProjects.isEmpty()) {
103             List<Task> aggregateJavadocTasks = createAggregateJavadocsTask(project)
104             createAggregateGroovydocsTask(project, aggregateJavadocTasks[0])
105             createAggregateApidocTask(project)
106 
107             project.gradle.addBuildListener(new BuildAdapter() {
108                 @Override
109                 void projectsEvaluated(Gradle gradle) {
110                     doConfigureRootProject(project)
111                 }
112             })
113         }
114     }
115 
116     private void doConfigureRootProject(Project project) {
117         ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
118         setEnabled(effectiveConfig.apidoc.enabled)
119 
120         if (!enabled) {
121             return
122         }
123 
124         if (!project.childProjects.isEmpty()) {
125             List<Javadoc> javadocs = []
126             project.tasks.withType(Javadoc) { Javadoc javadoc -> if (javadoc.name != AGGREGATE_JAVADOCS_TASK_NAME && javadoc.enabledjavadocs << javadoc }
127             project.childProjects.values().each Project p ->
128                 if (p in effectiveConfig.apidoc.excludedProjects()) return
129                 p.tasks.withType(Javadoc) { Javadoc javadoc -> if (javadoc.enabledjavadocs << javadoc }
130             }
131             javadocs = javadocs.unique()
132 
133             List<Groovydoc> groovydocs = []
134             project.tasks.withType(Groovydoc) { Groovydoc groovydoc -> if (groovydoc.name != AGGREGATE_GROOVYDOCS_TASK_NAME && groovydoc.enabledgroovydocs << groovydoc }
135             project.childProjects.values().each Project p ->
136                 if (p in effectiveConfig.apidoc.excludedProjects()) return
137                 p.tasks.withType(Groovydoc) { Groovydoc groovydoc -> if (groovydoc.enabledgroovydocs << groovydoc }
138             }
139             groovydocs = groovydocs.unique()
140 
141             Javadoc aggregateJavadocs = project.tasks.findByName(AGGREGATE_JAVADOCS_TASK_NAME)
142             Jar aggregateJavadocsJar = project.tasks.findByName(AGGREGATE_JAVADOCS_JAR_TASK_NAME)
143             Groovydoc aggregateGroovydocs = project.tasks.findByName(AGGREGATE_GROOVYDOCS_TASK_NAME)
144             Jar aggregateGroovydocsJar = project.tasks.findByName(AGGREGATE_GROOVYDOCS_JAR_TASK_NAME)
145             Task aggregateApidocTask = project.tasks.findByName(AGGREGATE_APIDOCS_TASK_NAME)
146 
147             if (javadocs && !effectiveConfig.groovydoc.replaceJavadoc) {
148                 aggregateJavadocs.configure task ->
149                     task.enabled true
150                     task.dependsOn javadocs
151                     task.source javadocs.source
152                     task.classpath = project.files(javadocs.classpath)
153 
154                     effectiveConfig.javadoc.applyTo(task)
155                     task.options.footer = "Copyright &copy; ${effectiveConfig.info.copyrightYear} ${effectiveConfig.info.authors.join(', ')}. All rights reserved."
156                 }
157                 aggregateJavadocsJar.configure {
158                     enabled true
159                     from aggregateJavadocs.destinationDir
160                 }
161 
162                 aggregateApidocTask.enabled = true
163                 aggregateApidocTask.dependsOn aggregateJavadocs
164             }
165 
166             if (groovydocs && effectiveConfig.groovydoc.enabled) {
167                 if (effectiveConfig.groovydoc.replaceJavadoc) {
168                     aggregateGroovydocsJar.classifier = 'javadoc'
169                 }
170 
171                 aggregateGroovydocs.configure task ->
172                     task.enabled true
173                     task.dependsOn groovydocs + javadocs
174                     task.source groovydocs.source + javadocs.source
175                     task.classpath = project.files(groovydocs.classpath + javadocs.classpath)
176                     task.groovyClasspath = project.files(groovydocs.groovyClasspath.flatten().unique())
177 
178                     effectiveConfig.groovydoc.applyTo(task)
179                     task.footer = "Copyright &copy; ${effectiveConfig.info.copyrightYear} ${effectiveConfig.info.authors.join(', ')}. All rights reserved."
180                 }
181                 aggregateGroovydocsJar.configure {
182                     enabled true
183                     from aggregateGroovydocs.destinationDir
184                 }
185 
186                 aggregateApidocTask.enabled = true
187                 aggregateApidocTask.dependsOn aggregateGroovydocs
188             }
189         }
190     }
191 
192     private List<Task> createAggregateJavadocsTask(Project project) {
193         Javadoc aggregateJavadocs = project.tasks.create(AGGREGATE_JAVADOCS_TASK_NAME, Javadoc) {
194             enabled false
195             group JavaBasePlugin.DOCUMENTATION_GROUP
196             description 'Aggregates Javadoc API docs for all projects.'
197             destinationDir project.file("${project.buildDir}/docs/javadoc")
198             if (JavaVersion.current().isJava8Compatible()) {
199                 options.addStringOption('Xdoclint:none', '-quiet')
200             }
201         }
202 
203         Jar aggregateJavadocsJar = project.tasks.create(AGGREGATE_JAVADOCS_JAR_TASK_NAME, Jar) {
204             enabled false
205             dependsOn aggregateJavadocs
206             group JavaBasePlugin.DOCUMENTATION_GROUP
207             description 'An archive of the aggregate Javadoc API docs'
208             classifier 'javadoc'
209         }
210 
211         [aggregateJavadocs, aggregateJavadocsJar]
212     }
213 
214     private List<Task> createAggregateGroovydocsTask(Project project, Task aggregateJavadoc) {
215         Groovydoc aggregateGroovydocs = project.tasks.create(AGGREGATE_GROOVYDOCS_TASK_NAME, Groovydoc) {
216             enabled false
217             group JavaBasePlugin.DOCUMENTATION_GROUP
218             description 'Aggregates Groovy API docs for all projects.'
219             destinationDir project.file("${project.buildDir}/docs/groovydoc")
220             classpath = aggregateJavadoc.classpath
221         }
222 
223         Jar aggregateGroovydocsJar = project.tasks.create(AGGREGATE_GROOVYDOCS_JAR_TASK_NAME, Jar) {
224             enabled false
225             dependsOn aggregateGroovydocs
226             group JavaBasePlugin.DOCUMENTATION_GROUP
227             description 'An archive of the aggregate Groovy API docs'
228             classifier 'groovydoc'
229         }
230 
231         [aggregateGroovydocs, aggregateGroovydocsJar]
232     }
233 
234     private Task createAggregateApidocTask(Project project) {
235         project.tasks.create(AGGREGATE_APIDOCS_TASK_NAME, DefaultTask) {
236             enabled false
237             group JavaBasePlugin.DOCUMENTATION_GROUP
238             description 'Aggregates all API docs for all projects.'
239         }
240     }
241 }