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