Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(755)

Unified Diff: build/build-bisect.py

Issue 195006: Add a Mac-specifc snapshot build archive bisecting tool. (Closed)
Patch Set: Style changes Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/build-bisect.py
diff --git a/build/build-bisect.py b/build/build-bisect.py
new file mode 100755
index 0000000000000000000000000000000000000000..38fc54f85fd1182f2f2cbf2d2c9eaf38661ec8b8
--- /dev/null
+++ b/build/build-bisect.py
@@ -0,0 +1,160 @@
+#!/usr/bin/python2.5
+# 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.
+
+"""Snapshot Build Bisect Tool
+
+This script bisects the Mac snapshot archive using binary search. It starts at
+a bad revision (it will try to guess HEAD) and asks for a last known-good
+revision. It will then binary search across this revision range by downloading,
+unzipping, and opening Chromium for you. After testing the specific revision,
+it will ask you whether it is good or bad before continuing the search.
+
+Currently this only works on Mac, but with some effort it could be ported to
+other platforms.
+"""
+
+# Base URL to download snapshots from.
+BUILD_BASE_URL = \
+ "http://build.chromium.org/buildbot/snapshots/chromium-rel-mac"
+
+# Location of the latest build revision number
+BUILD_LATEST_URL = "%s/LATEST" % BUILD_BASE_URL
+
+# The location of the builds.
+BUILD_ARCHIVE_URL = "/%d/"
+
+# Name of the build archive.
+BUILD_ZIP_NAME = "chrome-mac.zip"
+
+# Directory name inside the archive.
+BUILD_DIR_NAME = "chrome-mac"
+
+# Name of the executable.
+BUILD_EXE_NAME = "Chromium.app"
+
+# URL to the ViewVC commit page.
+BUILD_VIEWVC_URL = "http://src.chromium.org/viewvc/chrome?view=rev&revision=%d"
+
+###############################################################################
+
+import math
+import os
+import re
+import shutil
+import sys
+import urllib
+
+def ParseDirectoryIndex(url):
+ """Parses the HTML directory listing into a list of revision numbers."""
+ handle = urllib.urlopen(url)
+ dirindex = handle.read()
+ handle.close()
+ return re.findall(r'<a href="([0-9]*)/">\1/</a>', dirindex)
+
+def GetRevList(good, bad):
+ """Gets the list of revision numbers between |good| and |bad|."""
+ # Download the main revlist.
+ revlist = ParseDirectoryIndex(BUILD_BASE_URL)
+ revlist = map(int, revlist)
+ revlist = filter(lambda r: range(good, bad).__contains__(int(r)), revlist)
+ revlist.sort()
+ return revlist
+
+def TryRevision(rev):
+ """Downloads revision |rev|, unzips it, and opens it for the user to test."""
+ # Clear anything that's currently there.
+ try:
+ os.remove(BUILD_ZIP_NAME)
+ shutil.rmtree(BUILD_DIR_NAME, True)
+ except Exception, e:
+ pass
+
+ # Download the file.
+ download_url = BUILD_BASE_URL + (BUILD_ARCHIVE_URL % rev) + BUILD_ZIP_NAME
+ try:
+ urllib.urlretrieve(download_url, BUILD_ZIP_NAME)
+ except Exception, e:
+ print("Could not retrieve the download. Sorry.")
+ print("Tried to get: %s" % download_url)
+ sys.exit(-1)
+
+ # Unzip the file.
+ os.system("unzip -q %s" % BUILD_ZIP_NAME)
+
+ # Tell Finder to open the app.
+ os.system("open %s/%s" % (BUILD_DIR_NAME, BUILD_EXE_NAME))
+
+def AskIsGoodBuild(rev):
+ """Annoyingly ask the user whether build |rev| is good or bad."""
+ while True:
+ check = raw_input("Build %d [g/b]: " % int(rev))[0]
+ if (check == "g" or check == "b"):
+ return (check == "g")
+ else:
+ print("Just answer the question...")
+
+def main():
+ print("chrome-bisect: Perform binary search on the snapshot builds")
+
+ # Pick a starting point, try to get HEAD for this.
+ bad_rev = 0
+ try:
+ nh = urllib.urlopen(BUILD_LATEST_URL)
+ latest = int(nh.read())
+ nh.close()
+ bad_rev = raw_input("Bad revision [HEAD:%d]: " % latest)
+ if (bad_rev == ""):
+ bad_rev = latest
+ bad_rev = int(bad_rev)
+ except Exception, e:
+ print("Could not determine latest revision. This could be bad...")
+ bad_rev = int(raw_input("Bad revision: "))
+
+ # Find out when we were good.
+ good_rev = 0
+ try:
+ good_rev = int(raw_input("Last known good [0]: "))
+ except Exception, e:
+ pass
+
+ # Get a list of revisions to bisect across.
+ revlist = GetRevList(good_rev, bad_rev)
+
+ # If we don't have a |good_rev|, set it to be the first revision possible.
+ if good_rev == 0:
+ good_rev = revlist[0]
+
+ # These are indexes of |revlist|.
+ good = 0
+ bad = len(revlist) - 1
+
+ # Binary search time!
+ while good < bad:
+ candidates = revlist[good:bad]
+ num_poss = len(candidates)
+ if num_poss > 10:
+ print("%d candidates. %d tries left." %
+ (num_poss, round(math.log(num_poss, 2))))
+ else:
+ print("Candidates: %s" % revlist[good:bad])
+
+ # Cut the problem in half...
+ test = int((bad - good) / 2) + good
+ test_rev = revlist[test]
+
+ # Let the user give this revision a spin.
+ TryRevision(test_rev)
+ if AskIsGoodBuild(test_rev):
+ good = test + 1
+ else:
+ bad = test
+
+ # We're done. Let the user know the results in an official manner.
+ print("You are probably looking for build %d." % revlist[bad])
Evan Martin 2009/09/03 20:18:49 Maybe point out that this build is the earliest *b
+ print("This is the ViewVC URL for the potential bustage:")
+ print(BUILD_VIEWVC_URL % revlist[bad])
+
+if __name__ == '__main__':
+ main()
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698