SettingsPlugin.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.settings
019 
020 import groovy.transform.CompileStatic
021 import org.gradle.BuildAdapter
022 import org.gradle.api.Plugin
023 import org.gradle.api.initialization.Settings
024 
025 /**
026  @author Andres Almiray
027  @since 0.15.0
028  */
029 @CompileStatic
030 class SettingsPlugin implements Plugin<Settings> {
031     private Settings settings
032 
033     @Override
034     void apply(Settings settings) {
035         this.settings = settings
036 
037         if (!settings.extensions.findByType(ProjectsExtension)) {
038             settings.extensions.create(ProjectsExtension.EXTENSION_NAME, ProjectsExtension)
039         }
040 
041         settings.gradle.addBuildListener(new BuildAdapter() {
042             @Override
043             void settingsEvaluated(Settings s) {
044                 ProjectsExtension projects = (ProjectsExtensionsettings.extensions.findByName(ProjectsExtension.EXTENSION_NAME)
045 
046                 if ('two-level' == projects.layout?.toLowerCase()) {
047                     processTwoLevelLayout()
048                 else if ('multi-level' == projects.layout?.toLowerCase()) {
049                     processMultiLevelLayout()
050                 else if ('standard' == projects.layout?.toLowerCase()) {
051                     processStandardLayout()
052                 else {
053                     println "Unknown project layout '${projects.layout}'. No subprojects will be added."
054                 }
055             }
056         })
057     }
058 
059     private void processTwoLevelLayout() {
060         ProjectsExtension projects = (ProjectsExtensionsettings.extensions.findByName(ProjectsExtension.EXTENSION_NAME)
061 
062         if (projects.directories) {
063             for (String parentDirName : projects.directories) {
064                 File parentDir = new File(settings.rootDir, parentDirName)
065                 if (!parentDir.exists()) {
066                     println "Skipping ${parentDir} as it does not exist"
067                     continue
068                 }
069 
070                 doProcessTwoLevelLayout(projects, parentDir)
071             }
072         else {
073             settings.settingsDir.eachDir File parentDir ->
074                 doProcessTwoLevelLayout(projects, parentDir)
075             }
076         }
077     }
078 
079     private void doProcessTwoLevelLayout(ProjectsExtension projects, File parentDir) {
080         parentDir.eachDir File projectDir ->
081             if (projects.excludes.contains(projectDir.name)) return
082 
083             File buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectDir.name}.gradle".toString() 'build.gradle')
084             if (!buildFile.exists()) {
085                 buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectDir.name}.gradle.kts".toString() 'build.gradle.kts')
086             }
087             if (buildFile.exists()) {
088                 includeProject(parentDir, projectDir.name, buildFile)
089             }
090         }
091     }
092 
093     private void processMultiLevelLayout() {
094         ProjectsExtension projects = (ProjectsExtensionsettings.extensions.findByName(ProjectsExtension.EXTENSION_NAME)
095 
096         for (String path : projects.directories) {
097             File projectDir = new File(settings.rootDir, path)
098             if (!projectDir.exists()) {
099                 println "Skipping ${projectDir} as it does not exist"
100                 continue
101             }
102             includeProject(projects, path)
103         }
104     }
105 
106     private void processStandardLayout() {
107         ProjectsExtension projects = (ProjectsExtensionsettings.extensions.findByName(ProjectsExtension.EXTENSION_NAME)
108 
109         settings.rootDir.eachDir File projectDir ->
110             if (projects.excludes.contains(projectDir.name)) return
111 
112             File buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectDir.name}.gradle".toString() 'build.gradle')
113             if (!buildFile.exists()) {
114                 buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectDir.name}.gradle.kts".toString() 'build.gradle.kts')
115             }
116             if (buildFile.exists()) {
117                 includeProject(settings.rootDir, projectDir.name, buildFile)
118             }
119         }
120     }
121 
122     private void includeProject(File parentDir, String projectDirName, File buildFile) {
123         File projectDir = new File(parentDir, projectDirName)
124 
125         settings.include(projectDirName)
126         settings.project(":${projectDirName}").projectDir = projectDir
127         settings.project(":${projectDirName}").buildFileName = buildFile.name
128     }
129 
130     private void includeProject(ProjectsExtension projects, String projectPath) {
131         String[] parts = projectPath.split('/')
132         String projectDirName = projectPath
133         String projectName = parts[-1]
134 
135         if (projects.excludes.contains(projectName)) return
136 
137         File projectDir = new File(projectDirName)
138 
139         assert projectDir.isDirectory()
140 
141         File buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectName}.gradle".toString() 'build.gradle')
142         if (!buildFile.exists()) {
143             buildFile = new File(projectDir, projects.enforceNamingConvention ? "${projectName}.gradle.kts".toString() 'build.gradle.kts')
144         }
145         if (buildFile.exists()) {
146             settings.include(projectName)
147             settings.project(":${projectName}").projectDir = projectDir
148             settings.project(":${projectName}").buildFileName = buildFile.name
149         }
150     }
151 }