Improve roll.py to work with HEAD Chromium
diff --git a/sky/tools/roll/android_build.patch b/sky/tools/roll/android_build.patch
new file mode 100644
index 0000000..bd73b9e
--- /dev/null
+++ b/sky/tools/roll/android_build.patch
@@ -0,0 +1,33 @@
+--- a/build/android/pylib/constants/__init__.py
++++ b/build/android/pylib/constants/__init__.py
+@@ -184,7 +184,7 @@ class ANDROID_SDK_VERSION_CODES(object):
+   LOLLIPOP_MR1 = 22
+ 
+ ANDROID_SDK_VERSION = ANDROID_SDK_VERSION_CODES.LOLLIPOP_MR1
+-ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.0'
++ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.1'
+ ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT,
+                                 'third_party/android_tools/sdk')
+ ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
+--- a/build/common.gypi
++++ b/build/common.gypi
+@@ -1682,7 +1682,7 @@
+             'android_host_arch%': '<!(uname -m)',
+             # Android API-level of the SDK used for compilation.
+             'android_sdk_version%': '22',
+-            'android_sdk_build_tools_version%': '22.0.0',
++            'android_sdk_build_tools_version%': '22.0.1',
+             'host_os%': "<!(uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')",
+           },
+           # Copy conditionally-set variables out one scope.
+--- a/build/config/android/config.gni
++++ b/build/config/android/config.gni
+@@ -17,7 +17,7 @@ if (is_android) {
+   if (!defined(default_android_sdk_root)) {
+     default_android_sdk_root = "//third_party/android_tools/sdk"
+     default_android_sdk_version = "22"
+-    default_android_sdk_build_tools_version = "22.0.0"
++    default_android_sdk_build_tools_version = "22.0.1"
+   }
+ 
+   if (!defined(google_play_services_library)) {
diff --git a/sky/tools/roll/patch.py b/sky/tools/roll/patch.py
new file mode 100755
index 0000000..0aaf7c7
--- /dev/null
+++ b/sky/tools/roll/patch.py
@@ -0,0 +1,43 @@
+#!/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 os
+import subprocess
+import utils
+
+def patch_and_filter():
+  """Applies the *.patch files in the current dir and some hardcoded filters."""
+  os.chdir(utils.mojo_root_dir)
+
+  utils.filter_file("build/landmines.py",
+      lambda line: not "gyp_environment" in line)
+  utils.commit("filter gyp_environment out of build/landmines.py")
+
+  patch()
+
+
+def patch(relative_patches_dir=os.curdir):
+  """Applies the *.patch files in |relative_patches_dir|.
+
+  Args:
+    relative_patches_dir: A directory path relative to the current directory.
+        Defaults to the directory of this file.
+
+  Raises:
+    subprocess.CalledProcessError if the patch couldn't be applied.
+  """
+  patches_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                             relative_patches_dir)
+  assert os.path.isdir(patches_dir)
+
+  os.chdir(utils.mojo_root_dir)
+  for p in utils.find(["*.patch"], patches_dir):
+    print "applying patch %s" % os.path.basename(p)
+    try:
+      utils.system(["git", "apply", p])
+      utils.commit("applied patch %s" % os.path.basename(p))
+    except subprocess.CalledProcessError:
+      print "ERROR: patch %s failed to apply" % os.path.basename(p)
+      raise
diff --git a/sky/tools/roll/roll.py b/sky/tools/roll/roll.py
index e5f9bf8..f680d6b 100755
--- a/sky/tools/roll/roll.py
+++ b/sky/tools/roll/roll.py
@@ -11,6 +11,7 @@
 import urllib2
 from utils import commit
 from utils import system
+import patch
 
 # //base and its dependencies
 _base_deps = [
@@ -95,33 +96,39 @@
     'build/config/ui.gni',
     'build/ls.py',
     'build/module_args/mojo.gni',
+    'build/symlink.py',
+    'tools/android/VERSION_LINUX_NDK',
+    'tools/android/VERSION_LINUX_SDK',
+    'tools/android/VERSION_MACOSX_NDK',
+    'tools/android/VERSION_MACOSX_SDK',
+    'tools/android/download_android_tools.py',
 ]
 
 
-def rev(source_dir, dest_dir, dirs_to_rev):
-  for d in dirs_to_rev:
-    print "removing directory %s" % d
-    try:
-      system(["git", "rm", "-r", d], cwd=dest_dir)
-    except subprocess.CalledProcessError:
-      print "Could not remove %s" % d
-    print "cloning directory %s" % d
-    files = system(["git", "ls-files", d], cwd=source_dir)
-    for f in files.splitlines():
-      source_path = os.path.join(source_dir, f)
-      if not os.path.isfile(source_path):
-        continue
-      dest_path = os.path.join(dest_dir, f)
-      system(["mkdir", "-p", os.path.dirname(dest_path)], cwd=source_dir)
-      system(["cp", source_path, dest_path], cwd=source_dir)
-    system(["git", "add", d], cwd=dest_dir)
+def rev(source_dir, dest_dir, dirs_to_rev, name):
+    for d in dirs_to_rev:
+      print "removing directory %s" % d
+      try:
+          system(["git", "rm", "-r", d], cwd=dest_dir)
+      except subprocess.CalledProcessError:
+          print "Could not remove %s" % d
+      print "cloning directory %s" % d
+      files = system(["git", "ls-files", d], cwd=source_dir)
+      for f in files.splitlines():
+          source_path = os.path.join(source_dir, f)
+          if not os.path.isfile(source_path):
+              continue
+          dest_path = os.path.join(dest_dir, f)
+          system(["mkdir", "-p", os.path.dirname(dest_path)], cwd=source_dir)
+          system(["cp", source_path, dest_path], cwd=source_dir)
+      system(["git", "add", d], cwd=dest_dir)
 
-  for f in files_not_to_roll:
-    system(["git", "checkout", "HEAD", f], cwd=dest_dir)
+    for f in files_not_to_roll:
+        system(["git", "checkout", "HEAD", f], cwd=dest_dir)
 
-  system(["git", "add", "."], cwd=dest_dir)
-  src_commit = system(["git", "rev-parse", "HEAD"], cwd=source_dir).strip()
-  commit("Update to mojo %s" % src_commit, cwd=dest_dir)
+    system(["git", "add", "."], cwd=dest_dir)
+    src_commit = system(["git", "rev-parse", "HEAD"], cwd=source_dir).strip()
+    commit("Update to %s %s" % (name, src_commit), cwd=dest_dir)
 
 
 def main():
@@ -134,10 +141,17 @@
   args = parser.parse_args()
 
   if args.mojo_dir:
-    rev(args.mojo_dir, args.dest_dir, dirs_from_mojo)
+      rev(args.mojo_dir, args.dest_dir, dirs_from_mojo, 'mojo')
 
   if args.chromium_dir:
-    rev(args.chromium_dir, args.dest_dir, dirs_from_chromium)
+      rev(args.chromium_dir, args.dest_dir, dirs_from_chromium, 'chromium')
+    
+      try:
+          patch.patch_and_filter()
+      except subprocess.CalledProcessError:
+          print "ERROR: Roll failed due to a patch not applying"
+          print "Fix the patch to apply, commit the result, and re-run this script"
+          return 1
 
   return 0