Bug 1182579 - Compute Android version codes in Python. r=gps a=sylvestre
authorNick Alexander <nalexander@mozilla.com>
Wed, 08 Jul 2015 12:43:06 -0700
changeset 268835 512c79f324cc7d0ee389fed6bcb69b0b9702ca8a
parent 268834 17d07c58f85cc6fd2e8687f2edbc934b62d19e39
child 268836 d54724498db064efb58e193e27b57140a066175d
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps, sylvestre
bugs1182579
milestone41.0a2
Bug 1182579 - Compute Android version codes in Python. r=gps a=sylvestre I considered three ways to do this: * one, as a Python script executed with $(shell); * two, as a Python script that writes an include file for the preprocessor; * three, as a function exposed to the moz.build sandbox. I rejected two because it's both tied to the preprocessor, and awkward to make handle the dependency on the buildid (in a file) and additional build defines (in config.status). I rejected three because I know of no precedent for this approach, and it hides the dependency on the buildid. One doesn't handle failures in the script gracefully, but neither did the existing approach. This patch is at least testable.
mobile/android/base/Makefile.in
python/mozbuild/mozbuild/android_version_code.py
python/mozbuild/mozbuild/test/test_android_version_code.py
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -1,27 +1,21 @@
 # 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/.
 
 MOZ_APP_BUILDID=$(shell cat $(DEPTH)/config/buildid)
 
-# See Bug 1137586 for more details on version code computation.
-ifeq (,$(ANDROID_VERSION_CODE))
-ifeq ($(CPU_ARCH),arm)
-# Increment by MIN_SDK_VERSION -- this adds 9 to every build ID as a minimum.
-# Our split APK starts at 11.
-ANDROID_VERSION_CODE=$(shell echo $$((`cat $(DEPTH)/config/buildid | cut -c1-10` + $(MOZ_ANDROID_MIN_SDK_VERSION) + 0)))
-else # not ARM, so x86.
-# Increment the version code by 3 for x86 builds so they are offered to x86 phones that have ARM emulators,
-# beating the 2-point advantage that the v11+ ARMv7 APK has.
-# If we change our splits in the future, we'll need to do this further still.
-ANDROID_VERSION_CODE=$(shell echo $$((`cat $(DEPTH)/config/buildid | cut -c1-10` + $(MOZ_ANDROID_MIN_SDK_VERSION) + 3)))
-endif
-endif
+ANDROID_VERSION_CODE:=$(shell $(PYTHON) \
+  $(topsrcdir)/python/mozbuild/mozbuild/android_version_code.py \
+    --verbose \
+    --with-android-cpu-arch=$(ANDROID_CPU_ARCH) \
+    $(if $(MOZ_ANDROID_MIN_SDK_VERSION),--with-android-min-sdk=$(MOZ_ANDROID_MIN_SDK_VERSION)) \
+    $(if $(MOZ_ANDROID_MAX_SDK_VERSION),--with-android-max-sdk=$(MOZ_ANDROID_MAX_SDK_VERSION)) \
+    $(MOZ_APP_BUILDID))
 
 DEFINES += \
   -DANDROID_VERSION_CODE=$(ANDROID_VERSION_CODE) \
   -DMOZ_ANDROID_SHARED_ID="$(MOZ_ANDROID_SHARED_ID)" \
   -DMOZ_ANDROID_SHARED_ACCOUNT_TYPE="$(MOZ_ANDROID_SHARED_ACCOUNT_TYPE)" \
   -DMOZ_ANDROID_SHARED_FXACCOUNT_TYPE="$(MOZ_ANDROID_SHARED_FXACCOUNT_TYPE)" \
   -DMOZ_APP_BUILDID=$(MOZ_APP_BUILDID) \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -0,0 +1,57 @@
+# 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/.
+
+from __future__ import absolute_import, print_function
+
+import argparse
+import sys
+
+
+def android_version_code(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
+    base = int(str(buildid)[:10])
+    # None is interpreted as arm.
+    if not cpu_arch or cpu_arch in ['armeabi', 'armeabi-v7a']:
+        # Increment by MIN_SDK_VERSION -- this adds 9 to every build ID as a
+        # minimum.  Our split APK starts at 11.
+        return base + min_sdk + 0
+    elif cpu_arch in ['x86']:
+        # Increment the version code by 3 for x86 builds so they are offered to
+        # x86 phones that have ARM emulators, beating the 2-point advantage that
+        # the v11+ ARMv7 APK has.  If we change our splits in the future, we'll
+        # need to do this further still.
+        return base + min_sdk + 3
+    else:
+        raise ValueError("Don't know how to compute android:versionCode "
+                         "for CPU arch " + cpu_arch)
+
+
+def main(argv):
+    parser = argparse.ArgumentParser('Generate an android:versionCode',
+                                     add_help=False)
+    parser.add_argument('--verbose', action='store_true',
+                        default=False,
+                        help='Be verbose')
+    parser.add_argument('--with-android-cpu-arch', dest='cpu_arch',
+                        choices=['armeabi', 'armeabi-v7a', 'mips', 'x86'],
+                        help='The target CPU architecture')
+    parser.add_argument('--with-android-min-sdk-version', dest='min_sdk',
+                        type=int, default=0,
+                        help='The minimum target SDK')
+    parser.add_argument('--with-android-max-sdk-version', dest='max_sdk',
+                        type=int, default=0,
+                        help='The maximum target SDK')
+    parser.add_argument('buildid', type=int,
+                        help='The input build ID')
+
+    args = parser.parse_args(argv)
+    code = android_version_code(args.buildid,
+        cpu_arch=args.cpu_arch,
+        min_sdk=args.min_sdk,
+        max_sdk=args.max_sdk)
+    print(code)
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/test_android_version_code.py
@@ -0,0 +1,23 @@
+# 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/.
+
+from mozunit import main
+import unittest
+
+from mozbuild.android_version_code import android_version_code
+
+class TestAndroidVersionCode(unittest.TestCase):
+    def test_basic(self):
+        # From https://treeherder.mozilla.org/#/jobs?repo=mozilla-central&revision=e25de9972a77.
+        buildid = '20150708104620'
+        arm_api9  = 2015070819
+        arm_api11 = 2015070821
+        x86_api9  = 2015070822
+        self.assertEqual(android_version_code(buildid, cpu_arch='armeabi', min_sdk=9, max_sdk=None), arm_api9)
+        self.assertEqual(android_version_code(buildid, cpu_arch='armeabi-v7a', min_sdk=11, max_sdk=None), arm_api11)
+        self.assertEqual(android_version_code(buildid, cpu_arch='x86', min_sdk=9, max_sdk=None), x86_api9)
+
+
+if __name__ == '__main__':
+    main()