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 275343 62a5abc3188ecbb495fd68c572c0d6d28aa9732f
parent 275342 adad384b0f299d9357364f4531c5bc86fcc83b51
child 275344 14009d28adc198a062de9eb9169a8e3d5a8e0468
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps, sylvestre
bugs1182579
milestone40.0
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()