Rewrite chrome-update.py and .bat.

Now reuse compile.py and almost make them platform agnostic.

TEST=none
BUG=none
Review URL: http://codereview.chromium.org/306031

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@59108 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome-update.py b/chrome-update.py
index a2baa43..d1eb176 100755
--- a/chrome-update.py
+++ b/chrome-update.py
@@ -3,171 +3,85 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Author: mpcomplete
-#
-# This script updates and does a clean build of chrome for you.
-# Usage: python chrome-update.py C:\path\to\chrome\trunk
-#
-# It assumes the following:
-# - You have gclient.bat and devenv.com in your path (use the wrapper batch
-#   file to ensure this).
-
-import sys
 import os
-import subprocess
-import httplib
 import re
-import shutil
-import optparse
+import subprocess
+import sys
+import urllib
 
-def Message(str):
-  """Prints a status message."""
-  print "[chrome-update]", str
+IS_WIN = sys.platform.startswith('win')
+BASE_URL = 'http://src.chromium.org/svn/trunk/tools/buildbot/scripts/'
+COMPILE_URL = BASE_URL + 'slave/compile.py'
+UTILS_URL = BASE_URL + 'common/chromium_utils.py'
 
-def FixupPath(path):
-  """Returns the OS-ified version of a windows path."""
-  return os.path.sep.join(path.split("\\"))
 
-def GetRevision():
+def Fetch(url, file):
+  if not os.path.exists(file):
+    urllib.urlretrieve(url, file)
+
+
+def GetLastestRevision():
   """Returns the revision number of the last build that was archived, or
   None on failure."""
-  HOST = "build.chromium.org"
-  PATH = "/buildbot/continuous/LATEST/REVISION"
-  EXPR = r"(\d+)"
-
-  connection = httplib.HTTPConnection(HOST)
-  connection.request("GET", PATH)
-  response = connection.getresponse()
-  text = response.read()
-  match = re.search(EXPR, text)
-  if match:
-    return int(match.group(1))
+  url = 'http://build.chromium.org/buildbot/continuous/'
+  if sys.platform.startswith('win'):
+    url += 'win/'
+  elif sys.platform.startswith('linux'):
+    url += 'linux/'
+  elif sys.platform.startswith('darwin'):
+    url += 'mac/'
+  else:
+    # This path is actually win.
+    pass
+  url += 'LATEST/REVISION'
+  text = urllib.urlopen(url).read()
+  if text:
+    match = re.search(r"(\d+)", text)
+    if match:
+      return int(match.group(1))
   return None
 
-def SetRevisionForUpdate(chrome_root):
-  """Prepares environment so gclient syncs to a good revision, if possible."""
-  # Find a buildable revision.
-  rev = GetRevision()
-  if rev == None:
-    Message("WARNING: Failed to find a buildable revision.  Syncing to trunk.")
-    return "trunk"
-
-  # Read the .gclient file.
-  gclient_file = chrome_root + FixupPath("\\.gclient")
-  if not os.path.exists(gclient_file):
-    Message("WARNING: Failed to find .gclient file.  Syncing to trunk.")
-    return "trunk"
-  scope = {}
-  execfile(gclient_file, scope)
-  solutions = scope["solutions"]
-
-  # Edit the url of the chrome 'src' solution, unless the user wants a
-  # specific revision.
-  for solution in solutions:
-    if solution["name"] == "src":
-      splitter = solution["url"].split("@")
-      if len(splitter) == 1:
-        solution["url"] = splitter[0] + "@" + str(rev)
-      else:
-        rev = int(splitter[1])
-      break
-
-  # Write out the new .gclient file.
-  gclient_override = gclient_file + "-update-chrome"
-  f = open(gclient_override, "w")
-  f.write("solutions = " + str(solutions))
-  f.close()
-
-  # Set the env var that the gclient tool looks for.
-  os.environ["GCLIENT_FILE"] = gclient_override
-  return rev
 
 def DoUpdate(chrome_root):
   """gclient sync to the latest build."""
-  # gclient sync
-  rev = SetRevisionForUpdate(chrome_root)
+  cmd = ["gclient", "sync"]
+  rev = GetLastestRevision()
+  if rev:
+    cmd.extend(['--revision', 'src@%d' % rev])
+  return subprocess.call(cmd, cwd=chrome_root, shell=IS_WIN)
 
-  cmd = ["gclient.bat", "sync"]
-  Message("Updating to %s: %s" % (rev, cmd))
-  sys.stdout.flush()
-  return subprocess.call(cmd, cwd=chrome_root)
 
-def DoClean(chrome_root, type):
-  """Clean our build dir."""
-  # rm -rf src/chrome/Debug
-  rv = [0]
-  def onError(func, path, excinfo):
-    Message("Couldn't remove '%s': %s" % (path, excinfo))
-    rv[0] = [1]
+def DoBuild(chrome_root, args):
+  """Download compile.py and run it."""
+  compile = os.path.join(chrome_root, 'compile.py')
+  Fetch(COMPILE_URL, compile)
+  Fetch(UTILS_URL, os.path.join(chrome_root, 'chromium_utils.py'))
+  cmd = ['python', compile] + args
+  return subprocess.call(cmd, cwd=chrome_root, shell=IS_WIN)
 
-  build_path = chrome_root + FixupPath("\\src\\chrome\\" + type)
-  Message("Cleaning: %s" % build_path)
-  shutil.rmtree(build_path, False, onError)
-  return rv[0]
 
-def DoBuild(chrome_root, chrome_sln, clean, type):
-  """devenv /build what we just checked out."""
-  if clean:
-    rv = DoClean(chrome_root, type)
-    if rv != 0:
-      Message("WARNING: Clean failed.  Doing a build without clean.")
+def Main(args):
+  if len(args) < 3:
+    print('Usage: chrome-update.py <path> [options]')
+    print('See options from compile.py at')
+    print('  %s' % COMPILE_URL)
+    print('\nFor more example, see the compile steps on the waterfall')
+    return 1
 
-  # devenv chrome.sln /build Debug
-  cmd = ["devenv.com", chrome_sln, "/build", type]
-
-  Message("Building: %s" % cmd)
-  sys.stdout.flush()
-  return subprocess.call(cmd, cwd=chrome_root)
-
-def Main():
-  parser = optparse.OptionParser()
-  parser.add_option("", "--clean", action="store_true", default=False,
-                    help="wipe Debug output directory before building")
-  parser.add_option("", "--solution", default="src\\chrome\\chrome.sln",
-                    help="path to the .sln file to build (absolute, or "
-                         "relative to chrome trunk")
-  parser.add_option("", "--release", action="store_true", default=False,
-                    help="build the release configuration in addition of the "
-                         "debug configuration.")
-  parser.add_option("", "--nosync", action="store_true", default=False,
-                    help="doesn't sync before building")
-  parser.add_option("", "--print-latest", action="store_true", default=False,
-                    help="print the latest buildable revision and exit")
-  options, args = parser.parse_args(None)
-
-  if options.print_latest:
-    print GetRevision() or "HEAD"
-    sys.exit(0)
-
-  if not args:
-    Message("Usage: %s <path\\to\\chrome\\root> [options]" % sys.argv[0])
-    sys.exit(1)
-
-  chrome_root = args[0]
+  chrome_root = args[1]
   if not os.path.isdir(chrome_root):
-    Message("Path to chrome root (%s) not found." % repr(chrome_root))
-    sys.exit(1)
+    print('Path to chrome root (%s) not found.' % chrome_root)
+    return 1
 
-  if not options.nosync:
-    rv = DoUpdate(chrome_root)
-    if rv != 0:
-      Message("Update Failed.  Bailing.")
-      sys.exit(rv)
-
-  chrome_sln = FixupPath(options.solution)
-  rv = DoBuild(chrome_root, chrome_sln, options.clean, "Debug")
+  rv = DoUpdate(chrome_root)
   if rv != 0:
-    Message("Debug build failed.  Sad face :(")
+    print('Update Failed.  Bailing.')
+    return rv
 
-  if options.release:
-    rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release")
-    if rv != 0:
-      Message("Release build failed.  Sad face :(")
+  DoBuild(chrome_root, args[2:])
+  print('Success!')
+  return 0
 
-  if rv != 0:
-    sys.exit(rv)
-
-  Message("Success!")
 
 if __name__ == "__main__":
-  Main()
+  sys.exit(Main(sys.argv))