autopublish-settings.gradle (7739B)
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/. */ 4 5 // This settings file configures an Android project for substituting a 6 // local Application Services and/or Glean. 7 // 8 // For convenience, this file reads the `autoPublish.*` properties from 9 // `$topsrcdir/local.properties`, so that you only need to set them once 10 // for all Android projects. 11 // 12 // You can also set or override these properties on a per-project basis, 13 // by setting them in `$topsrcdir/mobile/android/{project}/local.properties`, 14 // if you want to only substitute App Services or Glean for a specific project, 15 // or to substitute different versions for different projects. 16 // 17 // This settings file configures the build to automatically publish the 18 // contents of your Application Services and Glean checkouts to the 19 // Maven local repository. Any dependencies are then substituted to use 20 // the locally published versions. 21 22 def rootLocalProperties = new File(gradle.mozconfig.topsrcdir, "local.properties").with { localPropertiesFile -> 23 def localProperties = new Properties() 24 if (localPropertiesFile.canRead()) { 25 localPropertiesFile.withInputStream { localProperties.load(it) } 26 } 27 localProperties 28 } 29 30 [ 31 "autoPublish.application-services.dir", 32 "autoPublish.glean.dir", 33 "uniffiBindgenNoop.executable", 34 ].each { key -> 35 def relativeOrAbsolutePath = rootLocalProperties."$key" 36 if (relativeOrAbsolutePath != null) { 37 def autoPublishDir = new File(gradle.mozconfig.topsrcdir).toPath().resolve(relativeOrAbsolutePath) 38 gradle.ext."localProperties.$key" = autoPublishDir.toString() 39 } 40 } 41 42 gradle.settingsEvaluated { 43 if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) { 44 if (!gradle.hasProperty("localProperties.uniffiBindgenNoop.executable")) { 45 throw new GradleException("Set uniffiBindgenNoop.executable to your local.properties in order to auto publish application-services.") 46 } 47 48 def appServicesLocalPath = gradle."localProperties.autoPublish.application-services.dir" 49 logger.lifecycle("settings.gradle> Enabling automatic publication of application-services from: $appServicesLocalPath") 50 // Windows can't execute .py files directly, so we assume a "manually installed" python, 51 // which comes with a "py" launcher and respects the shebang line to specify the version. 52 def publishAppServicesCmd = []; 53 if (System.properties["os.name"].toLowerCase().contains("windows")) { 54 publishAppServicesCmd << "py"; 55 } 56 publishAppServicesCmd << "./automation/publish_to_maven_local_if_modified.py" << gradle."localProperties.uniffiBindgenNoop.executable"; 57 runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.", false) 58 } else { 59 logger.lifecycle("settings.gradle> Disabled auto-publication of application-services. Enable it by settings 'autoPublish.application-services.dir' in local.properties") 60 } 61 62 if (gradle.hasProperty("localProperties.autoPublish.glean.dir")) { 63 if (!gradle.hasProperty("localProperties.uniffiBindgenNoop.executable")) { 64 throw new GradleException("Set uniffiBindgenNoop.executable to your local.properties in order to auto publish glean.") 65 } 66 67 def gleanLocalPath = gradle."localProperties.autoPublish.glean.dir" 68 logger.lifecycle("settings.gradle> Enabling automatic publication of Glean from: $gleanLocalPath") 69 // As above, hacks to execute .py files on Windows. 70 def publishGleanCmd = []; 71 if (System.properties["os.name"].toLowerCase().contains("windows")) { 72 publishGleanCmd << "py"; 73 } 74 75 // We do not have a fork of Glean. In order for this to work, on your local 76 // copy of the Glean repo, modify this python script to accept and use the uniffi-bindgen path. 77 publishGleanCmd << "./build-scripts/publish_to_maven_local_if_modified.py" << gradle."localProperties.uniffiBindgenNoop.executable"; 78 runCmd(publishGleanCmd, gleanLocalPath, "Published Glean for local development.", false) 79 } else { 80 logger.lifecycle("settings.gradle> Disabled auto-publication of Glean. Enable it by settings 'autoPublish.glean.dir' in local.properties") 81 } 82 } 83 84 gradle.projectsLoaded { -> 85 gradle.rootProject.allprojects { 86 if (gradle.ext.mozconfig.substs.MOZ_APPSERVICES_IN_TREE) { 87 // in tree, so we update our legacy "external" dep name to a local project. 88 // ie, `"${ApplicationServicesConfig.groupId}:syncmanager:${ApplicationServicesConfig.version}"` 89 // becomes `project(':syncmanager')` 90 configurations.all { config -> 91 if (config.isCanBeResolved()) { 92 config.resolutionStrategy { strategy -> 93 dependencySubstitution { 94 all { dependency -> 95 // We only care about substituting for a module, not a project. 96 if (!(dependency.requested instanceof ModuleComponentSelector)) { 97 return 98 } 99 def group = dependency.requested.group 100 if (group == 'org.mozilla.appservices' || group == 'org.mozilla.appservices.nightly') { 101 def name = dependency.requested.module 102 // What to do about full-megazord-libsForTests is tbd - it's a convenience; 103 // but we don't lose test coverage, just local test convience. 104 if (name == "full-megazord-libsForTests") { 105 name = "full-megazord" 106 } 107 dependency.useTarget(project(":${name}")) 108 } 109 } 110 } 111 } 112 } 113 } 114 } else { 115 // Allow local appservices substitution in each project. 116 if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) { 117 def appServicesSrcDir = gradle."localProperties.autoPublish.application-services.dir" 118 apply from: rootProject.file("${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle") 119 } 120 } 121 122 // Allow local Glean substitution in each project. 123 if (gradle.hasProperty('localProperties.autoPublish.glean.dir')) { 124 def gleanSrcDir = gradle."localProperties.autoPublish.glean.dir" 125 apply from: rootProject.file("${gleanSrcDir}/build-scripts/substitute-local-glean.gradle") 126 } 127 } 128 } 129 130 def runCmd(cmd, workingDirectory, successMessage, captureStdout = true) { 131 def proc = providers.exec { 132 commandLine(cmd) 133 ignoreExitValue = true 134 workingDir = workingDirectory 135 } 136 137 def result = proc.result.get().exitValue 138 139 if (result != 0) { 140 def message = "Process '${cmd}' finished with non-zero exit value ${result}" 141 println(message) 142 proc.standardOutput.asText.get().readLines().each { println("> ${it}") } 143 proc.standardError.asText.get().readLines().each { println("> ${it}") } 144 throw new GradleException(message) 145 } else { 146 logger.lifecycle("settings.gradle> ${successMessage}") 147 } 148 return captureStdout ? proc.standardOutput.asText.get() : null 149 }