123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #!/usr/bin/python
- # Copyright (c) 2009 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.
- # 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
- def Message(str):
- """Prints a status message."""
- print "[chrome-update]", str
- def FixupPath(path):
- """Returns the OS-ified version of a windows path."""
- return os.path.sep.join(path.split("\\"))
- def GetRevision():
- """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))
- 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.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]
- 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.")
- # 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()
- 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]
- 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")
- if rv != 0:
- Message("Debug build failed. Sad face :(")
- if options.release:
- rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release")
- if rv != 0:
- Message("Release build failed. Sad face :(")
- if rv != 0:
- sys.exit(rv)
- Message("Success!")
- if __name__ == "__main__":
- Main()
|