From 3a17ce396ebc701eaa73baa0fb793ec7e39306b6 Mon Sep 17 00:00:00 2001
From: Lina Butler <lina@yakshaving.ninja>
Date: Fri, 10 May 2024 06:21:28 +0000
Subject: [PATCH] Bug 1895781 - Move the App Services and Glean auto-publish
 logic to its own settings file. r=nalexander

This commit factors out the logic into its own settings file, adds
docs, and only imports the settings file into applications that
consume App Services and Glean via Maven (i.e., not GeckoView).

Differential Revision: https://phabricator.services.mozilla.com/D209897
---
 .../android-components/settings.gradle        |   1 +
 mobile/android/autopublish-settings.gradle    | 114 ++++++++++++++++++
 mobile/android/fenix/settings.gradle          |   1 +
 mobile/android/focus-android/settings.gradle  |   1 +
 mobile/android/shared-settings.gradle         |  94 ---------------
 settings.gradle                               |   1 +
 6 files changed, 118 insertions(+), 94 deletions(-)
 create mode 100644 mobile/android/autopublish-settings.gradle

diff --git a/mobile/android/android-components/settings.gradle b/mobile/android/android-components/settings.gradle
index 6ffd2882cfe84..75297593e1035 100644
--- a/mobile/android/android-components/settings.gradle
+++ b/mobile/android/android-components/settings.gradle
@@ -27,6 +27,7 @@ plugins {
 ext.topsrcdir = rootProject.projectDir.absolutePath.minus("mobile/android/android-components")
 
 apply from: file('../shared-settings.gradle')
+apply from: file('../autopublish-settings.gradle')
 
 buildCache {
     local {
diff --git a/mobile/android/autopublish-settings.gradle b/mobile/android/autopublish-settings.gradle
new file mode 100644
index 0000000000000..8d233abb12f7c
--- /dev/null
+++ b/mobile/android/autopublish-settings.gradle
@@ -0,0 +1,114 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This settings file configures an Android project for substituting a
+// local Application Services and/or Glean.
+//
+// For convenience, this file reads the `autoPublish.*` properties from
+// `$topsrcdir/local.properties`, so that you only need to set them once
+// for all Android projects.
+//
+// You can also set or override these properties on a per-project basis,
+// by setting them in `$topsrcdir/mobile/android/{project}/local.properties`,
+// if you want to only substitute App Services or Glean for a specific project,
+// or to substitute different versions for different projects.
+//
+// This settings file configures the build to automatically publish the
+// contents of your Application Services and Glean checkouts to the
+// Maven local repository. Any dependencies are then substituted to use
+// the locally published versions.
+
+def rootLocalProperties = new File(gradle.mozconfig.topsrcdir, "local.properties").with { localPropertiesFile ->
+    def localProperties = new Properties()
+    if (localPropertiesFile.canRead()) {
+        localPropertiesFile.withInputStream { localProperties.load(it) }
+    }
+    localProperties
+}
+
+[
+    "autoPublish.application-services.dir",
+    "autoPublish.glean.dir",
+].each { key ->
+    def relativeOrAbsolutePath = rootLocalProperties."$key"
+    if (relativeOrAbsolutePath != null) {
+        def autoPublishDir = new File(gradle.mozconfig.topsrcdir).toPath().resolve(relativeOrAbsolutePath)
+        gradle.ext."localProperties.$key" = autoPublishDir.toString()
+    }
+}
+
+gradle.settingsEvaluated {
+    if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) {
+        // The project that we're configuring now might have overridden
+        // the path from `$topsrcdir/local.properties`, so we need to
+        // resolve it again.
+        def appServicesLocalPath = gradle."localProperties.autoPublish.application-services.dir".with { relativeOrAbsolutePath ->
+            def absolutePath = rootDir.toPath().resolve(relativeOrAbsolutePath).toString()
+            gradle."localProperties.autoPublish.application-services.dir" = absolutePath
+            absolutePath
+        }
+
+        logger.lifecycle("settings.gradle> Enabling automatic publication of application-services from: $appServicesLocalPath")
+        // Windows can't execute .py files directly, so we assume a "manually installed" python,
+        // which comes with a "py" launcher and respects the shebang line to specify the version.
+        def publishAppServicesCmd = [];
+        if (System.properties["os.name"].toLowerCase().contains("windows")) {
+            publishAppServicesCmd << "py";
+        }
+        publishAppServicesCmd << "./automation/publish_to_maven_local_if_modified.py";
+        runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.", false)
+    } else {
+        logger.lifecycle("settings.gradle> Disabled auto-publication of application-services. Enable it by settings 'autoPublish.application-services.dir' in local.properties")
+    }
+
+    if (gradle.hasProperty("localProperties.autoPublish.glean.dir")) {
+        // As above, absolutize the path.
+        def gleanLocalPath = gradle."localProperties.autoPublish.glean.dir".with { relativeOrAbsolutePath ->
+            def absolutePath = rootDir.toPath().resolve(relativeOrAbsolutePath).toString()
+            gradle."localProperties.autoPublish.glean.dir" = absolutePath
+            absolutePath
+        }
+
+        logger.lifecycle("settings.gradle> Enabling automatic publication of Glean from: $gleanLocalPath")
+        // As above, hacks to execute .py files on Windows.
+        def publishGleanCmd = [];
+        if (System.properties["os.name"].toLowerCase().contains("windows")) {
+            publishGleanCmd << "py";
+        }
+        publishGleanCmd << "./build-scripts/publish_to_maven_local_if_modified.py";
+        runCmd(publishGleanCmd, gleanLocalPath, "Published Glean for local development.", false)
+    } else {
+        logger.lifecycle("settings.gradle> Disabled auto-publication of Glean. Enable it by settings 'autoPublish.glean.dir' in local.properties")
+    }
+}
+
+gradle.projectsLoaded { ->
+    gradle.rootProject.allprojects {
+        // Allow local appservices substitution in each project.
+        if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) {
+            def appServicesSrcDir = gradle."localProperties.autoPublish.application-services.dir"
+            apply from: "${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle"
+        }
+
+        // Allow local Glean substitution in each project.
+        if (gradle.hasProperty('localProperties.autoPublish.glean.dir')) {
+            def gleanSrcDir = gradle."localProperties.autoPublish.glean.dir"
+            apply from: "${gleanSrcDir}/build-scripts/substitute-local-glean.gradle"
+        }
+    }
+}
+
+def runCmd(cmd, workingDir, successMessage, captureStdout = true) {
+    def proc = cmd.execute(null, new File(workingDir))
+    def standardOutput = captureStdout ? new ByteArrayOutputStream() : System.out
+    proc.consumeProcessOutput(standardOutput, System.err)
+    proc.waitFor()
+
+    if (proc.exitValue() != 0) {
+        throw new GradleException("Process '${cmd}' finished with non-zero exit value ${proc.exitValue()}");
+    } else {
+        logger.lifecycle("settings.gradle> ${successMessage}")
+    }
+    return captureStdout ? standardOutput : null
+}
diff --git a/mobile/android/fenix/settings.gradle b/mobile/android/fenix/settings.gradle
index d18044b859e06..5a8eb1841cb90 100644
--- a/mobile/android/fenix/settings.gradle
+++ b/mobile/android/fenix/settings.gradle
@@ -33,6 +33,7 @@ plugins {
 ext.topsrcdir = rootProject.projectDir.absolutePath.minus("mobile/android/fenix")
 
 apply from: file('../shared-settings.gradle')
+apply from: file('../autopublish-settings.gradle')
 
 include ':app'
 include ':mozilla-detekt-rules'
diff --git a/mobile/android/focus-android/settings.gradle b/mobile/android/focus-android/settings.gradle
index 52b5321228575..9db906b61f865 100644
--- a/mobile/android/focus-android/settings.gradle
+++ b/mobile/android/focus-android/settings.gradle
@@ -31,6 +31,7 @@ plugins {
 ext.topsrcdir = rootProject.projectDir.absolutePath.minus("mobile/android/focus-android")
 
 apply from: file('../shared-settings.gradle')
+apply from: file('../autopublish-settings.gradle')
 
 include ':app'
 
diff --git a/mobile/android/shared-settings.gradle b/mobile/android/shared-settings.gradle
index 15b9cda955f8b..ffdfa28a36cd0 100644
--- a/mobile/android/shared-settings.gradle
+++ b/mobile/android/shared-settings.gradle
@@ -168,99 +168,5 @@ gradle.projectsLoaded { ->
                 expand(values)
             }
         }
-
-        // Allow local appservices substitution in each project.
-        if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) {
-            def appServicesSrcDir = gradle."localProperties.autoPublish.application-services.dir"
-            apply from: "${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle"
-        }
-
-        // Allow local Glean substitution in each project.
-        if (gradle.hasProperty('localProperties.autoPublish.glean.dir')) {
-            def gleanSrcDir = gradle."localProperties.autoPublish.glean.dir"
-            apply from: "${gleanSrcDir}/build-scripts/substitute-local-glean.gradle"
-        }
-    }
-}
-
-def runCmd(cmd, workingDir, successMessage, captureStdout = true) {
-    def proc = cmd.execute(null, new File(workingDir))
-    def standardOutput = captureStdout ? new ByteArrayOutputStream() : System.out
-    proc.consumeProcessOutput(standardOutput, System.err)
-    proc.waitFor()
-
-    if (proc.exitValue() != 0) {
-        throw new GradleException("Process '${cmd}' finished with non-zero exit value ${proc.exitValue()}");
-    } else {
-        logger.lifecycle("settings.gradle> ${successMessage}")
-    }
-    return captureStdout ? standardOutput : null
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Local Development overrides
-//////////////////////////////////////////////////////////////////////////
-
-def rootLocalProperties = new File(gradle.mozconfig.topsrcdir, "local.properties").with { localPropertiesFile ->
-    def localProperties = new Properties()
-    if (localPropertiesFile.canRead()) {
-        localPropertiesFile.withInputStream { localProperties.load(it) }
-    }
-    localProperties
-}
-
-[
-    "autoPublish.application-services.dir",
-    "autoPublish.glean.dir",
-].each { key ->
-    def relativeOrAbsolutePath = rootLocalProperties."$key"
-    if (relativeOrAbsolutePath != null) {
-        def autoPublishDir = new File(gradle.mozconfig.topsrcdir).toPath().resolve(relativeOrAbsolutePath)
-        gradle.ext."localProperties.$key" = autoPublishDir.toString()
-    }
-}
-
-gradle.settingsEvaluated {
-    if (gradle.hasProperty("localProperties.autoPublish.application-services.dir")) {
-        // The project that we're configuring now might have overridden
-        // the path from `$topsrcdir/local.properties`, so we need to
-        // resolve it again.
-        def appServicesLocalPath = gradle."localProperties.autoPublish.application-services.dir".with { relativeOrAbsolutePath ->
-            def absolutePath = rootDir.toPath().resolve(relativeOrAbsolutePath).toString()
-            gradle."localProperties.autoPublish.application-services.dir" = absolutePath
-            absolutePath
-        }
-
-        logger.lifecycle("settings.gradle> Enabling automatic publication of application-services from: $appServicesLocalPath")
-        // Windows can't execute .py files directly, so we assume a "manually installed" python,
-        // which comes with a "py" launcher and respects the shebang line to specify the version.
-        def publishAppServicesCmd = [];
-        if (System.properties["os.name"].toLowerCase().contains("windows")) {
-            publishAppServicesCmd << "py";
-        }
-        publishAppServicesCmd << "./automation/publish_to_maven_local_if_modified.py";
-        runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.", false)
-    } else {
-        logger.lifecycle("settings.gradle> Disabled auto-publication of application-services. Enable it by settings 'autoPublish.application-services.dir' in local.properties")
-    }
-
-    if (gradle.hasProperty("localProperties.autoPublish.glean.dir")) {
-        // As above, absolutize the path.
-        def gleanLocalPath = gradle."localProperties.autoPublish.glean.dir".with { relativeOrAbsolutePath ->
-            def absolutePath = rootDir.toPath().resolve(relativeOrAbsolutePath).toString()
-            gradle."localProperties.autoPublish.glean.dir" = absolutePath
-            absolutePath
-        }
-
-        logger.lifecycle("settings.gradle> Enabling automatic publication of Glean from: $gleanLocalPath")
-        // As above, hacks to execute .py files on Windows.
-        def publishGleanCmd = [];
-        if (System.properties["os.name"].toLowerCase().contains("windows")) {
-            publishGleanCmd << "py";
-        }
-        publishGleanCmd << "./build-scripts/publish_to_maven_local_if_modified.py";
-        runCmd(publishGleanCmd, gleanLocalPath, "Published Glean for local development.", false)
-    } else {
-        logger.lifecycle("settings.gradle> Disabled auto-publication of Glean. Enable it by settings 'autoPublish.glean.dir' in local.properties")
     }
 }
diff --git a/settings.gradle b/settings.gradle
index 3d474f902610f..4abb2462fca76 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -33,6 +33,7 @@ plugins {
 ext.topsrcdir = rootProject.projectDir.absolutePath
 
 apply from: "${topsrcdir}/mobile/android/shared-settings.gradle"
+apply from: "${topsrcdir}/mobile/android/autopublish-settings.gradle"
 
 // Set the Android SDK location.  This is the *least specific* mechanism, which
 // is unfortunate: we'd prefer to use the *most specific* mechanism.  That is,
-- 
GitLab