Bug 1407872 - Use Python yes-like pipe for --no-interactive in |mach bootstrap|. r=gbrown
authorNick Alexander <nalexander@mozilla.com>
Fri, 13 Oct 2017 11:48:52 -0700
changeset 386195 35866a88d5673db6c760658f3e3cd159cc50f36b
parent 386194 68ccc9cb5de00d3e357b3736142d106e6bce11b3
child 386196 366262985fa8b12e1a3a7c6131d7697fcfc1a624
push id32678
push userarchaeopteryx@coole-files.de
push dateSat, 14 Oct 2017 09:40:07 +0000
treeherdermozilla-central@0dd64d5842e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgbrown
bugs1407872
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1407872 - Use Python yes-like pipe for --no-interactive in |mach bootstrap|. r=gbrown The old system was simply in place because I couldn't figure out how to pipe `yes | ...` in Python. This is good enough to replace it, and much less fragile since the license hashes change frequently. MozReview-Commit-ID: AhJJPqMKfUh
python/mozboot/mozboot/android.py
--- a/python/mozboot/mozboot/android.py
+++ b/python/mozboot/mozboot/android.py
@@ -169,35 +169,20 @@ def ensure_android(os_name, artifact_mod
     sdk_url = 'https://dl.google.com/android/repository/sdk-tools-{0}-3859397.zip'.format(os_tag)
     ndk_url = android_ndk_url(os_name)
 
     ensure_android_sdk_and_ndk(mozbuild_path, os_name,
                                sdk_path=sdk_path, sdk_url=sdk_url,
                                ndk_path=ndk_path, ndk_url=ndk_url,
                                artifact_mode=artifact_mode)
 
-    if no_interactive:
-        # Cribbed from observation and https://stackoverflow.com/a/38381577.
-        path = os.path.join(mozbuild_path, 'android-sdk-{0}'.format(os_name), 'licenses')
-        ensure_dir(path)
-
-        licenses = {
-            'android-sdk-license': '8933bad161af4178b1185d1a37fbf41ea5269c55',
-            'android-sdk-preview-license': '84831b9409646a918e30573bab4c9c91346d8abd',
-        }
-        for license, tag in licenses.items():
-            lname = os.path.join(path, license)
-            if not os.path.isfile(lname):
-                open(lname, 'w').write('\n{0}\n'.format(tag))
-
-
     # We expect the |sdkmanager| tool to be at
     # ~/.mozbuild/android-sdk-$OS_NAME/tools/bin/sdkmanager.
     sdkmanager_tool = os.path.join(sdk_path, 'tools', 'bin', 'sdkmanager')
-    ensure_android_packages(sdkmanager_tool=sdkmanager_tool)
+    ensure_android_packages(sdkmanager_tool=sdkmanager_tool, no_interactive=no_interactive)
 
 
 def ensure_android_sdk_and_ndk(mozbuild_path, os_name, sdk_path, sdk_url, ndk_path, ndk_url, artifact_mode):
     '''
     Ensure the Android SDK and NDK are found at the given paths.  If not, fetch
     and unpack the SDK and/or NDK from the given URLs into |mozbuild_path/{android-sdk-$OS_NAME,android-ndk-$VER}|.
     '''
 
@@ -223,28 +208,49 @@ def ensure_android_sdk_and_ndk(mozbuild_
     else:
         # 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)))
 
 
-def ensure_android_packages(sdkmanager_tool, packages=None):
+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'))
     print(INSTALLING_ANDROID_PACKAGES % open(package_file_name, 'rt').read())
-    subprocess.check_call([sdkmanager_tool,
-                           '--package_file={0}'.format(package_file_name)])
+
+    args = [sdkmanager_tool, '--package_file={0}'.format(package_file_name)]
+    if not no_interactive:
+        subprocess.check_call(args)
+        return
+
+    # 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,
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.STDOUT,
+                            stdin=subprocess.PIPE)
+    output, unused_err = proc.communicate(yes)
+
+    retcode = proc.poll()
+    if retcode:
+        cmd = args[0]
+        e = subprocess.CalledProcessError(retcode, cmd)
+        e.output = output
+        raise e
+
+    print(output)
 
 
 def suggest_mozconfig(os_name, artifact_mode=False):
     _mozbuild_path, sdk_path, ndk_path = get_paths(os_name)
     if artifact_mode:
         print(MOBILE_ANDROID_ARTIFACT_MODE_MOZCONFIG_TEMPLATE % (sdk_path))
     else:
         print(MOBILE_ANDROID_MOZCONFIG_TEMPLATE % (sdk_path, ndk_path))