131157974SDawid Weiss/* 231157974SDawid Weiss * Licensed to the Apache Software Foundation (ASF) under one or more 331157974SDawid Weiss * contributor license agreements. See the NOTICE file distributed with 431157974SDawid Weiss * this work for additional information regarding copyright ownership. 531157974SDawid Weiss * The ASF licenses this file to You under the Apache License, Version 2.0 631157974SDawid Weiss * (the "License"); you may not use this file except in compliance with 731157974SDawid Weiss * the License. You may obtain a copy of the License at 831157974SDawid Weiss * 931157974SDawid Weiss * http://www.apache.org/licenses/LICENSE-2.0 1031157974SDawid Weiss * 1131157974SDawid Weiss * Unless required by applicable law or agreed to in writing, software 1231157974SDawid Weiss * distributed under the License is distributed on an "AS IS" BASIS, 1331157974SDawid Weiss * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1431157974SDawid Weiss * See the License for the specific language governing permissions and 1531157974SDawid Weiss * limitations under the License. 1631157974SDawid Weiss */ 1731157974SDawid Weiss 1831157974SDawid Weissallprojects { 1931157974SDawid Weiss apply plugin: 'base' 2031157974SDawid Weiss 2131157974SDawid Weiss group "org.apache" 2231157974SDawid Weiss 2331157974SDawid Weiss // Repositories to fetch dependencies from. 2431157974SDawid Weiss repositories { 2531157974SDawid Weiss mavenCentral() 2631157974SDawid Weiss } 2731157974SDawid Weiss 2831157974SDawid Weiss // Artifacts will have names after full gradle project path 2931157974SDawid Weiss // so :solr:core will have solr-core.jar, etc. 3031157974SDawid Weiss project.archivesBaseName = project.path.replaceAll("^:", "").replace(':', '-') 3131157974SDawid Weiss 3231157974SDawid Weiss ext { 3331157974SDawid Weiss // Utility method to support passing overrides via -P or -D. 3431157974SDawid Weiss propertyOrDefault = { propName, defValue -> 3531157974SDawid Weiss def result 3631157974SDawid Weiss if (project.hasProperty(propName)) { 3731157974SDawid Weiss result = project.getProperty(propName) 3831157974SDawid Weiss } else if (System.properties.containsKey(propName)) { 3931157974SDawid Weiss result = System.properties.get(propName) 4031157974SDawid Weiss } else if (defValue instanceof Closure) { 4131157974SDawid Weiss result = defValue.call() 4231157974SDawid Weiss } else { 4331157974SDawid Weiss result = defValue 4431157974SDawid Weiss } 4531157974SDawid Weiss return result 4631157974SDawid Weiss } 4731157974SDawid Weiss 4831157974SDawid Weiss // System environment variable or default. 4931157974SDawid Weiss envOrDefault = { envName, defValue -> 508bcc3dc4SDawid Weiss def result = System.getenv(envName) 518bcc3dc4SDawid Weiss if (result == null) { 528bcc3dc4SDawid Weiss result = defValue 538bcc3dc4SDawid Weiss } 548bcc3dc4SDawid Weiss return result 5531157974SDawid Weiss } 5631157974SDawid Weiss 5731157974SDawid Weiss // Either a project, system property, environment variable or default value. 5831157974SDawid Weiss propertyOrEnvOrDefault = { propName, envName, defValue -> 5931157974SDawid Weiss return propertyOrDefault(propName, envOrDefault(envName, defValue)); 6031157974SDawid Weiss } 6131157974SDawid Weiss 6231157974SDawid Weiss // Locate script-relative resource folder. This is context-sensitive so pass 6331157974SDawid Weiss // the right buildscript (top-level). 6431157974SDawid Weiss scriptResources = { buildscript -> 6531157974SDawid Weiss return file(buildscript.sourceFile.absolutePath.replaceAll('.gradle$', "")) 6631157974SDawid Weiss } 6731157974SDawid Weiss 6839b8e976SDawid Weiss // Utility function similar to project.exec but not emitting 6939b8e976SDawid Weiss // any output unless an error code is returned from the executed command. 7039b8e976SDawid Weiss quietExec = { closure -> 7139b8e976SDawid Weiss // Resolve any properties against the provided closure. 7239b8e976SDawid Weiss resolveStrategy = Closure.DELEGATE_ONLY 7339b8e976SDawid Weiss delegate = closure.delegate 7439b8e976SDawid Weiss 7539b8e976SDawid Weiss File outputFile = File.createTempFile("exec-output-", ".txt", getTemporaryDir()) 7639b8e976SDawid Weiss ExecResult result 7739b8e976SDawid Weiss boolean saveIgnoreExitValue 7839b8e976SDawid Weiss ExecSpec saveExecSpec 7939b8e976SDawid Weiss 8039b8e976SDawid Weiss outputFile.withOutputStream { output -> 8139b8e976SDawid Weiss // we want to capture both stdout and stderr to the same 8239b8e976SDawid Weiss // stream but gradle attempts to close these separately 8339b8e976SDawid Weiss // (it has two independent pumping threads) and it can happen 8439b8e976SDawid Weiss // that one still tries to write something when the other closed 8539b8e976SDawid Weiss // the underlying output stream. 8639b8e976SDawid Weiss def wrapped = new java.io.FilterOutputStream(output) { 8739b8e976SDawid Weiss public void close() { 8839b8e976SDawid Weiss // no-op. we close this stream manually. 8939b8e976SDawid Weiss } 9039b8e976SDawid Weiss } 9139b8e976SDawid Weiss 9239b8e976SDawid Weiss result = project.exec { ExecSpec execSpec -> 9339b8e976SDawid Weiss project.configure(execSpec, closure) 9439b8e976SDawid Weiss 9539b8e976SDawid Weiss saveIgnoreExitValue = execSpec.ignoreExitValue 9639b8e976SDawid Weiss saveExecSpec = execSpec 9739b8e976SDawid Weiss 9839b8e976SDawid Weiss standardOutput = wrapped 9939b8e976SDawid Weiss errorOutput = wrapped 10039b8e976SDawid Weiss ignoreExitValue true 10139b8e976SDawid Weiss } 10239b8e976SDawid Weiss } 10339b8e976SDawid Weiss 10439b8e976SDawid Weiss if (result.getExitValue() != 0) { 10539b8e976SDawid Weiss // Pipe the output to console. Intentionally skips any encoding conversion 10639b8e976SDawid Weiss // and pumps raw bytes. 10739b8e976SDawid Weiss logger.error(new String(outputFile.bytes)) 10839b8e976SDawid Weiss 10939b8e976SDawid Weiss if (!saveIgnoreExitValue) { 11039b8e976SDawid Weiss result.rethrowFailure() 11139b8e976SDawid Weiss throw new GradleException("The executed process ${saveExecSpec.executable} " + 11239b8e976SDawid Weiss "returned an odd status " + 11339b8e976SDawid Weiss "code: ${result.exitValue}, " + 11439b8e976SDawid Weiss "output at: ${outputFile} (and logged above).") 11539b8e976SDawid Weiss } 11639b8e976SDawid Weiss } 11739b8e976SDawid Weiss 11839b8e976SDawid Weiss return result 11939b8e976SDawid Weiss } 120e3ae57a3SDawid Weiss 121e3ae57a3SDawid Weiss // Convert a list of strings, tasks and task providers into resolved tasks or task providers. 122e3ae57a3SDawid Weiss resolveTaskRefs = { List<Object> refs -> 123e3ae57a3SDawid Weiss def resolved = refs.collect { 124e3ae57a3SDawid Weiss if (it instanceof Task) return it 125e3ae57a3SDawid Weiss if (it instanceof TaskProvider) return it 126e3ae57a3SDawid Weiss if (it instanceof String) return project.tasks.named((String) it) 127e3ae57a3SDawid Weiss throw new GradleException("Can't resolve task: ${it}") 128e3ae57a3SDawid Weiss } 129e3ae57a3SDawid Weiss return resolved 130e3ae57a3SDawid Weiss } 131e3ae57a3SDawid Weiss 132e3ae57a3SDawid Weiss // Forces sequential ordering of a list of tasks (via mustRunAfter). 133e3ae57a3SDawid Weiss // This method should not be required in 99% of cases, consider regular dependsOn links. 134e3ae57a3SDawid Weiss // This method does NOT imply any ordering between dependencies of task on the input 135e3ae57a3SDawid Weiss // list - the execution of these may still be unordered. 136e3ae57a3SDawid Weiss mustRunInOrder = { List<Object> taskList -> 137e3ae57a3SDawid Weiss project.afterEvaluate { 138e3ae57a3SDawid Weiss def resolved = resolveTaskRefs(taskList) 139e3ae57a3SDawid Weiss 140e3ae57a3SDawid Weiss // Enforce sequential ordering between tasks (this does NOT apply to their dependencies!) 141e3ae57a3SDawid Weiss for (int i = 1; i < resolved.size(); i++) { 142e3ae57a3SDawid Weiss resolved[i].configure { 143e3ae57a3SDawid Weiss logger.info("Scheduling " + resolved[i].name + " to run after " + resolved[i - 1].name) 144e3ae57a3SDawid Weiss mustRunAfter resolved[i - 1] 145e3ae57a3SDawid Weiss } 146e3ae57a3SDawid Weiss } 147e3ae57a3SDawid Weiss } 148e3ae57a3SDawid Weiss return taskList 149e3ae57a3SDawid Weiss } 150*7a8071c9SUwe Schindler 151*7a8071c9SUwe Schindler // detect if we run in CI environment by looking at existence of env vars: 152*7a8071c9SUwe Schindler // "CI": Github (https://docs.github.com/en/actions/learn-github-actions/environment-variables) 153*7a8071c9SUwe Schindler // anything starting with "JENKINS_" or "HUDSON_": Jenkins/Hudson (https://jenkins.thetaphi.de/env-vars.html/) 154*7a8071c9SUwe Schindler isCIBuild = System.getenv().keySet().find { it ==~ /(?i)((JENKINS|HUDSON)(_\w+)?|CI)/ } != null 15531157974SDawid Weiss } 15631157974SDawid Weiss} 157