Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / tools / push-to-trunk / auto_tag.py
1 #!/usr/bin/env python
2 # Copyright 2014 the V8 project 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
6 import argparse
7 import sys
8
9 from common_includes import *
10
11
12 class Preparation(Step):
13   MESSAGE = "Preparation."
14
15   def RunStep(self):
16     self.CommonPrepare()
17     self.PrepareBranch()
18     self.GitCheckout("master")
19     self.GitSVNRebase()
20
21
22 class GetTags(Step):
23   MESSAGE = "Get all V8 tags."
24
25   def RunStep(self):
26     self.GitCreateBranch(self._config["BRANCHNAME"])
27
28     # Get remote tags.
29     tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s),
30                   self.GitRemotes())
31
32     # Remove 'svn/tags/' prefix.
33     self["tags"] = map(lambda s: s[9:], tags)
34
35
36 class GetOldestUntaggedVersion(Step):
37   MESSAGE = "Check if there's a version on bleeding edge without a tag."
38
39   def RunStep(self):
40     tags = set(self["tags"])
41     self["candidate"] = None
42     self["candidate_version"] = None
43     self["next"] = None
44     self["next_version"] = None
45
46     # Iterate backwards through all automatic version updates.
47     for git_hash in self.GitLog(
48         format="%H", grep="\\[Auto\\-roll\\] Bump up version to").splitlines():
49
50       # Get the version.
51       if not self.GitCheckoutFileSafe(VERSION_FILE, git_hash):
52         continue
53
54       self.ReadAndPersistVersion()
55       version = self.ArrayToVersion("")
56
57       # Strip off trailing patch level (tags don't include tag level 0).
58       if version.endswith(".0"):
59         version = version[:-2]
60
61       # Clean up checked-out version file.
62       self.GitCheckoutFileSafe(VERSION_FILE, "HEAD")
63
64       if version in tags:
65         if self["candidate"]:
66           # Revision "git_hash" is tagged already and "candidate" was the next
67           # newer revision without a tag.
68           break
69         else:
70           print("Stop as %s is the latest version and it has been tagged." %
71                 version)
72           self.CommonCleanup()
73           return True
74       else:
75         # This is the second oldest version without a tag.
76         self["next"] = self["candidate"]
77         self["next_version"] = self["candidate_version"]
78
79         # This is the oldest version without a tag.
80         self["candidate"] = git_hash
81         self["candidate_version"] = version
82
83     if not self["candidate"] or not self["candidate_version"]:
84       print "Nothing found to tag."
85       self.CommonCleanup()
86       return True
87
88     print("Candidate for tagging is %s with version %s" %
89           (self["candidate"], self["candidate_version"]))
90
91
92 class GetLKGRs(Step):
93   MESSAGE = "Get the last lkgrs."
94
95   def RunStep(self):
96     revision_url = "https://v8-status.appspot.com/revisions?format=json"
97     status_json = self.ReadURL(revision_url, wait_plan=[5, 20])
98     self["lkgrs"] = [entry["revision"]
99                      for entry in json.loads(status_json) if entry["status"]]
100
101
102 class CalculateTagRevision(Step):
103   MESSAGE = "Calculate the revision to tag."
104
105   def LastLKGR(self, min_rev, max_rev):
106     """Finds the newest lkgr between min_rev (inclusive) and max_rev
107     (exclusive).
108     """
109     for lkgr in self["lkgrs"]:
110       # LKGRs are reverse sorted.
111       if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev):
112         return lkgr
113     return None
114
115   def RunStep(self):
116     # Get the lkgr after the tag candidate and before the next tag candidate.
117     candidate_svn = self.GitSVNFindSVNRev(self["candidate"])
118     if self["next"]:
119       next_svn = self.GitSVNFindSVNRev(self["next"])
120     else:
121       # Don't include the version change commit itself if there is no upper
122       # limit yet.
123       candidate_svn =  str(int(candidate_svn) + 1)
124       next_svn = sys.maxint
125     lkgr_svn = self.LastLKGR(candidate_svn, next_svn)
126
127     if not lkgr_svn:
128       print "There is no lkgr since the candidate version yet."
129       self.CommonCleanup()
130       return True
131
132     # Let's check if the lkgr is at least three hours old.
133     self["lkgr"] = self.GitSVNFindGitHash(lkgr_svn)
134     if not self["lkgr"]:
135       print "Couldn't find git hash for lkgr %s" % lkgr_svn
136       self.CommonCleanup()
137       return True
138
139     lkgr_utc_time = int(self.GitLog(n=1, format="%at", git_hash=self["lkgr"]))
140     current_utc_time = self._side_effect_handler.GetUTCStamp()
141
142     if current_utc_time < lkgr_utc_time + 10800:
143       print "Candidate lkgr %s is too recent for tagging." % lkgr_svn
144       self.CommonCleanup()
145       return True
146
147     print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"])
148
149
150 class MakeTag(Step):
151   MESSAGE = "Tag the version."
152
153   def RunStep(self):
154     if not self._options.dry_run:
155       self.GitReset(self["lkgr"])
156       self.GitSVNTag(self["candidate_version"])
157
158
159 class CleanUp(Step):
160   MESSAGE = "Clean up."
161
162   def RunStep(self):
163     self.CommonCleanup()
164
165
166 class AutoTag(ScriptsBase):
167   def _PrepareOptions(self, parser):
168     parser.add_argument("--dry_run", help="Don't tag the new version.",
169                         default=False, action="store_true")
170
171   def _ProcessOptions(self, options):  # pragma: no cover
172     if not options.dry_run and not options.author:
173       print "Specify your chromium.org email with -a"
174       return False
175     options.wait_for_lgtm = False
176     options.force_readline_defaults = True
177     options.force_upload = True
178     return True
179
180   def _Config(self):
181     return {
182       "BRANCHNAME": "auto-tag-v8",
183       "PERSISTFILE_BASENAME": "/tmp/v8-auto-tag-tempfile",
184     }
185
186   def _Steps(self):
187     return [
188       Preparation,
189       GetTags,
190       GetOldestUntaggedVersion,
191       GetLKGRs,
192       CalculateTagRevision,
193       MakeTag,
194       CleanUp,
195     ]
196
197
198 if __name__ == "__main__":  # pragma: no cover
199   sys.exit(AutoTag().Run())