1
1
import org.gradle.util.GradleVersion
2
- import java.nio.charset.StandardCharsets ;
2
+ import java.nio.charset.StandardCharsets
3
3
4
+ // note that there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated
5
+
6
+ // conditionally apply the GE / Build Scan plugin to the classpath so it can be applied to the build further down in this script
4
7
initscript {
5
- def gradleEnterprisePluginVersion = " 3.12.4"
8
+ def isTopLevelBuild = ! gradle. parent
9
+ if (! isTopLevelBuild) {
10
+ return
11
+ }
6
12
7
- repositories {
8
- gradlePluginPortal()
13
+ def getInputParam = { String name ->
14
+ def envVarName = name. toUpperCase(). replace(' .' , ' _' ). replace(' -' , ' _' )
15
+ return System . getProperty(name) ?: System . getenv(envVarName)
16
+ }
17
+
18
+ def pluginRepositoryUrl = getInputParam(' com.gradle.enterprise.build_validation.gradle.plugin-repository.url' )
19
+ def gePluginVersion = getInputParam(' com.gradle.enterprise.build_validation.gradle-enterprise.plugin.version' )
20
+ def ccudPluginVersion = getInputParam(' com.gradle.enterprise.build_validation.ccud.plugin.version' )
21
+
22
+ def atLeastGradle5 = GradleVersion . current() >= GradleVersion . version(' 5.0' )
23
+ def atLeastGradle4 = GradleVersion . current() >= GradleVersion . version(' 4.0' )
24
+
25
+ if (gePluginVersion || ccudPluginVersion && atLeastGradle4) {
26
+ pluginRepositoryUrl = pluginRepositoryUrl ?: ' https://plugins.gradle.org/m2'
27
+ logger. quiet(" Gradle Enterprise plugins resolution: $pluginRepositoryUrl " )
28
+
29
+ repositories {
30
+ maven { url pluginRepositoryUrl }
31
+ }
9
32
}
10
33
11
34
dependencies {
12
- classpath(" com.gradle:gradle-enterprise-gradle-plugin:${ gradleEnterprisePluginVersion} " )
35
+ if (gePluginVersion) {
36
+ classpath atLeastGradle5 ?
37
+ " com.gradle:gradle-enterprise-gradle-plugin:$gePluginVersion " :
38
+ " com.gradle:build-scan-plugin:1.16"
39
+ }
40
+
41
+ if (ccudPluginVersion && atLeastGradle4) {
42
+ classpath " com.gradle:common-custom-user-data-gradle-plugin:$ccudPluginVersion "
43
+ }
13
44
}
14
45
}
15
46
16
- // Don't run against the included builds (if the main build has any).
17
- def isTopLevelBuild = gradle. getParent() == null
18
- if (isTopLevelBuild) {
19
- def version = GradleVersion . current(). baseVersion
20
- def atLeastGradle5 = version >= GradleVersion . version(" 5.0" )
21
- def atLeastGradle6 = version >= GradleVersion . version(" 6.0" )
22
- def isScanDump = System . properties. containsKey(" scan.dump" )
47
+ def BUILD_SCAN_PLUGIN_ID = ' com.gradle.build-scan'
48
+ def BUILD_SCAN_PLUGIN_CLASS = ' com.gradle.scan.plugin.BuildScanPlugin'
49
+
50
+ def GRADLE_ENTERPRISE_PLUGIN_ID = ' com.gradle.enterprise'
51
+ def GRADLE_ENTERPRISE_PLUGIN_CLASS = ' com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin'
52
+ def GRADLE_ENTERPRISE_EXTENSION_CLASS = ' com.gradle.enterprise.gradleplugin.GradleEnterpriseExtension'
53
+
54
+ def CCUD_PLUGIN_ID = ' com.gradle.common-custom-user-data-gradle-plugin'
55
+ def CCUD_PLUGIN_CLASS = ' com.gradle.CommonCustomUserDataGradlePlugin'
56
+
57
+ def isTopLevelBuild = ! gradle. parent
58
+ if (! isTopLevelBuild) {
59
+ return
60
+ }
61
+
62
+ def getInputParam = { String name ->
63
+ def envVarName = name. toUpperCase(). replace(' .' , ' _' ). replace(' -' , ' _' )
64
+ return System . getProperty(name) ?: System . getenv(envVarName)
65
+ }
66
+
67
+ def geUrl = getInputParam(' com.gradle.enterprise.build_validation.gradle-enterprise.url' )
68
+ def geAllowUntrustedServer = Boolean . parseBoolean(getInputParam(' com.gradle.enterprise.build_validation.gradle-enterprise.allow-untrusted-server' ))
69
+ def gePluginVersion = getInputParam(' com.gradle.enterprise.build_validation.gradle-enterprise.plugin.version' )
70
+ def ccudPluginVersion = getInputParam(' com.gradle.enterprise.build_validation.ccud.plugin.version' )
71
+
72
+ def atLeastGradle4 = GradleVersion . current() >= GradleVersion . version(' 4.0' )
73
+
74
+ // finish early if configuration parameters passed in via system properties are not valid/supported
75
+ if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, ' 1.7' )) {
76
+ logger. warn(" Common Custom User Data Gradle plugin must be at least 1.7. Configured version is $ccudPluginVersion . " )
77
+ return
78
+ }
79
+
80
+ // register build scan listeners to capture build scan URL/id and to track publishing errors
81
+ def registerBuildScanActions = { def buildScan ->
82
+ def scanFile = new File (experimentDir, ' build-scans.csv' )
83
+ buildScan. buildScanPublished { publishedBuildScan ->
84
+ def buildScanUri = publishedBuildScan. buildScanUri
85
+ def buildScanId = publishedBuildScan. buildScanId
86
+ def port = (buildScanUri. port != -1 ) ? ' :' + buildScanUri. port : ' '
87
+ def baseUrl = " ${ buildScanUri.scheme} ://${ buildScanUri.host}${ port} "
88
+ scanFile. append(" ${ baseUrl} ,${ buildScanUri} ,${ buildScanId} \n " )
89
+ }
90
+
91
+ def errorFile = new File (experimentDir, ' build-scan-publish-error.txt' )
92
+ buildScan. onError { error ->
93
+ errorFile. text = error
94
+ }
95
+ }
96
+
97
+ // configure build scan publishing behavior
98
+ def configureBuildScanPublishing = { def buildScan ->
99
+ buildScan. publishAlways()
100
+ // buildScan.captureTaskInputFiles = true // too late to be set here for Gradle 5, set via sys prop
101
+ if (buildScan. metaClass. respondsTo(buildScan, ' setUploadInBackground' , Boolean )) buildScan. uploadInBackground = false // uploadInBackground not available for build-scan-plugin 1.16
102
+ }
103
+
104
+ // add custom data identifying the experiment
105
+ def addBuildScanCustomData = { def buildScan ->
106
+ def projectProperties = gradle. startParameter. projectProperties
107
+
108
+ def expId = projectProperties. get(" com.gradle.enterprise.build_validation.expId" )
109
+ addCustomValueAndSearchLink(buildScan, " Experiment id" , expId)
110
+ buildScan. tag(expId)
111
+
112
+ def runId = projectProperties. get(" com.gradle.enterprise.build_validation.runId" )
113
+ addCustomValueAndSearchLink(buildScan, " Experiment run id" , runId)
114
+ }
115
+
116
+ // configure build scan behavior and optionally apply the GE / Build Scan / CCUD plugin
117
+ if (GradleVersion . current() < GradleVersion . version(' 6.0' )) {
118
+ // noinspection GroovyAssignabilityCheck
119
+ rootProject {
120
+ buildscript. configurations. getByName(" classpath" ). incoming. afterResolve { ResolvableDependencies incoming ->
121
+ def resolutionResult = incoming. resolutionResult
23
122
24
- clearWarnings()
123
+ def scanPluginComponent = resolutionResult. allComponents. find {
124
+ it. moduleVersion. with { group == " com.gradle" && (name == " build-scan-plugin" || name == " gradle-enterprise-gradle-plugin" ) }
125
+ }
25
126
26
- if (atLeastGradle6) {
27
- settingsEvaluated { settings ->
28
- if (! settings. pluginManager. hasPlugin(" com.gradle.enterprise" )) {
29
- throw new IllegalStateException (" The com.gradle.enterprise plugin is missing from the project (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_6_x_and_later)." )
127
+ if (gePluginVersion) {
128
+ if (! scanPluginComponent) {
129
+ logger. quiet(" Applying $BUILD_SCAN_PLUGIN_CLASS via init script" )
130
+ logger. quiet(" Connection to Gradle Enterprise: $geUrl , allowUntrustedServer: $geAllowUntrustedServer " )
131
+ pluginManager. apply(initscript. classLoader. loadClass(BUILD_SCAN_PLUGIN_CLASS ))
132
+ if (geUrl) buildScan. server = geUrl
133
+ if (geAllowUntrustedServer) buildScan. allowUntrustedServer = geAllowUntrustedServer
134
+ }
135
+ } else {
136
+ if (! scanPluginComponent) {
137
+ throw new IllegalStateException (" The com.gradle.build-scan plugin is missing from the project.\n " +
138
+ " Either apply it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_5_x) to the project,\n " +
139
+ " or use `--enable-gradle-enterprise` when running the build validation script." )
140
+ }
30
141
}
31
- if (! settings. pluginManager. hasPlugin(" com.gradle.common-custom-user-data-gradle-plugin" )) {
32
- logWarningMissingCommonCustomUserDataGradlePlugin()
142
+
143
+ def ccudPluginComponent = resolutionResult. allComponents. find {
144
+ it. moduleVersion. with { group == " com.gradle" && name == " common-custom-user-data-gradle-plugin" }
33
145
}
34
- if (! isScanDump) {
35
- configureGradleEnterprise(settings. extensions[" gradleEnterprise" ])
146
+
147
+ if (ccudPluginVersion && atLeastGradle4) {
148
+ if (! ccudPluginComponent) {
149
+ logger. quiet(" Applying $CCUD_PLUGIN_CLASS via init script" )
150
+ pluginManager. apply(initscript. classLoader. loadClass(CCUD_PLUGIN_CLASS ))
151
+ }
152
+ } else {
153
+ if (! ccudPluginComponent) {
154
+ logWarningMissingCommonCustomUserDataGradlePlugin()
155
+ }
36
156
}
37
157
}
38
- } else if (atLeastGradle5) {
39
- projectsEvaluated { gradle ->
40
- if (! gradle. rootProject. pluginManager. hasPlugin(" com.gradle.build-scan" )) {
41
- throw new IllegalStateException (" The com.gradle.build-scan plugin is missing from the project (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_5_x)." )
158
+
159
+ pluginManager. withPlugin(BUILD_SCAN_PLUGIN_ID ) {
160
+ afterEvaluate {
161
+ if (geUrl) buildScan. server = geUrl
162
+ if (geAllowUntrustedServer) buildScan. allowUntrustedServer = geAllowUntrustedServer
163
+
164
+ registerBuildScanActions(buildScan)
165
+ addBuildScanCustomData(buildScan)
166
+ configureBuildScanPublishing(buildScan)
42
167
}
43
- if (! gradle. rootProject. pluginManager. hasPlugin(" com.gradle.common-custom-user-data-gradle-plugin" )) {
44
- logWarningMissingCommonCustomUserDataGradlePlugin()
168
+ }
169
+ }
170
+ } else {
171
+ gradle. settingsEvaluated { settings ->
172
+ if (gePluginVersion) {
173
+ if (! settings. pluginManager. hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID )) {
174
+ logger. quiet(" Applying $GRADLE_ENTERPRISE_PLUGIN_CLASS via init script" )
175
+ logger. quiet(" Connection to Gradle Enterprise: $geUrl , allowUntrustedServer: $geAllowUntrustedServer " )
176
+ settings. pluginManager. apply(initscript. classLoader. loadClass(GRADLE_ENTERPRISE_PLUGIN_CLASS ))
177
+ extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS ). collect { settings[it. name] }. each { ext ->
178
+ if (geUrl) ext. server = geUrl
179
+ if (geAllowUntrustedServer) ext. allowUntrustedServer = geAllowUntrustedServer
180
+ }
45
181
}
46
- if (! isScanDump) {
47
- configureGradleEnterprise(gradle. rootProject. extensions[" gradleEnterprise" ])
182
+ } else {
183
+ if (! settings. pluginManager. hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID )) {
184
+ throw new IllegalStateException (" The com.gradle.enterprise plugin is missing from the project.\n " +
185
+ " Either apply it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_6_x_and_later),\n " +
186
+ " or use `--enable-gradle-enterprise` when running the build validation script." )
48
187
}
49
188
}
50
- } else {
51
- throw new IllegalStateException (" Build validation not supported for Gradle ${ GradleVersion.current()} . Upgrade your project's build to Gradle 5 or newer." )
52
- }
53
- }
54
189
55
- void configureGradleEnterprise (gradleEnterprise ) {
56
- gradleEnterprise. with {
57
- buildScan {
58
- def projectProperties = gradle. startParameter. projectProperties
59
- if (projectProperties. containsKey(" com.gradle.enterprise.build_validation.server" )) {
60
- server = projectProperties. get(" com.gradle.enterprise.build_validation.server" )
190
+ if (ccudPluginVersion) {
191
+ if (! settings. pluginManager. hasPlugin(CCUD_PLUGIN_ID )) {
192
+ logger. quiet(" Applying $CCUD_PLUGIN_CLASS via init script" )
193
+ settings. pluginManager. apply(initscript. classLoader. loadClass(CCUD_PLUGIN_CLASS ))
61
194
}
62
-
63
- if (! server ) {
64
- throw new IllegalStateException ( " A Gradle Enterprise server URL has not been configured. " , null )
195
+ } else {
196
+ if (! settings . pluginManager . hasPlugin( CCUD_PLUGIN_ID ) ) {
197
+ logWarningMissingCommonCustomUserDataGradlePlugin( )
65
198
}
199
+ }
200
+
201
+ extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS ). collect { settings[it. name] }. each { ext ->
202
+ if (geUrl) ext. server = geUrl
203
+ if (geAllowUntrustedServer) ext. allowUntrustedServer = geAllowUntrustedServer
66
204
67
- // captureTaskInputFiles = true (too late to be set here for Gradle 5, set via sys prop )
68
- uploadInBackground = false
69
- publishAlways( )
205
+ registerBuildScanActions(ext . buildScan )
206
+ addBuildScanCustomData(ext . buildScan)
207
+ configureBuildScanPublishing(ext . buildScan )
70
208
}
71
- addCustomData(buildScan)
72
209
}
73
210
}
74
211
75
- void addCustomData (buildScan ) {
76
- def projectProperties = gradle. startParameter. projectProperties
77
-
78
- def expId = projectProperties. get(" com.gradle.enterprise.build_validation.expId" )
79
- addCustomValueAndSearchLink(buildScan, " Experiment id" , expId)
80
- buildScan. tag(expId)
212
+ static def extensionsWithPublicType (def container , String publicType ) {
213
+ container. extensions. extensionsSchema. elements. findAll { it. publicType. concreteClass. name == publicType }
214
+ }
81
215
82
- def runId = projectProperties . get( " com.gradle.enterprise.build_validation.runId " )
83
- addCustomValueAndSearchLink(buildScan, " Experiment run id " , runId )
216
+ static boolean isNotAtLeast ( String versionUnderTest , String referenceVersion ) {
217
+ GradleVersion . version(versionUnderTest) < GradleVersion . version(referenceVersion )
84
218
}
85
219
86
- void addCustomValueAndSearchLink (buildScan , String label , String value ) {
220
+ static void addCustomValueAndSearchLink (buildScan , String label , String value ) {
87
221
buildScan. value(label, value)
88
- String server = buildScan. server
89
- String searchParams = " search.names=" + urlEncode(label) + " &search.values=" + urlEncode(value)
90
- String url = appendIfMissing(server, " /" ) + " scans?" + searchParams + " #selection.buildScanB=" + urlEncode(" {SCAN_ID}" )
91
- buildScan. link(label + " build scans" , url)
222
+ if (buildScan. metaClass. respondsTo(buildScan, ' getServer' )) { // required for Gradle 4.x / build-scan-plugin 1.16
223
+ String server = buildScan. server
224
+ String searchParams = " search.names=" + urlEncode(label) + " &search.values=" + urlEncode(value)
225
+ String url = appendIfMissing(server, " /" ) + " scans?" + searchParams + " #selection.buildScanB=" + urlEncode(" {SCAN_ID}" )
226
+ buildScan. link(label + " build scans" , url)
227
+ }
92
228
}
93
229
94
- String appendIfMissing (String str , String suffix ) {
230
+ static String appendIfMissing (String str , String suffix ) {
95
231
return str. endsWith(suffix) ? str : str + suffix
96
232
}
97
233
98
- String urlEncode (String str ) {
234
+ static String urlEncode (String str ) {
99
235
return URLEncoder . encode(str, StandardCharsets . UTF_8 . name())
100
236
}
101
237
@@ -108,11 +244,6 @@ void logWarning(String warning) {
108
244
warningFile. append(warning + " \n " )
109
245
}
110
246
111
- void clearWarnings () {
112
- def warningFile = new File (experimentDir, " warnings.txt" )
113
- warningFile. delete()
114
- }
115
-
116
247
File getExperimentDir () {
117
248
def projectProperties = gradle. startParameter. projectProperties
118
249
new File (projectProperties. get(" com.gradle.enterprise.build_validation.experimentDir" ))
0 commit comments