Update recipes.py to 78c57c5d69a38ef3db86d9763d539383f98714e6.

This updates the recipes.py script to the latest version, which fixes a
couple bugs.

BUG=

Change-Id: Ibe958f1b767050b9492fe725d42642f42b1133e8
diff --git a/recipes.py b/recipes.py
old mode 100644
new mode 100755
index 7b11ee5..b944b0a
--- a/recipes.py
+++ b/recipes.py
@@ -26,6 +26,7 @@
 
 BOOTSTRAP_VERSION = 1
 
+import argparse
 import ast
 import logging
 import random
@@ -103,15 +104,38 @@
   logging.info('Running %r', argv)
   return subprocess.call(argv, **kwargs)
 
+
 def _subprocess_check_call(argv, **kwargs):
   logging.info('Running %r', argv)
   subprocess.check_call(argv, **kwargs)
 
 
+def find_engine_override(argv):
+  """Since the bootstrap process attempts to defer all logic to the recipes-py
+  repo, we need to be aware if the user is overriding the recipe_engine
+  dependency. This looks for and returns the overridden recipe_engine path, if
+  any, or None if the user didn't override it."""
+  PREFIX = 'recipe_engine='
+
+  p = argparse.ArgumentParser()
+  p.add_argument('-O', '--project-override', action='append')
+  args, _ = p.parse_known_args(argv)
+  for override in args.project_override or ():
+    if override.startswith(PREFIX):
+      return override[len(PREFIX):]
+  return None
+
+
 def main():
   if '--verbose' in sys.argv:
     logging.getLogger().setLevel(logging.INFO)
 
+  if REPO_ROOT is None or RECIPES_CFG is None:
+    logging.error(
+      'In order to use this script, please copy it to your repo and '
+      'replace the REPO_ROOT and RECIPES_CFG values with approprite paths.')
+    sys.exit(1)
+
   if sys.platform.startswith(('win', 'cygwin')):
     git = 'git.bat'
   else:
@@ -126,40 +150,42 @@
     protobuf = parse_protobuf(fh)
 
   engine_buf = get_unique([
-      b for b in protobuf['deps'] if b.get('project_id') == ['recipe_engine'] ])
+      b for b in protobuf.get('deps', [])
+      if b.get('project_id') == ['recipe_engine'] ])
   engine_url = get_unique(engine_buf['url'])
   engine_revision = get_unique(engine_buf['revision'])
   engine_subpath = (get_unique(engine_buf.get('path_override', ['']))
                     .replace('/', os.path.sep))
 
   recipes_path = os.path.join(repo_root,
-      get_unique(protobuf['recipes_path']).replace('/', os.path.sep))
+      get_unique(protobuf.get('recipes_path', [''])).replace('/', os.path.sep))
   deps_path = os.path.join(recipes_path, '.recipe_deps')
-  engine_path = os.path.join(deps_path, 'recipe_engine')
+  engine_path = find_engine_override(sys.argv[1:])
+  if not engine_path:
+    # Ensure that we have the recipe engine cloned.
+    engine_path = os.path.join(deps_path, 'recipe_engine')
+    def ensure_engine():
+      if not os.path.exists(deps_path):
+        os.makedirs(deps_path)
+      if not os.path.exists(engine_path):
+        _subprocess_check_call([git, 'clone', engine_url, engine_path])
 
-  # Ensure that we have the recipe engine cloned.
-  def ensure_engine():
-    if not os.path.exists(deps_path):
-      os.makedirs(deps_path)
-    if not os.path.exists(engine_path):
-      _subprocess_check_call([git, 'clone', engine_url, engine_path])
+      needs_fetch = _subprocess_call(
+          [git, 'rev-parse', '--verify', '%s^{commit}' % engine_revision],
+          cwd=engine_path, stdout=open(os.devnull, 'w'))
+      if needs_fetch:
+        _subprocess_check_call([git, 'fetch'], cwd=engine_path)
+      _subprocess_check_call(
+          [git, 'checkout', '--quiet', engine_revision], cwd=engine_path)
 
-    needs_fetch = _subprocess_call(
-        [git, 'rev-parse', '--verify', '%s^{commit}' % engine_revision],
-        cwd=engine_path, stdout=open(os.devnull, 'w'))
-    if needs_fetch:
-      _subprocess_check_call([git, 'fetch'], cwd=engine_path)
-    _subprocess_check_call(
-        [git, 'checkout', '--quiet', engine_revision], cwd=engine_path)
+    try:
+      ensure_engine()
+    except subprocess.CalledProcessError:
+      logging.exception('ensure_engine failed')
 
-  try:
-    ensure_engine()
-  except subprocess.CalledProcessError:
-    logging.exception('ensure_engine failed')
-
-    # Retry errors.
-    time.sleep(random.uniform(2,5))
-    ensure_engine()
+      # Retry errors.
+      time.sleep(random.uniform(2,5))
+      ensure_engine()
 
   args = ['--package', recipes_cfg_path] + sys.argv[1:]
   return _subprocess_call([