servo: Merge #10616 - #10614: Mach install now builds servo if it hasn't been built before (from autrilla:10614); r=edunham
authorAdrian Utrilla <adrianutrilla@gmail.com>
Sat, 16 Apr 2016 00:12:34 +0500
changeset 338537 4b66f7bd4d879ee6f18c6ced190244b46cbebb21
parent 338536 f150cc5804a8005a08d2856077522a54b53a9ce7
child 338538 2857d710dfbac7cfba89f6a015dfd31f9dbd57ed
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedunham
servo: Merge #10616 - #10614: Mach install now builds servo if it hasn't been built before (from autrilla:10614); r=edunham Source-Repo: https://github.com/servo/servo Source-Revision: 7c615233d88967f79efbf78618eda3f3a8479e88
servo/python/servo/command_base.py
servo/python/servo/post_build_commands.py
--- a/servo/python/servo/command_base.py
+++ b/servo/python/servo/command_base.py
@@ -98,16 +98,24 @@ def check_call(*args, **kwargs):
 
     if verbose:
         print(' '.join(args[0]))
     # we have to use shell=True in order to get PATH handling
     # when looking for the binary on Windows
     return subprocess.check_call(*args, shell=sys.platform == 'win32', **kwargs)
 
 
+class BuildNotFound(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
+
 class CommandBase(object):
     """Base class for mach command providers.
 
     This mostly handles configuration management, such as .servobuild."""
 
     def __init__(self, context):
         self.context = context
 
@@ -198,16 +206,18 @@ class CommandBase(object):
 
     def get_target_dir(self):
         if "CARGO_TARGET_DIR" in os.environ:
             return os.environ["CARGO_TARGET_DIR"]
         else:
             return path.join(self.context.topdir, "target")
 
     def get_binary_path(self, release, dev, android=False):
+        # TODO(autrilla): this function could still use work - it shouldn't
+        # handle quitting, or printing. It should return the path, or an error.
         base_path = self.get_target_dir()
 
         if android:
             base_path = path.join(base_path, self.config["android"]["target"])
 
         binary_name = "servo" + BIN_SUFFIX
         release_path = path.join(base_path, "release", binary_name)
         dev_path = path.join(base_path, "debug", binary_name)
@@ -215,18 +225,18 @@ class CommandBase(object):
         # Prefer release if both given
         if release and dev:
             dev = False
 
         release_exists = path.exists(release_path)
         dev_exists = path.exists(dev_path)
 
         if not release_exists and not dev_exists:
-            print("No Servo binary found. Please run './mach build' and try again.")
-            sys.exit()
+            raise BuildNotFound('No Servo binary found.'
+                                ' Perhaps you forgot to run `./mach build`?')
 
         if release and release_exists:
             return release_path
 
         if dev and dev_exists:
             return dev_path
 
         if not dev and not release and release_exists and dev_exists:
--- a/servo/python/servo/post_build_commands.py
+++ b/servo/python/servo/post_build_commands.py
@@ -18,17 +18,17 @@ from shutil import copytree, rmtree, cop
 from mach.registrar import Registrar
 
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
     Command,
 )
 
-from servo.command_base import CommandBase, cd, call, check_call
+from servo.command_base import CommandBase, cd, call, check_call, BuildNotFound
 
 
 def read_file(filename, if_exists=False):
     if if_exists and not path.exists(filename):
         return None
     with open(filename) as f:
         return f.read()
 
@@ -258,21 +258,30 @@ class PostBuildCommands(CommandBase):
     @Command('install',
              description='Install Servo (currently, Android only)',
              category='post-build')
     @CommandArgument('--release', '-r', action='store_true',
                      help='Package the release build')
     @CommandArgument('--dev', '-d', action='store_true',
                      help='Package the dev build')
     def install(self, release=False, dev=False):
-        binary_path = self.get_binary_path(release, dev, android=True)
-        if not path.exists(binary_path):
-            # TODO: Run the build command automatically?
-            print("Servo build not found. Please run `./mach build` to compile Servo.")
-            return 1
+        try:
+            binary_path = self.get_binary_path(release, dev, android=True)
+        except BuildNotFound:
+            print("Servo build not found. Building servo...")
+            result = Registrar.dispatch(
+                "build", context=self.context, release=release, dev=dev
+            )
+            if result:
+                return result
+            try:
+                binary_path = self.get_binary_path(release, dev, android=True)
+            except BuildNotFound:
+                print("Rebuilding Servo did not solve the missing build problem.")
+                return 1
 
         apk_path = binary_path + ".apk"
         if not path.exists(apk_path):
             result = Registrar.dispatch("package", context=self.context, release=release, dev=dev)
             if result is not 0:
                 return result
 
         print(["adb", "install", "-r", apk_path])