tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }