chrome-update.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/python
  2. # Copyright (c) 2009 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. # Author: mpcomplete
  6. #
  7. # This script updates and does a clean build of chrome for you.
  8. # Usage: python chrome-update.py C:\path\to\chrome\trunk
  9. #
  10. # It assumes the following:
  11. # - You have gclient.bat and devenv.com in your path (use the wrapper batch
  12. # file to ensure this).
  13. import sys
  14. import os
  15. import subprocess
  16. import httplib
  17. import re
  18. import shutil
  19. import optparse
  20. def Message(str):
  21. """Prints a status message."""
  22. print "[chrome-update]", str
  23. def FixupPath(path):
  24. """Returns the OS-ified version of a windows path."""
  25. return os.path.sep.join(path.split("\\"))
  26. def GetRevision():
  27. """Returns the revision number of the last build that was archived, or
  28. None on failure."""
  29. HOST = "build.chromium.org"
  30. PATH = "/buildbot/continuous/LATEST/REVISION"
  31. EXPR = r"(\d+)"
  32. connection = httplib.HTTPConnection(HOST)
  33. connection.request("GET", PATH)
  34. response = connection.getresponse()
  35. text = response.read()
  36. match = re.search(EXPR, text)
  37. if match:
  38. return int(match.group(1))
  39. return None
  40. def SetRevisionForUpdate(chrome_root):
  41. """Prepares environment so gclient syncs to a good revision, if possible."""
  42. # Find a buildable revision.
  43. rev = GetRevision()
  44. if rev == None:
  45. Message("WARNING: Failed to find a buildable revision. Syncing to trunk.")
  46. return "trunk"
  47. # Read the .gclient file.
  48. gclient_file = chrome_root + FixupPath("\\.gclient")
  49. if not os.path.exists(gclient_file):
  50. Message("WARNING: Failed to find .gclient file. Syncing to trunk.")
  51. return "trunk"
  52. scope = {}
  53. execfile(gclient_file, scope)
  54. solutions = scope["solutions"]
  55. # Edit the url of the chrome 'src' solution, unless the user wants a
  56. # specific revision.
  57. for solution in solutions:
  58. if solution["name"] == "src":
  59. splitter = solution["url"].split("@")
  60. if len(splitter) == 1:
  61. solution["url"] = splitter[0] + "@" + str(rev)
  62. else:
  63. rev = int(splitter[1])
  64. break
  65. # Write out the new .gclient file.
  66. gclient_override = gclient_file + "-update-chrome"
  67. f = open(gclient_override, "w")
  68. f.write("solutions = " + str(solutions))
  69. f.close()
  70. # Set the env var that the gclient tool looks for.
  71. os.environ["GCLIENT_FILE"] = gclient_override
  72. return rev
  73. def DoUpdate(chrome_root):
  74. """gclient sync to the latest build."""
  75. # gclient sync
  76. rev = SetRevisionForUpdate(chrome_root)
  77. cmd = ["gclient.bat", "sync"]
  78. Message("Updating to %s: %s" % (rev, cmd))
  79. sys.stdout.flush()
  80. return subprocess.call(cmd, cwd=chrome_root)
  81. def DoClean(chrome_root, type):
  82. """Clean our build dir."""
  83. # rm -rf src/chrome/Debug
  84. rv = [0]
  85. def onError(func, path, excinfo):
  86. Message("Couldn't remove '%s': %s" % (path, excinfo))
  87. rv[0] = [1]
  88. build_path = chrome_root + FixupPath("\\src\\chrome\\" + type)
  89. Message("Cleaning: %s" % build_path)
  90. shutil.rmtree(build_path, False, onError)
  91. return rv[0]
  92. def DoBuild(chrome_root, chrome_sln, clean, type):
  93. """devenv /build what we just checked out."""
  94. if clean:
  95. rv = DoClean(chrome_root, type)
  96. if rv != 0:
  97. Message("WARNING: Clean failed. Doing a build without clean.")
  98. # devenv chrome.sln /build Debug
  99. cmd = ["devenv.com", chrome_sln, "/build", type]
  100. Message("Building: %s" % cmd)
  101. sys.stdout.flush()
  102. return subprocess.call(cmd, cwd=chrome_root)
  103. def Main():
  104. parser = optparse.OptionParser()
  105. parser.add_option("", "--clean", action="store_true", default=False,
  106. help="wipe Debug output directory before building")
  107. parser.add_option("", "--solution", default="src\\chrome\\chrome.sln",
  108. help="path to the .sln file to build (absolute, or "
  109. "relative to chrome trunk")
  110. parser.add_option("", "--release", action="store_true", default=False,
  111. help="build the release configuration in addition of the "
  112. "debug configuration.")
  113. parser.add_option("", "--nosync", action="store_true", default=False,
  114. help="doesn't sync before building")
  115. parser.add_option("", "--print-latest", action="store_true", default=False,
  116. help="print the latest buildable revision and exit")
  117. options, args = parser.parse_args()
  118. if options.print_latest:
  119. print GetRevision() or "HEAD"
  120. sys.exit(0)
  121. if not args:
  122. Message("Usage: %s <path\\to\\chrome\\root> [options]" % sys.argv[0])
  123. sys.exit(1)
  124. chrome_root = args[0]
  125. if not options.nosync:
  126. rv = DoUpdate(chrome_root)
  127. if rv != 0:
  128. Message("Update Failed. Bailing.")
  129. sys.exit(rv)
  130. chrome_sln = FixupPath(options.solution)
  131. rv = DoBuild(chrome_root, chrome_sln, options.clean, "Debug")
  132. if rv != 0:
  133. Message("Debug build failed. Sad face :(")
  134. if options.release:
  135. rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release")
  136. if rv != 0:
  137. Message("Release build failed. Sad face :(")
  138. if rv != 0:
  139. sys.exit(rv)
  140. Message("Success!")
  141. if __name__ == "__main__":
  142. Main()