Bug 1460355 - Fix: Change how the packages are sent to the sdkmanager to install, avoid missing argument. r=nalexander
authorAniket Kadam <anikadamg@gmail.com>
Tue, 24 Jul 2018 20:06:21 +0530
changeset 823443 427b229b7ea4f17343d5723f10ba749b9c15cfb6
parent 823442 96087548d901717805a9197bcf8cc7b0d6783fb7
child 823444 ca5ab353b5d8e35cb757098ff4bcce04269f2101
child 824439 3ee144386beaeb5845180c8ba60729df787b1301
push id117683
push userdgottwald@mozilla.com
push dateFri, 27 Jul 2018 11:18:41 +0000
Bug 1460355 - Fix: Change how the packages are sent to the sdkmanager to install, avoid missing argument. r=nalexander The argument --package_file was removed in the latest sdkmanager by Google's Android. But the docs for it say packages can also be sent by putting them in quotes and calling the sdk manager with them as individual args. So now instead of sending the file directly with the --package_file argument, the package names are read from the file and the sdk manager is called with them as individual args. Historically this has been thought of as a bug that happens with the wrong version of the JDK, but this can be reproduced with just java 1.8.0_181 and the most up to date version of sdkmanager currently 26.1.1 Important note, the mach bootstrap command downloads an older version of the sdk and this bug is not present in the older version. Since the way of updating packages I'm proposiing to use is backwards compatible, there shouldn't be any problem in any version of the sdkamanger. This is a simpler fix than trying the --package_file argument, particularly because it would involve capturing output (to detect this particular bug) that's also supposed to be shown to the user because this also happens when the user is supposed to be interacting with the install. MozReview-Commit-ID: L7VhCVKJNIf *** Formatting changes to satisfy the linter.
--- a/python/mozboot/mozboot/android.py
+++ b/python/mozboot/mozboot/android.py
@@ -222,32 +222,54 @@ def ensure_android_sdk_and_ndk(mozbuild_
     elif os.path.isdir(sdk_path):
         raise NotImplementedError(ANDROID_SDK_TOO_OLD % sdk_path)
         # The SDK archive used to include a top-level
         # android-sdk-$OS_NAME directory; it no longer does so.  We
         # preserve the old convention to smooth detecting existing SDK
         # installations.
         install_mobile_android_sdk_or_ndk(sdk_url, os.path.join(mozbuild_path,
-                                          'android-sdk-{0}'.format(os_name)))
+                                                                'android-sdk-{0}'.format(os_name)))
+def get_packages_to_install(packages_file_name):
+    """
+    sdkmanager version 26.1.1 (current) and some versions below have a bug that makes
+    the following command fail:
+        args = [sdkmanager_tool, '--package_file={0}'.format(package_file_name)]
+        subprocess.check_call(args)
+    The error is in the sdkmanager, where the --package_file param isn't recognized.
+        The error is being tracked here https://issuetracker.google.com/issues/66465833
+    Meanwhile, this workaround achives installing all required Android packages by reading
+    them out of the same file that --package_file would have used, and passing them as strings.
+    So from here: https://developer.android.com/studio/command-line/sdkmanager
+    Instead of:
+        sdkmanager --package_file=package_file [options]
+    We're doing:
+        sdkmanager "platform-tools" "platforms;android-26"
+    """
+    with open(packages_file_name) as package_file:
+        return map(lambda package: package.strip(), package_file.readlines())
 def ensure_android_packages(sdkmanager_tool, packages=None, no_interactive=False):
     Use the given sdkmanager tool (like 'sdkmanager') to install required
     Android packages.
     # This tries to install all the required Android packages.  The user
     # may be prompted to agree to the Android license.
     package_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                        'android-packages.txt'))
+                                                     'android-packages.txt'))
     print(INSTALLING_ANDROID_PACKAGES % open(package_file_name, 'rt').read())
-    args = [sdkmanager_tool, '--package_file={0}'.format(package_file_name)]
+    args = [sdkmanager_tool]
+    args.extend(get_packages_to_install(package_file_name))
     if not no_interactive:
     # Emulate yes.  For a discussion of passing input to check_output,
     # see https://stackoverflow.com/q/10103551.
     yes = '\n'.join(['y']*100)
     proc = subprocess.Popen(args,