1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import org.yaml.snakeyaml.Yaml
9 if (hasProperty("centralRepo")) {
12 url property("centralRepo")
20 classpath 'org.yaml:snakeyaml:1.23'
26 directory = new File(rootDir, '.build-cache')
27 removeUnusedEntriesAfterDays = 30
31 // Synchronized library configuration for all modules
32 // This "componentsVersion" number is defined in "version.txt" and should follow
33 // semantic versioning (MAJOR.MINOR.PATCH). See https://semver.org/
36 public final String componentsVersion
37 public final String componentsGroupId
38 public final Integer compileSdkVersion
39 public final Integer minSdkVersion
40 public final Integer targetSdkVersion
43 String componentsVersion,
44 String componentsGroupId,
45 Integer compileSdkVersion,
46 Integer minSdkVersion,
47 Integer targetSdkVersion
49 this.componentsVersion = componentsVersion
50 this.componentsGroupId = componentsGroupId
51 this.compileSdkVersion = compileSdkVersion
52 this.minSdkVersion = minSdkVersion
53 this.targetSdkVersion = targetSdkVersion
57 def setupProject(name, path, description) {
58 settings.include(":$name")
60 project(":$name").projectDir = new File(rootDir, path)
62 // project(...) gives us a skeleton project that we can't set ext.* on
63 gradle.beforeProject { project ->
64 // However, the "afterProject" listener iterates over every project and gives us the actual project
65 // So, once we filter for the project we care about, we can set whatever we want
66 if (project.name == name) {
67 project.ext.description = description
73 def buildconfig = yaml.load(new File(rootDir, '.buildconfig.yml').newInputStream())
74 def componentsVersion = new File(rootDir, 'version.txt').text.replaceAll('\\n', '')
75 buildconfig.projects.each { project ->
76 setupProject(project.key, project.value.path, project.value.description)
79 gradle.projectsLoaded { ->
80 def configData = yaml.load(new File(rootDir, '.config.yml').newInputStream())
81 String version = componentsVersion
83 if (gradle.rootProject.hasProperty("nightlyVersion")) {
84 version = gradle.rootProject.nightlyVersion
85 } else if (gradle.rootProject.hasProperty("local")) {
86 // To support local auto-publication workflow, we use a version prefix we wouldn't normally encounter.
88 } else if (gradle.hasProperty("localProperties.branchBuild.android-components.version")) {
89 version = gradle.getProperty("localProperties.branchBuild.android-components.version")
91 // Wait until root project is "loaded" before we set "config"
92 // Note that since this is set on "rootProject.ext", it will be "in scope" during the evaluation of all projects'
93 // gradle files. This means that they can just access "config.<value>", and it'll function properly
94 gradle.rootProject.ext.config = new Config(
96 configData.componentsGroupId,
97 configData.compileSdkVersion,
98 configData.minSdkVersion,
99 configData.targetSdkVersion
101 gradle.rootProject.ext.buildConfig = buildconfig
104 def runCmd(cmd, workingDir, successMessage) {
105 def proc = cmd.execute(null, new File(workingDir))
106 proc.consumeProcessOutput(System.out, System.err)
108 if (proc.exitValue() != 0) {
109 throw new GradleException("Process '${cmd}' finished with non-zero exit value ${proc.exitValue()}")
111 logger.lifecycle(successMessage)
115 //////////////////////////////////////////////////////////////////////////
116 // Local Development overrides
117 //////////////////////////////////////////////////////////////////////////
119 Properties localProperties = null;
120 String settingAppServicesPath = "autoPublish.application-services.dir"
121 String settingGleanPath = "autoPublish.glean.dir";
123 if (file('local.properties').canRead()) {
124 localProperties = new Properties()
125 localProperties.load(file('local.properties').newDataInputStream())
126 logger.lifecycle('Local configuration: loaded local.properties')
128 logger.lifecycle('Local configuration: absent local.properties; proceeding as normal.')
131 if (localProperties != null) {
132 localProperties.each { prop ->
133 gradle.ext.set("localProperties.${prop.key}", prop.value)
136 String appServicesLocalPath = localProperties.getProperty(settingAppServicesPath);
138 if (appServicesLocalPath != null) {
139 logger.lifecycle("Enabling automatic publication of application-services from: $appServicesLocalPath")
140 // Windows can't execute .py files directly, so we assume a "manually installed" python,
141 // which comes with a "py" launcher and respects the shebang line to specify the version.
142 def publishAppServicesCmd = [];
143 if (System.properties['os.name'].toLowerCase().contains('windows')) {
144 publishAppServicesCmd << "py";
146 publishAppServicesCmd << "./automation/publish_to_maven_local_if_modified.py";
147 runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.")
149 logger.lifecycle("Disabled auto-publication of application-services. Enable it by settings '$settingAppServicesPath' in local.properties")
152 String gleanLocalPath = localProperties.getProperty(settingGleanPath);
154 if (gleanLocalPath != null) {
155 logger.lifecycle("Enabling automatic publication of Glean from: $gleanLocalPath")
156 // Windows can't execute .py files directly, so we assume a "manually installed" python,
157 // which comes with a "py" launcher and respects the shebang line to specify the version.
158 def publishGleanCmd = [];
159 if (System.properties['os.name'].toLowerCase().contains('windows')) {
160 publishGleanCmd << "py";
162 publishGleanCmd << "./build-scripts/publish_to_maven_local_if_modified.py";
163 runCmd(publishGleanCmd, gleanLocalPath, "Published Glean for local development.")
165 logger.lifecycle("Disabled auto-publication of Glean. Enable it by settings '$settingGleanPath' in local.properties")