Bug 1119365 - Implement |mach ide| for mobile/android and IntelliJ/Android Studio. r=nalexander
authorAhmed Khalil <ahmedibrahimkhali>
Fri, 27 Feb 2015 05:46:00 -0800
changeset 231469 352ebcbf802e1f80fb9d92ab84ed77619f94f2b7
parent 231468 f19c915183c2cc5a1485a0f10c9a950a87cf6d48
child 231470 68472846761f51a2292340a1d0afea9c72b13c86
push id28352
push usercbook@mozilla.com
push dateTue, 03 Mar 2015 12:51:09 +0000
treeherdermozilla-central@e545f650c695 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1119365
milestone39.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 1119365 - Implement |mach ide| for mobile/android and IntelliJ/Android Studio. r=nalexander
python/mozbuild/mozbuild/backend/mach_commands.py
--- a/python/mozbuild/mozbuild/backend/mach_commands.py
+++ b/python/mozbuild/mozbuild/backend/mach_commands.py
@@ -24,52 +24,116 @@ from mach.decorators import (
     CommandProvider,
     Command,
 )
 
 @CommandProvider
 class MachCommands(MachCommandBase):
     @Command('ide', category='devenv',
         description='Generate a project and launch an IDE.')
-    @CommandArgument('ide', choices=['eclipse', 'visualstudio'])
+    @CommandArgument('ide', choices=['eclipse', 'visualstudio', 'androidstudio', 'intellij'])
     @CommandArgument('args', nargs=argparse.REMAINDER)
     def eclipse(self, ide, args):
         if ide == 'eclipse':
             backend = 'CppEclipse'
         elif ide == 'visualstudio':
             backend = 'VisualStudio'
+        elif ide == 'androidstudio' or ide == 'intellij':
+            # The build backend for Android Studio and IntelliJ is just the regular one.
+            backend = 'RecursiveMake'
 
-        if backend == 'CppEclipse':
+        if ide == 'eclipse':
             try:
                 which.which('eclipse')
             except which.WhichError:
                 print('Eclipse CDT 8.4 or later must be installed in your PATH.')
                 print('Download: http://www.eclipse.org/cdt/downloads.php')
                 return 1
+        elif ide == 'androidstudio' or ide =='intellij':
+            studio = ['studio'] if ide == 'androidstudio' else ['idea']
+            if sys.platform != 'darwin':
+                try:
+                    which.which(studio[0])
+                except:
+                    self.print_ide_error(ide)
+                    return 1
+            else:
+                # In order of preference!
+                for d in self.get_mac_ide_preferences(ide):
+                    if os.path.isdir(d):
+                        studio = ['open', '-a', d]
+                        break
+                else:
+                    print('Android Studio or IntelliJ IDEA 14 is not installed in /Applications.')
+                    return 1
 
         # Here we refresh the whole build. 'build export' is sufficient here and is probably more
         # correct but it's also nice having a single target to get a fully built and indexed
         # project (gives a easy target to use before go out to lunch).
         res = self._mach_context.commands.dispatch('build', self._mach_context)
         if res != 0:
             return 1
 
-        # Generate or refresh the eclipse workspace
-        python = self.virtualenv_manager.python_path
-        config_status = os.path.join(self.topobjdir, 'config.status')
-        args = [python, config_status, '--backend=%s' % backend]
-        res = self._run_command_in_objdir(args=args, pass_thru=True, ensure_exit_code=False)
-        if res != 0:
-            return 1
+        if ide == 'androidstudio' or 'intellij':
+            res = self._mach_context.commands.dispatch('package', self._mach_context)
+            if res != 0:
+                return 1
+            res = self._mach_context.commands.dispatch('gradle-install', self._mach_context)
+            if res != 0:
+                 return 1
+        else:
+            # Generate or refresh the IDE backend.
+            python = self.virtualenv_manager.python_path
+            config_status = os.path.join(self.topobjdir, 'config.status')
+            args = [python, config_status, '--backend=%s' % backend]
+            res = self._run_command_in_objdir(args=args, pass_thru=True, ensure_exit_code=False)
+            if res != 0:
+                return 1
 
-        if backend == 'CppEclipse':
+
+        if ide == 'eclipse':
             eclipse_workspace_dir = self.get_eclipse_workspace_path()
             process = subprocess.check_call(['eclipse', '-data', eclipse_workspace_dir])
-        elif backend == 'VisualStudio':
+        elif ide == 'visualstudio':
             visual_studio_workspace_dir = self.get_visualstudio_workspace_path()
             process = subprocess.check_call(['explorer.exe', visual_studio_workspace_dir])
+        elif ide == 'androidstudio' or ide == 'intellij':
+            gradle_dir = None
+            if self.is_gradle_project_already_imported():
+                gradle_dir = self.get_gradle_project_path()
+            else:
+                gradle_dir = self.get_gradle_import_path()
+            process = subprocess.check_call(studio + [gradle_dir])
 
     def get_eclipse_workspace_path(self):
         return CppEclipseBackend.get_workspace_path(self.topsrcdir, self.topobjdir)
 
     def get_visualstudio_workspace_path(self):
         return os.path.join(self.topobjdir, 'msvc', 'mozilla.sln')
 
+    def get_gradle_project_path(self):
+        return os.path.join(self.topobjdir, 'mobile', 'android', 'gradle')
+
+    def get_gradle_import_path(self):
+        return os.path.join(self.get_gradle_project_path(), 'build.gradle')
+
+    def is_gradle_project_already_imported(self):
+        gradle_project_path = os.path.join(self.get_gradle_project_path(), '.idea')
+        return os.path.exists(gradle_project_path)
+
+    def get_mac_ide_preferences(self, ide):
+        if sys.platform == 'darwin':
+            if ide == 'androidstudio':
+                return ['/Applications/Android Studio.app']
+            else:
+                return [
+                    '/Applications/IntelliJ IDEA 14 EAP.app',
+                    '/Applications/IntelliJ IDEA 14.app',
+                    '/Applications/IntelliJ IDEA 14 CE EAP.app',
+                    '/Applications/IntelliJ IDEA 14 CE.app']
+
+    def print_ide_error(self, ide):
+        if ide == 'androidstudio':
+            print('Android Studio is not installed in your PATH.')
+            print('You can generate a command-line launcher from Android Studio->Tools->Create Command-line launcher with script name \'studio\'')
+        elif ide == 'intellij':
+            print('IntelliJ is not installed in your PATH.')
+            print('You can generate a command-line launcher from IntelliJ IDEA->Tools->Create Command-line launcher with script name \'idea\'')