summaryrefslogtreecommitdiff
path: root/deps/v8/tools/push-to-trunk/auto_tag.py
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/tools/push-to-trunk/auto_tag.py')
-rwxr-xr-xdeps/v8/tools/push-to-trunk/auto_tag.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/deps/v8/tools/push-to-trunk/auto_tag.py b/deps/v8/tools/push-to-trunk/auto_tag.py
new file mode 100755
index 000000000..6beaaff8a
--- /dev/null
+++ b/deps/v8/tools/push-to-trunk/auto_tag.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project 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 argparse
+import sys
+
+from common_includes import *
+
+CONFIG = {
+ BRANCHNAME: "auto-tag-v8",
+ PERSISTFILE_BASENAME: "/tmp/v8-auto-tag-tempfile",
+ DOT_GIT_LOCATION: ".git",
+ VERSION_FILE: "src/version.cc",
+}
+
+
+class Preparation(Step):
+ MESSAGE = "Preparation."
+
+ def RunStep(self):
+ self.CommonPrepare()
+ self.PrepareBranch()
+ self.GitCheckout("master")
+ self.GitSVNRebase()
+
+
+class GetTags(Step):
+ MESSAGE = "Get all V8 tags."
+
+ def RunStep(self):
+ self.GitCreateBranch(self._config[BRANCHNAME])
+
+ # Get remote tags.
+ tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s),
+ self.GitRemotes())
+
+ # Remove 'svn/tags/' prefix.
+ self["tags"] = map(lambda s: s[9:], tags)
+
+
+class GetOldestUntaggedVersion(Step):
+ MESSAGE = "Check if there's a version on bleeding edge without a tag."
+
+ def RunStep(self):
+ tags = set(self["tags"])
+ self["candidate"] = None
+ self["candidate_version"] = None
+ self["next"] = None
+ self["next_version"] = None
+
+ # Iterate backwards through all automatic version updates.
+ for git_hash in self.GitLog(
+ format="%H", grep="\\[Auto\\-roll\\] Bump up version to").splitlines():
+
+ # Get the version.
+ if not self.GitCheckoutFileSafe(self._config[VERSION_FILE], git_hash):
+ continue
+
+ self.ReadAndPersistVersion()
+ version = self.ArrayToVersion("")
+
+ # Strip off trailing patch level (tags don't include tag level 0).
+ if version.endswith(".0"):
+ version = version[:-2]
+
+ # Clean up checked-out version file.
+ self.GitCheckoutFileSafe(self._config[VERSION_FILE], "HEAD")
+
+ if version in tags:
+ if self["candidate"]:
+ # Revision "git_hash" is tagged already and "candidate" was the next
+ # newer revision without a tag.
+ break
+ else:
+ print("Stop as %s is the latest version and it has been tagged." %
+ version)
+ self.CommonCleanup()
+ return True
+ else:
+ # This is the second oldest version without a tag.
+ self["next"] = self["candidate"]
+ self["next_version"] = self["candidate_version"]
+
+ # This is the oldest version without a tag.
+ self["candidate"] = git_hash
+ self["candidate_version"] = version
+
+ if not self["candidate"] or not self["candidate_version"]:
+ print "Nothing found to tag."
+ self.CommonCleanup()
+ return True
+
+ print("Candidate for tagging is %s with version %s" %
+ (self["candidate"], self["candidate_version"]))
+
+
+class GetLKGRs(Step):
+ MESSAGE = "Get the last lkgrs."
+
+ def RunStep(self):
+ revision_url = "https://v8-status.appspot.com/revisions?format=json"
+ status_json = self.ReadURL(revision_url, wait_plan=[5, 20])
+ self["lkgrs"] = [entry["revision"]
+ for entry in json.loads(status_json) if entry["status"]]
+
+
+class CalculateTagRevision(Step):
+ MESSAGE = "Calculate the revision to tag."
+
+ def LastLKGR(self, min_rev, max_rev):
+ """Finds the newest lkgr between min_rev (inclusive) and max_rev
+ (exclusive).
+ """
+ for lkgr in self["lkgrs"]:
+ # LKGRs are reverse sorted.
+ if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev):
+ return lkgr
+ return None
+
+ def RunStep(self):
+ # Get the lkgr after the tag candidate and before the next tag candidate.
+ candidate_svn = self.GitSVNFindSVNRev(self["candidate"])
+ if self["next"]:
+ next_svn = self.GitSVNFindSVNRev(self["next"])
+ else:
+ # Don't include the version change commit itself if there is no upper
+ # limit yet.
+ candidate_svn = str(int(candidate_svn) + 1)
+ next_svn = sys.maxint
+ lkgr_svn = self.LastLKGR(candidate_svn, next_svn)
+
+ if not lkgr_svn:
+ print "There is no lkgr since the candidate version yet."
+ self.CommonCleanup()
+ return True
+
+ # Let's check if the lkgr is at least three hours old.
+ self["lkgr"] = self.GitSVNFindGitHash(lkgr_svn)
+ if not self["lkgr"]:
+ print "Couldn't find git hash for lkgr %s" % lkgr_svn
+ self.CommonCleanup()
+ return True
+
+ lkgr_utc_time = int(self.GitLog(n=1, format="%at", git_hash=self["lkgr"]))
+ current_utc_time = self._side_effect_handler.GetUTCStamp()
+
+ if current_utc_time < lkgr_utc_time + 10800:
+ print "Candidate lkgr %s is too recent for tagging." % lkgr_svn
+ self.CommonCleanup()
+ return True
+
+ print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"])
+
+
+class MakeTag(Step):
+ MESSAGE = "Tag the version."
+
+ def RunStep(self):
+ if not self._options.dry_run:
+ self.GitReset(self["lkgr"])
+ self.GitSVNTag(self["candidate_version"])
+
+
+class CleanUp(Step):
+ MESSAGE = "Clean up."
+
+ def RunStep(self):
+ self.CommonCleanup()
+
+
+class AutoTag(ScriptsBase):
+ def _PrepareOptions(self, parser):
+ parser.add_argument("--dry_run", help="Don't tag the new version.",
+ default=False, action="store_true")
+
+ def _ProcessOptions(self, options): # pragma: no cover
+ if not options.dry_run and not options.author:
+ print "Specify your chromium.org email with -a"
+ return False
+ options.wait_for_lgtm = False
+ options.force_readline_defaults = True
+ options.force_upload = True
+ return True
+
+ def _Steps(self):
+ return [
+ Preparation,
+ GetTags,
+ GetOldestUntaggedVersion,
+ GetLKGRs,
+ CalculateTagRevision,
+ MakeTag,
+ CleanUp,
+ ]
+
+
+if __name__ == "__main__": # pragma: no cover
+ sys.exit(AutoTag(CONFIG).Run())