Extract the shell runner into devtools.

In this patch, mojo/tools/mojo_shell.py is moved to devtools. Default
output paths corresponding to a regular Mojo checkout are inferred, so
that it continues to work out-of-the-box there.

In the next step we will make it easier (in particular, possible) to use
the runner outside of the regular Mojo checkout too (allow to indicate
some paths by hand, allow to run against already installed device Mojo
Shell, etc.)

R=qsr@chromium.org

Review URL: https://codereview.chromium.org/1242453003 .
diff --git a/README.md b/README.md
index 64dbec8..ac04dea 100644
--- a/README.md
+++ b/README.md
@@ -212,24 +212,24 @@
 
 ## Run Mojo Shell
 
-`mojo_shell.py` is a universal shell runner abstracting away the differences
-between running on Linux and Android. Having built Mojo as described above, a
-demo app can be run as follows:
+Devtools script `mojo_shell` is a universal shell runner abstracting away the
+differences between running on Linux and Android. Having built Mojo as
+described above, a demo app can be run as follows:
 
 ```
-mojo/tools/mojo_shell.py mojo:spinning_cube  # Linux.
-mojo/tools/mojo_shell.py mojo:spinning_cube  --android # Android.
+mojo/devtools/common/mojo_shell mojo:spinning_cube  # Linux.
+mojo/devtools/common/mojo_shell mojo:spinning_cube  --android # Android.
 ```
 
 Pass `--sky path_to_sky_file` to run a
 [Sky](https://github.com/domokit/mojo/tree/master/sky) app on either platform:
 ```
-mojo/tools/mojo_shell.py --sky sky/examples/raw/hello_world.dart
-mojo/tools/mojo_shell.py --sky sky/examples/raw/hello_world.dart --android
+mojo/devtools/common/mojo_shell --sky sky/examples/raw/hello_world.dart
+mojo/devtools/common/mojo_shell --sky sky/examples/raw/hello_world.dart --android
 ```
 
 Passing the `-v` flag will increase the output verbosity. In particular, it will
-also print all arguments passed by `mojo_shell.py` to the shell binary.
+also print all arguments passed by `mojo_shell` to the shell binary.
 
 ### Chromoting
 
@@ -237,7 +237,7 @@
 over [chromoting](https://support.google.com/chrome/answer/1649523?hl=en):
 
 ```
-mojo/tools/mojo_shell.py --sky sky/examples/raw/hello_world.dart --use-osmesa
+mojo/devtools/common/mojo_shell --sky sky/examples/raw/hello_world.dart --use-osmesa
 ```
 
 ### <a name="debugging"></a>Debugging, tracing, profiling
@@ -249,8 +249,8 @@
 and retrieve the result:
 
 ```
-devtools/common/debugger tracing start
-devtools/common/debugger tracing stop [result.json]
+mojo/devtools/common/debugger tracing start
+mojo/devtools/common/debugger tracing stop [result.json]
 ```
 
 The trace file can be then loaded using the trace viewer in Chrome available at
@@ -299,14 +299,6 @@
 running a userdebug build. For Googlers, [follow the instructions at this
 link](http://go/mojo-internal-build-instructions).
 
-#### Aw, snap!
-
-If the shell crashes on the device, you won't see symbols. Use
-`tools/android_stack_parser/stack` to map back to symbols, e.g.:
-```
-adb logcat | ./tools/android_stack_parser/stack
-```
-
 ### Running manually on Linux
 
 If you wish to, you can also run the Linux Mojo shell directly with no wrappers:
diff --git a/examples/dart/camera_roll/camera_roll.dart b/examples/dart/camera_roll/camera_roll.dart
index bd0c0de..cea99f5 100644
--- a/examples/dart/camera_roll/camera_roll.dart
+++ b/examples/dart/camera_roll/camera_roll.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// To run: mojo/tools/mojo_shell.py --sky \
+// To run: mojo/devtools/common/mojo_shell --sky \
 //             examples/dart/camera_roll/camera_roll.dart --android
 // This example makes use of mojo:camera_roll which is available only when
 // running on Android.
diff --git a/examples/dart/speech_input/speech_input.dart b/examples/dart/speech_input/speech_input.dart
index b44f873..6ad3b52 100644
--- a/examples/dart/speech_input/speech_input.dart
+++ b/examples/dart/speech_input/speech_input.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// To run: mojo/tools/mojo_shell.py --sky \
+// To run: mojo/devtools/common/mojo_shell --sky \
 //             examples/dart/speech_input/speech_input.dart --android
 //
 // The speech_recognizer service is only available for Android targets.
diff --git a/examples/go/README.txt b/examples/go/README.txt
index 89a1027..501873e 100644
--- a/examples/go/README.txt
+++ b/examples/go/README.txt
@@ -20,10 +20,10 @@
 
 3) Run
 To run echo client:
-$ mojo/tools/mojo_shell.py --enable-multiprocess mojo:go_echo_client
+$ mojo/devtools/common/mojo_shell --enable-multiprocess mojo:go_echo_client
 
 To run http handler:
-$ mojo/tools/mojo_shell.py --enable-multiprocess mojo:go_http_handler
+$ mojo/devtools/common/mojo_shell --enable-multiprocess mojo:go_http_handler
 
 To run http server:
-$ mojo/tools/mojo_shell.py --enable-multiprocess mojo:go_http_server
+$ mojo/devtools/common/mojo_shell --enable-multiprocess mojo:go_http_server
diff --git a/examples/java_android/echo/src/org/chromium/examples/java_echo/README.md b/examples/java_android/echo/src/org/chromium/examples/java_echo/README.md
index 3d83548..2db9694 100644
--- a/examples/java_android/echo/src/org/chromium/examples/java_echo/README.md
+++ b/examples/java_android/echo/src/org/chromium/examples/java_echo/README.md
@@ -5,16 +5,16 @@
 
 `cd <mojo>/src`
 
-`./mojo/tools/mojo_shell.py --android mojo:java_echo_client --logcat-tags=JavaEchoClient`
+`mojo/devtools/common/mojo_shell --android mojo:java_echo_client --logcat-tags=JavaEchoClient`
 
 **To use the Java Echo Server instead of the native Echo Server:**
 
-`./mojo/tools/mojo_shell.py --android mojo:java_echo_client --logcat-tags=JavaEchoClient,JavaEchoServer --url-mappings=mojo:echo_server=mojo:java_echo_server`
+`mojo/devtools/common/mojo_shell --android mojo:java_echo_client --logcat-tags=JavaEchoClient,JavaEchoServer --url-mappings=mojo:echo_server=mojo:java_echo_server`
 
 
 **To send a message of your choice:**
 
-`./mojo/tools/mojo_shell.py --android mojo:java_echo_client --logcat-tags=JavaEchoClient,JavaEchoServer --url-mappings=mojo:echo_server=mojo:java_echo_server --args-for='mojo:java_echo_client Hello Mojo'`
+`mojo/devtools/common/mojo_shell --android mojo:java_echo_client --logcat-tags=JavaEchoClient,JavaEchoServer --url-mappings=mojo:echo_server=mojo:java_echo_server --args-for='mojo:java_echo_client Hello Mojo'`
 
 <!---
 If you copy the above commands from this source .md file then do not include the backticks: `
diff --git a/mojo/devtools/common/README.md b/mojo/devtools/common/README.md
index 656dbd1..7db9cb1 100644
--- a/mojo/devtools/common/README.md
+++ b/mojo/devtools/common/README.md
@@ -2,39 +2,37 @@
 
 Unopinionated tools for **running**, **debugging** and **testing** Mojo apps.
 
-The repo consists of:
+## Repo contents
 
- - **devtoolslib** - Python module containing the core scripting functionality
-   for running Mojo apps: shell abstraction with implementations for Android and
-   Linux and support for apptest frameworks
- - executable scripts - example embedders of devtoolslib and other utils
+Devtools offer the following tools:
 
-## Embedding devtoolslib
-
-As devtools carry no assumptions about build system or file layout being used,
-the primary way of using devtools now is to embed the functionality provided by
-**devtoolslib** in a thin wrapper script. For examples, one can refer to mojo's
-[shell
-runner](https://github.com/domokit/mojo/blob/master/mojo/tools/mojo_shell.py)
-and [apptest
-runner](https://github.com/domokit/mojo/blob/master/mojo/tools/apptest_runner.py).
-
-## Executable scripts
-
-The set of executable scripts is WIP. We currently offer:
-
- - **debugger** - supports interactive tracing of a running mojo shell and
-   symbolizing android stack traces
+ - **mojo_shell** - universall shell runner
+ - **debugger** - supports interactive tracing and debugging of a running mojo shell
  - **remote_adb_setup** - configures adb on a remote machine to communicate with
    a device attached to the local machine
 
+and a Python scripting library designed for being embedded (devtoolslib).
+
+### Devtoolslib
+
+**devtoolslib** is a Python module containing the core scripting functionality
+for running Mojo apps: shell abstraction with implementations for Android and
+Linux and support for apptest frameworks. The executable scripts in devtools
+are based on this module.
+
+As devtools carry no assumptions about build system or file layout being used,
+one can choose to embed the functionality provided by **devtoolslib** in their
+own wrapper, instead of relying on the provided scripts. For examples, one can
+refer to mojo's [apptest
+runner](https://github.com/domokit/mojo/blob/master/mojo/tools/apptest_runner.py).
+
 ## Install
 
 ```
 git clone https://github.com/domokit/devtools.git
 ```
 
-## File location
+## Development
 
 The library is canonically developed [in the mojo
 repository](https://github.com/domokit/mojo/tree/master/mojo/devtools/common),
diff --git a/mojo/devtools/common/devtoolslib/default_paths.py b/mojo/devtools/common/devtoolslib/default_paths.py
new file mode 100644
index 0000000..3bffca7
--- /dev/null
+++ b/mojo/devtools/common/devtoolslib/default_paths.py
@@ -0,0 +1,58 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Supports inferring locations of files in default checkout layouts.
+
+These functions allow devtools scripts to work out-of-the-box with regular Mojo
+checkouts.
+"""
+
+import os.path
+
+
+def _lowest_ancestor_containing_relpath(relpath):
+  """Returns the lowest ancestor of this file that contains |relpath|."""
+  cur_dir_path = os.path.abspath(os.path.dirname(__file__))
+  while True:
+    if os.path.exists(os.path.join(cur_dir_path, relpath)):
+      return cur_dir_path
+
+    next_dir_path = os.path.dirname(cur_dir_path)
+    if next_dir_path != cur_dir_path:
+      cur_dir_path = next_dir_path
+    else:
+      return None
+
+
+def infer_default_paths(is_android, is_debug, target_cpu):
+  """Infers the locations of select build output artifacts in a regular Mojo
+  checkout.
+
+  Returns:
+    Tuple of path dictionary, error message. Only one of the two will be
+    not-None.
+  """
+  build_dir = (('android_' if is_android else '') +
+               (target_cpu + '_' if target_cpu else '') +
+               ('Debug' if is_debug else 'Release'))
+  out_build_dir = os.path.join('out', build_dir)
+
+  root_path = _lowest_ancestor_containing_relpath(out_build_dir)
+  if not root_path:
+    return None, ('Failed to find build directory: ' + out_build_dir)
+
+  paths = {}
+  paths['root'] = root_path
+  build_dir_path = os.path.join(root_path, out_build_dir)
+  paths['build'] = build_dir_path
+  if is_android:
+    paths['shell'] = os.path.join(build_dir_path, 'apks', 'MojoShell.apk')
+    paths['adb'] = os.path.join(root_path, 'third_party', 'android_tools',
+                                'sdk', 'platform-tools', 'adb')
+  else:
+    paths['shell'] = os.path.join(build_dir_path, 'mojo_shell')
+
+  paths['sky_packages'] = os.path.join(build_dir_path, 'gen', 'dart-pkg',
+                                       'packages')
+  return paths, None
diff --git a/mojo/devtools/common/mojo_shell b/mojo/devtools/common/mojo_shell
new file mode 100755
index 0000000..517b38e
--- /dev/null
+++ b/mojo/devtools/common/mojo_shell
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import logging
+import sys
+
+from devtoolslib.android_shell import AndroidShell
+from devtoolslib.linux_shell import LinuxShell
+from devtoolslib import shell_arguments
+from devtoolslib import default_paths
+
+USAGE = ("mojo_shell "
+         "[--args-for=<mojo-app>] "
+         "[--content-handlers=<handlers>] "
+         "[--enable-external-applications] "
+         "[--disable-cache] "
+         "[--enable-multiprocess] "
+         "[--url-mappings=from1=to1,from2=to2] "
+         "[<mojo-app>] "
+         """
+
+A <mojo-app> is a Mojo URL or a Mojo URL and arguments within quotes.
+Example: mojo_shell "mojo:js_standalone test.js".
+<url-lib-path> is searched for shared libraries named by mojo URLs.
+The value of <handlers> is a comma separated list like:
+text/html,mojo:html_viewer,application/javascript,mojo:js_content_handler
+""")
+
+_DEFAULT_WINDOW_MANAGER = "mojo:kiosk_wm"
+_SKY_SERVER_PORT = 9998
+
+
+def main():
+  logging.basicConfig()
+
+  parser = argparse.ArgumentParser(usage=USAGE)
+
+  # Arguments indicating the configuration we are targeting.
+  parser.add_argument('--android', help='Run on Android',
+                      action='store_true')
+  debug_group = parser.add_mutually_exclusive_group()
+  debug_group.add_argument('--debug', help='Debug build (default)',
+                           default=True, action='store_true')
+  debug_group.add_argument('--release', help='Release build', default=False,
+                           dest='debug', action='store_false')
+  parser.add_argument('--target-cpu', help='CPU architecture to run for.',
+                      choices=['x64', 'x86', 'arm'])
+
+  # Arguments configuring the shell run.
+  parser.add_argument('--origin', help='Origin for mojo: URLs.')
+  parser.add_argument('--window-manager', default=_DEFAULT_WINDOW_MANAGER,
+                      help='Window manager app to be mapped as '
+                      'mojo:window_manager. By default it is ' +
+                      _DEFAULT_WINDOW_MANAGER)
+  parser.add_argument('--no-debugger', action="store_true",
+                      help='Do not spawn mojo:debugger.')
+  parser.add_argument('--sky',
+                      help='Loads the given Sky file.')
+  parser.add_argument('-v', '--verbose', action="store_true",
+                      help="Increase output verbosity")
+
+  # Android-only arguments.
+  parser.add_argument('--target-device',
+                      help='(android-only) Device to run on.')
+  parser.add_argument('--logcat-tags',
+                      help='(android-only) Comma-separated list of additional '
+                      'logcat tags to display on the console.')
+
+  # Desktop-only arguments.
+  parser.add_argument('--use-osmesa', action='store_true',
+                      help='(linux-only) Configure the native viewport service '
+                      'for off-screen rendering.')
+
+  launcher_args, args = parser.parse_known_args()
+  paths, error_msg = default_paths.infer_default_paths(launcher_args.android,
+                                                       launcher_args.debug,
+                                                       launcher_args.target_cpu)
+  if not paths:
+    print error_msg
+    return -1
+
+  if launcher_args.android:
+    verbose_pipe = sys.stdout if launcher_args.verbose else None
+
+    shell = AndroidShell(paths['adb'], launcher_args.target_device,
+                         logcat_tags=launcher_args.logcat_tags,
+                         verbose_pipe=verbose_pipe)
+    device_status, error = shell.CheckDevice()
+    if not device_status:
+      print 'Device check failed: ' + error
+      return 1
+    shell.InstallApk(paths['shell'])
+
+    args = shell_arguments.RewriteMapOriginParameters(shell, args)
+    if not launcher_args.origin:
+      args.extend(shell_arguments.ConfigureLocalOrigin(shell, paths['build']))
+  else:
+    shell = LinuxShell(paths['shell'])
+    if launcher_args.use_osmesa:
+      args.append('--args-for=mojo:native_viewport_service --use-osmesa')
+
+  if launcher_args.origin:
+    args.append('--origin=' + launcher_args.origin)
+  args = shell_arguments.AppendToArgument(args, '--url-mappings=',
+                                          'mojo:window_manager=%s' %
+                                          launcher_args.window_manager)
+  if not launcher_args.no_debugger:
+    args.extend(shell_arguments.ConfigureDebugger(shell))
+
+  if launcher_args.sky:
+    # Configure a server to serve the checkout root at / (so that Sky examples
+    # are accessible using a root-relative path) and Sky packages at /packages.
+    # This is independent from the server that potentially serves the origin
+    # directory containing the mojo: apps.
+    additional_mappings = [
+        ('packages/', paths['sky_packages']),
+    ]
+    server_url = shell.ServeLocalDirectory(paths['root'],
+        port=_SKY_SERVER_PORT, additional_mappings=additional_mappings)
+
+    # Configure the content type mappings for the sky_viewer. This is needed
+    # only for the Sky apps that do not declare mojo:sky_viewer in a shebang,
+    # and it is unfortunate as it configures the shell to map all items of the
+    # application/dart content-type as Sky apps.
+    # TODO(ppi): drop this part once we can rely on the Sky files declaring
+    # correct shebang.
+    args = shell_arguments.AppendToArgument(args, '--content-handlers=',
+                                            'text/sky,mojo:sky_viewer')
+    args = shell_arguments.AppendToArgument(args, '--content-handlers=',
+                                            'application/dart,mojo:sky_viewer')
+
+    # Configure the window manager to embed the sky_viewer.
+    sky_url = server_url + launcher_args.sky
+    args.append('mojo:window_manager %s' % sky_url)
+
+  if launcher_args.verbose:
+    print "Shell arguments: " + str(args)
+
+  shell.Run(args)
+  return 0
+
+
+if __name__ == "__main__":
+  sys.exit(main())
diff --git a/mojo/tools/mojo_shell.py b/mojo/tools/mojo_shell.py
index 4c303d9..6a689f4 100755
--- a/mojo/tools/mojo_shell.py
+++ b/mojo/tools/mojo_shell.py
@@ -3,154 +3,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import argparse
-import logging
 import sys
-import os.path
-import subprocess
-
-import devtools
-devtools.add_lib_to_path()
-from devtoolslib.android_shell import AndroidShell
-from devtoolslib.linux_shell import LinuxShell
-from devtoolslib import shell_arguments
-
-from mopy.config import Config
-from mopy.paths import Paths
-
-USAGE = ("mojo_shell.py "
-         "[--args-for=<mojo-app>] "
-         "[--content-handlers=<handlers>] "
-         "[--enable-external-applications] "
-         "[--disable-cache] "
-         "[--enable-multiprocess] "
-         "[--url-mappings=from1=to1,from2=to2] "
-         "[<mojo-app>] "
-         """
-
-A <mojo-app> is a Mojo URL or a Mojo URL and arguments within quotes.
-Example: mojo_shell "mojo:js_standalone test.js".
-<url-lib-path> is searched for shared libraries named by mojo URLs.
-The value of <handlers> is a comma separated list like:
-text/html,mojo:html_viewer,application/javascript,mojo:js_content_handler
-""")
-
-_DEFAULT_WINDOW_MANAGER = "mojo:kiosk_wm"
-_SKY_SERVER_PORT = 9998
 
 
 def main():
-  logging.basicConfig()
-
-  parser = argparse.ArgumentParser(usage=USAGE)
-
-  # Arguments indicating the configuration we are targeting.
-  parser.add_argument('--android', help='Run on Android',
-                      action='store_true')
-  debug_group = parser.add_mutually_exclusive_group()
-  debug_group.add_argument('--debug', help='Debug build (default)',
-                           default=True, action='store_true')
-  debug_group.add_argument('--release', help='Release build', default=False,
-                           dest='debug', action='store_false')
-  parser.add_argument('--target-cpu', help='CPU architecture to run for.',
-                      choices=['x64', 'x86', 'arm'])
-
-  # Arguments configuring the shell run.
-  parser.add_argument('--origin', help='Origin for mojo: URLs.')
-  parser.add_argument('--window-manager', default=_DEFAULT_WINDOW_MANAGER,
-                      help='Window manager app to be mapped as '
-                      'mojo:window_manager. By default it is ' +
-                      _DEFAULT_WINDOW_MANAGER)
-  parser.add_argument('--no-debugger', action="store_true",
-                      help='Do not spawn mojo:debugger.')
-  parser.add_argument('--sky',
-                      help='Loads the given Sky file.')
-  parser.add_argument('-v', '--verbose', action="store_true",
-                      help="Increase output verbosity")
-
-  # Android-only arguments.
-  parser.add_argument('--target-device',
-                      help='(android-only) Device to run on.')
-  parser.add_argument('--logcat-tags',
-                      help='(android-only) Comma-separated list of additional '
-                      'logcat tags to display on the console.')
-
-  # Desktop-only arguments.
-  parser.add_argument('--use-osmesa', action='store_true',
-                      help='(linux-only) Configure the native viewport service '
-                      'for off-screen rendering.')
-
-  launcher_args, args = parser.parse_known_args()
-  if launcher_args.android:
-    config = Config(target_os=Config.OS_ANDROID,
-                    target_cpu=launcher_args.target_cpu,
-                    is_debug=launcher_args.debug)
-    paths = Paths(config)
-    verbose_pipe = sys.stdout if launcher_args.verbose else None
-
-    shell = AndroidShell(paths.adb_path, launcher_args.target_device,
-                         logcat_tags=launcher_args.logcat_tags,
-                         verbose_pipe=verbose_pipe)
-    device_status, error = shell.CheckDevice()
-    if not device_status:
-      print 'Device check failed: ' + error
-      return 1
-    shell.InstallApk(paths.target_mojo_shell_path)
-
-    args = shell_arguments.RewriteMapOriginParameters(shell, args)
-    if not launcher_args.origin:
-      args.extend(shell_arguments.ConfigureLocalOrigin(shell, paths.build_dir))
-  else:
-    config = Config(target_os=Config.OS_LINUX,
-                    target_cpu=launcher_args.target_cpu,
-                    is_debug=launcher_args.debug)
-    paths = Paths(config)
-    shell = LinuxShell(paths.mojo_shell_path)
-    if launcher_args.use_osmesa:
-      args.append('--args-for=mojo:native_viewport_service --use-osmesa')
-
-  if launcher_args.origin:
-    args.append('--origin=' + launcher_args.origin)
-  args = shell_arguments.AppendToArgument(args, '--url-mappings=',
-                                          'mojo:window_manager=%s' %
-                                          launcher_args.window_manager)
-  if not launcher_args.no_debugger:
-    args.extend(shell_arguments.ConfigureDebugger(shell))
-
-  if launcher_args.sky:
-    # Configure a server to serve the checkout root at / (so that Sky examples
-    # are accessible using a root-relative path) and Sky packages at /packages.
-    # This is independent from the server that potentially serves the origin
-    # directory containing the mojo: apps.
-    packages_local_path = os.path.join(paths.build_dir, 'gen', 'dart-pkg',
-                                       'packages')
-    additional_mappings = [
-        ('packages/', packages_local_path),
-    ]
-    server_url = shell.ServeLocalDirectory(paths.src_root,
-        port=_SKY_SERVER_PORT, additional_mappings=additional_mappings)
-
-    # Configure the content type mappings for the sky_viewer. This is needed
-    # only for the Sky apps that do not declare mojo:sky_viewer in a shebang,
-    # and it is unfortunate as it configures the shell to map all items of the
-    # application/dart content-type as Sky apps.
-    # TODO(ppi): drop this part once we can rely on the Sky files declaring
-    # correct shebang.
-    args = shell_arguments.AppendToArgument(args, '--content-handlers=',
-                                            'text/sky,mojo:sky_viewer')
-    args = shell_arguments.AppendToArgument(args, '--content-handlers=',
-                                            'application/dart,mojo:sky_viewer')
-
-    # Configure the window manager to embed the sky_viewer.
-    sky_url = server_url + launcher_args.sky
-    args.append('mojo:window_manager %s' % sky_url)
-
-  if launcher_args.verbose:
-    print "Shell arguments: " + str(args)
-
-  shell.Run(args)
-  return 0
-
+  print 'Good news, the shell runner has moved! Please use: '
+  print ''
+  print '  mojo/devtools/common/mojo_shell'
+  print ''
+  print 'as you would use mojo_shell.py before.'
+  return -1
 
 if __name__ == "__main__":
   sys.exit(main())