KotlindocPlugin.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.kotlindoc
019 
020 import groovy.transform.CompileDynamic
021 import groovy.transform.CompileStatic
022 import org.gradle.api.Project
023 import org.gradle.api.Task
024 import org.gradle.api.plugins.JavaBasePlugin
025 import org.gradle.api.publish.maven.MavenPublication
026 import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
027 import org.gradle.api.tasks.bundling.Jar
028 import org.gradle.api.tasks.javadoc.Javadoc
029 import org.jetbrains.dokka.gradle.DokkaPlugin
030 import org.jetbrains.dokka.gradle.DokkaTask
031 import org.jetbrains.dokka.gradle.DokkaVersion
032 import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper
033 import org.kordamp.gradle.StringUtils
034 import org.kordamp.gradle.plugin.AbstractKordampPlugin
035 import org.kordamp.gradle.plugin.base.BasePlugin
036 import org.kordamp.gradle.plugin.base.ProjectConfigurationExtension
037 import org.kordamp.gradle.plugin.base.plugins.Kotlindoc
038 import org.kordamp.gradle.plugin.javadoc.JavadocPlugin
039 
040 import static org.kordamp.gradle.PluginUtils.resolveEffectiveConfig
041 import static org.kordamp.gradle.plugin.base.BasePlugin.isRootProject
042 
043 /**
044  * Configures {@code kotlindoc} and {@code kotlindocJar} tasks.
045  *
046  @author Andres Almiray
047  @since 0.7.0
048  */
049 class KotlindocPlugin extends AbstractKordampPlugin {
050     static final String KOTLINDOC_BASENAME = 'kotlindoc'
051 
052     private static final DokkaVersion DOKKA_VERSION = new DokkaVersion()
053 
054     static {
055         DOKKA_VERSION.loadFrom(DokkaPlugin.class.getResourceAsStream('/META-INF/gradle-plugins/org.jetbrains.dokka.properties'))
056     }
057 
058     Project project
059 
060     @CompileStatic
061     void apply(Project project) {
062         this.project = project
063 
064         if (isRootProject(project)) {
065             if (project.childProjects.size()) {
066                 project.childProjects.values().each {
067                     configureProject(it)
068                 }
069             else {
070                 configureProject(project)
071             }
072         else {
073             configureProject(project)
074         }
075     }
076 
077     @CompileStatic
078     static void applyIfMissing(Project project) {
079         if (!project.plugins.findPlugin(KotlindocPlugin)) {
080             project.plugins.apply(KotlindocPlugin)
081         }
082     }
083 
084     @CompileStatic
085     private void configureProject(Project project) {
086         if (hasBeenVisited(project)) {
087             return
088         }
089         setVisited(project, true)
090 
091         BasePlugin.applyIfMissing(project)
092         // apply first then we can be certain javadoc tasks can be located on time
093         JavadocPlugin.applyIfMissing(project)
094 
095         project.afterEvaluate {
096             ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
097             setEnabled(effectiveConfig.kotlindoc.enabled)
098 
099             if (!enabled) {
100                 return
101             }
102 
103             project.plugins.withType(KotlinBasePluginWrapper) {
104                 Javadoc javadoc = (Javadocproject.tasks.findByName(JavadocPlugin.JAVADOC_TASK_NAME)
105                 if (!javadocreturn
106 
107                 effectiveConfig.kotlindoc.outputFormats.each String format ->
108                     Task kotlindoc = createKotlindocTaskIfNeeded(project, format)
109                     if (!kotlindocreturn
110                     effectiveConfig.kotlindoc.kotlindocTasks() << kotlindoc
111 
112                     Jar kotlindocJar = createKotlindocJarTask(project, kotlindoc, format)
113                     project.tasks.findByName(org.gradle.api.plugins.BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(kotlindocJar)
114                     effectiveConfig.kotlindoc.kotlindocJarTasks() << kotlindocJar
115 
116                     effectiveConfig.kotlindoc.projects() << project
117                 }
118             }
119         }
120     }
121 
122     @CompileDynamic
123     private Task createKotlindocTaskIfNeeded(Project project, String format) {
124         String formatName = format == 'html-as-java' ? 'htmljava' : format
125         String taskName = KOTLINDOC_BASENAME + StringUtils.capitalize(formatName)
126 
127         DokkaTask kotlindocTask = project.tasks.findByName(taskName)
128         Task classesTask = project.tasks.findByName('classes')
129 
130         if (classesTask && !kotlindocTask) {
131             kotlindocTask = project.tasks.create(taskName, DokkaTask) {
132                 dependsOn classesTask
133                 group JavaBasePlugin.DOCUMENTATION_GROUP
134                 description "Generates Kotlindoc API documentation in $format format"
135                 dokkaFatJar = "org.jetbrains.dokka:dokka-fatjar:${DOKKA_VERSION.version}"
136             }
137         }
138 
139         ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
140         applyConfiguration(effectiveConfig.kotlindoc, kotlindocTask, format, formatName)
141 
142         kotlindocTask
143     }
144 
145     @CompileDynamic
146     private Jar createKotlindocJarTask(Project project, Task kotlindoc, String format) {
147         String formatName = format == 'html-as-java' ? 'htmljava' : format
148         String resolvedClassifier = 'kotlindoc'
149         String taskName = KOTLINDOC_BASENAME + StringUtils.capitalize(formatName'Jar'
150         ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
151 
152         if (effectiveConfig.kotlindoc.outputFormats.size() 1) {
153             resolvedClassifier += '-' + formatName
154         }
155 
156         Task kotlindocJarTask = project.tasks.findByName(taskName)
157 
158         if (!kotlindocJarTask) {
159             kotlindocJarTask = project.tasks.create(taskName, Jar) {
160                 dependsOn kotlindoc
161                 group JavaBasePlugin.DOCUMENTATION_GROUP
162                 description "An archive of the $format formatted Kotlindoc API docs"
163                 classifier resolvedClassifier
164                 from kotlindoc.outputDirectory
165             }
166         }
167 
168         if (effectiveConfig.kotlindoc.replaceJavadoc && effectiveConfig.kotlindoc.outputFormats.indexOf(format== 0) {
169             kotlindocJarTask.classifier = 'javadoc'
170             project.tasks.findByName(JavadocPlugin.JAVADOC_TASK_NAME)?.enabled = false
171             project.tasks.findByName(JavadocPlugin.JAVADOC_JAR_TASK_NAME)?.enabled = false
172 
173         }
174 
175         if (project.plugins.findPlugin(MavenPublishPlugin)) {
176             project.publishing {
177                 publications {
178                     main(MavenPublication) {
179                         artifact kotlindocJarTask
180                     }
181                 }
182             }
183         }
184 
185         kotlindocJarTask
186     }
187 
188     @CompileDynamic
189     static void applyConfiguration(Kotlindoc kotlindoc, DokkaTask task, String format, String formatName) {
190         task.moduleName = kotlindoc.moduleName
191         task.outputFormat = format
192         task.outputDirectory = kotlindoc.outputDirectory.absolutePath + File.separator + formatName
193         task.jdkVersion = kotlindoc.jdkVersion
194         task.cacheRoot = kotlindoc.cacheRoot
195         task.languageVersion = kotlindoc.languageVersion
196         task.languageVersion = kotlindoc.languageVersion
197         task.apiVersion = kotlindoc.apiVersion
198         task.includeNonPublic = kotlindoc.includeNonPublic
199         task.skipDeprecated = kotlindoc.skipDeprecated
200         task.reportUndocumented = kotlindoc.reportUndocumented
201         task.skipEmptyPackages = kotlindoc.skipEmptyPackages
202         task.noStdlibLink = kotlindoc.noStdlibLink
203         task.impliedPlatforms = new ArrayList<>(kotlindoc.impliedPlatforms)
204         task.includes = new ArrayList<>(kotlindoc.includes)
205         task.samples = new ArrayList<>(kotlindoc.samples)
206 
207         kotlindoc.linkMappings.resolveLinkMappings().each linkMapping ->
208             task.linkMapping {
209                 delegate.dir = linkMapping.dir
210                 delegate.url = linkMapping.url
211                 delegate.path = linkMapping.path
212                 delegate.suffix = linkMapping.suffix
213             }
214         }
215 
216         kotlindoc.externalDocumentationLinks.resolveExternalDocumentationLinks().each link ->
217             task.externalDocumentationLink {
218                 delegate.url = link.url
219                 delegate.packageListUrl = link.packageListUrl
220             }
221         }
222 
223         kotlindoc.packageOptions.resolvePackageOptions().each packageOption ->
224             task.packageOptions {
225                 delegate.prefix = packageOption.prefix
226                 delegate.includeNonPublic = packageOption.includeNonPublic
227                 delegate.reportUndocumented = packageOption.reportUndocumented
228                 delegate.skipDeprecated = packageOption.skipDeprecated
229                 delegate.suppress = packageOption.suppress
230             }
231         }
232     }
233 }