SourceJarPlugin.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  *     https://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.source
019 
020 import groovy.transform.CompileDynamic
021 import groovy.transform.CompileStatic
022 import org.gradle.BuildAdapter
023 import org.gradle.api.Action
024 import org.gradle.api.Project
025 import org.gradle.api.Task
026 import org.gradle.api.invocation.Gradle
027 import org.gradle.api.tasks.TaskProvider
028 import org.gradle.api.tasks.bundling.Jar
029 import org.kordamp.gradle.PluginUtils
030 import org.kordamp.gradle.plugin.AbstractKordampPlugin
031 import org.kordamp.gradle.plugin.base.BasePlugin
032 import org.kordamp.gradle.plugin.base.ProjectConfigurationExtension
033 import org.kordamp.gradle.plugin.base.plugins.Source
034 
035 import static org.kordamp.gradle.PluginUtils.resolveEffectiveConfig
036 import static org.kordamp.gradle.plugin.base.BasePlugin.isRootProject
037 
038 /**
039  * Configures a {@code sourceJar} task.
040  *
041  @author Andres Almiray
042  @since 0.1.0
043  */
044 @CompileStatic
045 class SourceJarPlugin extends AbstractKordampPlugin {
046     static final String SOURCE_JAR_TASK_NAME = 'sourceJar'
047     static final String AGGREGATE_SOURCE_JAR_TASK_NAME = 'aggregateSourceJar'
048 
049     Project project
050 
051     void apply(Project project) {
052         this.project = project
053 
054         if (isRootProject(project)) {
055             project.childProjects.values().each {
056                 configureProject(it)
057             }
058         }
059         configureProject(project)
060     }
061 
062     static void applyIfMissing(Project project) {
063         if (!project.plugins.findPlugin(SourceJarPlugin)) {
064             project.pluginManager.apply(SourceJarPlugin)
065         }
066     }
067 
068     private void configureProject(Project project) {
069         if (hasBeenVisited(project)) {
070             return
071         }
072         setVisited(project, true)
073 
074         BasePlugin.applyIfMissing(project)
075 
076         project.pluginManager.withPlugin('java-base') {
077             project.afterEvaluate {
078                 ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
079                 setEnabled(effectiveConfig.source.enabled)
080 
081                 if (!enabled) {
082                     return
083                 }
084 
085                 TaskProvider<Jar> sourceTask = createSourceJarTask(project)
086                 if (sourceTask) {
087                     effectiveConfig.source.sourceTasks() << sourceTask
088                     effectiveConfig.source.projects() << project
089                 }
090             }
091         }
092 
093         if (isRootProject(project&& !project.childProjects.isEmpty()) {
094             TaskProvider<Jar> sourceJarTask = project.tasks.register(AGGREGATE_SOURCE_JAR_TASK_NAME, Jar,
095                 new Action<Jar>() {
096                     @Override
097                     void execute(Jar t) {
098                         t.group = org.gradle.api.plugins.BasePlugin.BUILD_GROUP
099                         t.description = 'An archive of all the source code.'
100                         t.archiveClassifier.set('sources')
101                         t.enabled = false
102                     }
103                 })
104             project.gradle.addBuildListener(new BuildAdapter() {
105                 @Override
106                 void projectsEvaluated(Gradle gradle) {
107                     configureAggregateSourceJarTask(project, sourceJarTask)
108                 }
109             })
110         }
111     }
112 
113     private TaskProvider<Jar> createSourceJarTask(Project project) {
114         Task classesTask = project.tasks.findByName('classes')
115 
116         if (classesTask) {
117             TaskProvider<Jar> sourceJarTask = project.tasks.register(SOURCE_JAR_TASK_NAME, Jar,
118                 new Action<Jar>() {
119                     @Override
120                     @CompileDynamic
121                     void execute(Jar t) {
122                         t.group = org.gradle.api.plugins.BasePlugin.BUILD_GROUP
123                         t.description = 'An archive of the source code.'
124                         t.archiveClassifier.set('sources')
125                         t.dependsOn classesTask
126                         t.from PluginUtils.resolveSourceSets(project).main.allSource
127                     }
128                 })
129 
130             project.tasks.findByName(org.gradle.api.plugins.BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(sourceJarTask)
131             return sourceJarTask
132         }
133 
134         return null
135     }
136 
137     private void configureAggregateSourceJarTask(Project project, TaskProvider<Jar> sourceJarTask) {
138         ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
139 
140         Set<Project> projects = new LinkedHashSet<>(effectiveConfig.source.projects())
141         Set<TaskProvider<Jar>> sourceTasks = new LinkedHashSet<>(effectiveConfig.source.sourceTasks())
142 
143         project.childProjects.values().each {
144             Source e = resolveEffectiveConfig(it).source
145             if (!e.enabled || effectiveConfig.source.excludedProjects().intersect(e.projects())) return
146             projects.addAll(e.projects())
147             sourceTasks.addAll(e.sourceTasks())
148         }
149 
150         sourceJarTask.configure(new Action<Jar>() {
151             @Override
152             @CompileDynamic
153             void execute(Jar t) {
154                 t.dependsOn sourceTasks
155                 t.from PluginUtils.resolveSourceSets(projects).main.allSource
156                 t.enabled = true
157             }
158         })
159     }
160 }