BomPlugin.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.bom
019 
020 import groovy.transform.CompileDynamic
021 import groovy.transform.CompileStatic
022 import org.gradle.api.Project
023 import org.gradle.api.publish.maven.MavenPublication
024 import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
025 import org.gradle.plugins.signing.SigningPlugin
026 import org.kordamp.gradle.plugin.AbstractKordampPlugin
027 import org.kordamp.gradle.plugin.base.BasePlugin
028 import org.kordamp.gradle.plugin.base.ProjectConfigurationExtension
029 import org.kordamp.gradle.plugin.base.model.Credentials
030 import org.kordamp.gradle.plugin.base.model.Dependency
031 import org.kordamp.gradle.plugin.base.model.Repository
032 import org.kordamp.gradle.plugin.base.plugins.util.PublishingUtils
033 
034 import static org.kordamp.gradle.PluginUtils.resolveEffectiveConfig
035 import static org.kordamp.gradle.StringUtils.isNotBlank
036 
037 /**
038  * Generates a BOM file for the given inputs.
039  *
040  @author Andres Almiray
041  @since 0.9.0
042  */
043 @CompileStatic
044 class BomPlugin extends AbstractKordampPlugin {
045     Project project
046 
047     void apply(Project project) {
048         this.project = project
049 
050         configureProject(project)
051     }
052 
053     static void applyIfMissing(Project project) {
054         if (!project.plugins.findPlugin(BomPlugin)) {
055             project.pluginManager.apply(BomPlugin)
056         }
057         if (!project.plugins.findPlugin(SigningPlugin)) {
058             project.pluginManager.apply(SigningPlugin)
059         }
060     }
061 
062     private void configureProject(Project project) {
063         if (hasBeenVisited(project)) {
064             return
065         }
066         setVisited(project, true)
067 
068         BasePlugin.applyIfMissing(project)
069 
070         if (!project.plugins.findPlugin(MavenPublishPlugin)) {
071             project.pluginManager.apply(MavenPublishPlugin)
072         }
073 
074         project.extensions.findByType(ProjectConfigurationExtension).publishing.enabled = false
075 
076         project.afterEvaluate {
077             updatePublications(project)
078         }
079     }
080 
081     @CompileDynamic
082     private void updatePublications(Project project) {
083         ProjectConfigurationExtension effectiveConfig = resolveEffectiveConfig(project)
084         setEnabled(effectiveConfig.bom.enabled)
085 
086         if (!enabled) {
087             return
088         }
089 
090         List<Dependency> compileDeps = effectiveConfig.bom.compile.collect Dependency.parseDependency(project, it) }
091         List<Dependency> runtimeDeps = effectiveConfig.bom.runtime.collect Dependency.parseDependency(project, it) }
092         List<Dependency> testDeps = effectiveConfig.bom.test.collect Dependency.parseDependency(project, it) }
093 
094         if (effectiveConfig.bom.autoIncludes) {
095             project.rootProject.subprojects.each Project prj ->
096                 if (prj == projectreturn
097 
098                 Closure<Boolean> predicate = Dependency d ->
099                     d.artifactId == prj.name && (d.groupId == project.group || d.groupId == '${project.groupId}')
100                 }
101                 if ((!effectiveConfig.bom.excludes.contains(prj.name&& !effectiveConfig.bom.excludes.contains(':' + prj.name)) &&
102                     !compileDeps.find(predicate&& !runtimeDeps.find(predicate&& !testDeps.find(predicate)) {
103                     compileDeps << new Dependency('${project.groupId}', prj.name, '${project.version}')
104                 }
105             }
106         }
107 
108         project.publishing {
109             publications {
110                 main(MavenPublication) {
111                     artifacts = []
112 
113                     PublishingUtils.configurePom(pom, effectiveConfig, effectiveConfig.bom)
114 
115                     pom {
116                         packaging = 'pom'
117                     }
118 
119                     pom.withXml {
120                         def dependencyManagementNode = asNode().appendNode('dependencyManagement').appendNode('dependencies')
121                         compileDeps.each Dependency dep ->
122                             dependencyManagementNode.appendNode('dependency').with {
123                                 appendNode('groupId', dep.groupId)
124                                 appendNode('artifactId', dep.artifactId)
125                                 appendNode('version', dep.version)
126                             }
127                         }
128                         runtimeDeps.each Dependency dep ->
129                             dependencyManagementNode.appendNode('dependency').with {
130                                 appendNode('groupId', dep.groupId)
131                                 appendNode('artifactId', dep.artifactId)
132                                 appendNode('version', dep.version)
133                                 appendNode('scope', 'runtime')
134                             }
135                         }
136                         testDeps.each Dependency dep ->
137                             dependencyManagementNode.appendNode('dependency').with {
138                                 appendNode('groupId', dep.groupId)
139                                 appendNode('artifactId', dep.artifactId)
140                                 appendNode('version', dep.version)
141                                 appendNode('scope', 'test')
142                             }
143                         }
144                     }
145                 }
146             }
147 
148             String repositoryName = effectiveConfig.release ? effectiveConfig.publishing.releasesRepository : effectiveConfig.publishing.snapshotsRepository
149             if (isNotBlank(repositoryName)) {
150                 Repository repo = effectiveConfig.info.repositories.getRepository(repositoryName)
151                 if (repo == null) {
152                     throw new IllegalStateException("Repository '${repositoryName}' was not found")
153                 }
154 
155                 repositories {
156                     maven {
157                         name = repositoryName
158                         url = repo.url
159                         Credentials creds = effectiveConfig.info.credentials.getCredentials(repo.name)
160                         if (repo.credentials && !repo.credentials.empty) {
161                             credentials {
162                                 username = repo.credentials.username
163                                 password = repo.credentials.password
164                             }
165                         else if (creds && !creds.empty) {
166                             credentials {
167                                 username = creds.username
168                                 password = creds.password
169                             }
170                         }
171                     }
172                 }
173             }
174         }
175 
176         PublishingUtils.configureSigning(effectiveConfig, project)
177     }
178 }