Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / tools / push-to-trunk / bump_up_version.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 """
7 Script for auto-increasing the version on bleeding_edge.
8
9 The script can be run regularly by a cron job. It will increase the build
10 level of the version on bleeding_edge if:
11 - the lkgr version is smaller than the version of the latest revision,
12 - the lkgr version is not a version change itself,
13 - the tree is not closed for maintenance.
14
15 The new version will be the maximum of the bleeding_edge and trunk versions +1.
16 E.g. latest bleeding_edge version: 3.22.11.0 and latest trunk 3.23.0.0 gives
17 the new version 3.23.1.0.
18
19 This script requires a depot tools git checkout. I.e. 'fetch v8'.
20 """
21
22 import argparse
23 import os
24 import sys
25
26 from common_includes import *
27
28 VERSION_BRANCH = "auto-bump-up-version"
29
30
31 class Preparation(Step):
32   MESSAGE = "Preparation."
33
34   def RunStep(self):
35     # Check for a clean workdir.
36     if not self.GitIsWorkdirClean():  # pragma: no cover
37       # This is in case a developer runs this script on a dirty tree.
38       self.GitStash()
39
40     # TODO(machenbach): This should be called master after the git switch.
41     self.GitCheckout("bleeding_edge")
42
43     self.GitPull()
44
45     # Ensure a clean version branch.
46     self.DeleteBranch(VERSION_BRANCH)
47
48
49 class GetCurrentBleedingEdgeVersion(Step):
50   MESSAGE = "Get latest bleeding edge version."
51
52   def RunStep(self):
53     # TODO(machenbach): This should be called master after the git switch.
54     self.GitCheckout("bleeding_edge")
55
56     # Store latest version and revision.
57     self.ReadAndPersistVersion()
58     self["latest_version"] = self.ArrayToVersion("")
59     self["latest"] = self.GitLog(n=1, format="%H")
60     print "Bleeding edge version: %s" % self["latest_version"]
61
62
63 # This step is pure paranoia. It forbids the script to continue if the last
64 # commit changed version.cc. Just in case the other bailout has a bug, this
65 # prevents the script from continuously commiting version changes.
66 class LastChangeBailout(Step):
67   MESSAGE = "Stop script if the last change modified the version."
68
69   def RunStep(self):
70     if VERSION_FILE in self.GitChangedFiles(self["latest"]):
71       print "Stop due to recent version change."
72       return True
73
74
75 # TODO(machenbach): Implement this for git.
76 class FetchLKGR(Step):
77   MESSAGE = "Fetching V8 LKGR."
78
79   def RunStep(self):
80     lkgr_url = "https://v8-status.appspot.com/lkgr"
81     self["lkgr_svn"] = self.ReadURL(lkgr_url, wait_plan=[5])
82
83
84 # TODO(machenbach): Implement this for git. With a git lkgr we could simply
85 # checkout that revision. With svn, we have to search backwards until that
86 # revision is found.
87 class GetLKGRVersion(Step):
88   MESSAGE = "Get bleeding edge lkgr version."
89
90   def RunStep(self):
91     self.GitCheckout("bleeding_edge")
92     # If the commit was made from svn, there is a mapping entry in the commit
93     # message.
94     self["lkgr"] = self.GitLog(
95         grep="^git-svn-id: [^@]*@%s [A-Za-z0-9-]*$" % self["lkgr_svn"],
96         format="%H")
97
98     # FIXME(machenbach): http://crbug.com/391712 can lead to svn lkgrs on the
99     # trunk branch (rarely).
100     if not self["lkgr"]:  # pragma: no cover
101       self.Die("No git hash found for svn lkgr.")
102
103     self.GitCreateBranch(VERSION_BRANCH, self["lkgr"])
104     self.ReadAndPersistVersion("lkgr_")
105     self["lkgr_version"] = self.ArrayToVersion("lkgr_")
106     print "LKGR version: %s" % self["lkgr_version"]
107
108     # Ensure a clean version branch.
109     self.GitCheckout("bleeding_edge")
110     self.DeleteBranch(VERSION_BRANCH)
111
112
113 class LKGRVersionUpToDateBailout(Step):
114   MESSAGE = "Stop script if the lkgr has a renewed version."
115
116   def RunStep(self):
117     # If a version-change commit becomes the lkgr, don't bump up the version
118     # again.
119     if VERSION_FILE in self.GitChangedFiles(self["lkgr"]):
120       print "Stop because the lkgr is a version change itself."
121       return True
122
123     # Don't bump up the version if it got updated already after the lkgr.
124     if SortingKey(self["lkgr_version"]) < SortingKey(self["latest_version"]):
125       print("Stop because the latest version already changed since the lkgr "
126             "version.")
127       return True
128
129
130 class GetTrunkVersion(Step):
131   MESSAGE = "Get latest trunk version."
132
133   def RunStep(self):
134     # TODO(machenbach): This should be called trunk after the git switch.
135     self.GitCheckout("master")
136     self.GitPull()
137     self.ReadAndPersistVersion("trunk_")
138     self["trunk_version"] = self.ArrayToVersion("trunk_")
139     print "Trunk version: %s" % self["trunk_version"]
140
141
142 class CalculateVersion(Step):
143   MESSAGE = "Calculate the new version."
144
145   def RunStep(self):
146     if self["lkgr_build"] == "9999":  # pragma: no cover
147       # If version control on bleeding edge was switched off, just use the last
148       # trunk version.
149       self["lkgr_version"] = self["trunk_version"]
150
151     # The new version needs to be greater than the max on bleeding edge and
152     # trunk.
153     max_version = max(self["trunk_version"],
154                       self["lkgr_version"],
155                       key=SortingKey)
156
157     # Strip off possible leading zeros.
158     self["new_major"], self["new_minor"], self["new_build"], _ = (
159         map(str, map(int, max_version.split("."))))
160
161     self["new_build"] = str(int(self["new_build"]) + 1)
162     self["new_patch"] = "0"
163
164     self["new_version"] = ("%s.%s.%s.0" %
165         (self["new_major"], self["new_minor"], self["new_build"]))
166     print "New version is %s" % self["new_version"]
167
168     if self._options.dry_run:  # pragma: no cover
169       print "Dry run, skipping version change."
170       return True
171
172
173 class CheckTreeStatus(Step):
174   MESSAGE = "Checking v8 tree status message."
175
176   def RunStep(self):
177     status_url = "https://v8-status.appspot.com/current?format=json"
178     status_json = self.ReadURL(status_url, wait_plan=[5, 20, 300, 300])
179     message = json.loads(status_json)["message"]
180     if re.search(r"maintenance|no commits", message, flags=re.I):
181       print "Skip version change by tree status: \"%s\"" % message
182       return True
183
184
185 class ChangeVersion(Step):
186   MESSAGE = "Bump up the version."
187
188   def RunStep(self):
189     self.GitCreateBranch(VERSION_BRANCH, "bleeding_edge")
190
191     self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_")
192
193     try:
194       msg = "[Auto-roll] Bump up version to %s" % self["new_version"]
195       self.GitCommit("%s\n\nTBR=%s" % (msg, self._options.author),
196                      author=self._options.author)
197       if self._options.svn:
198         self.SVNCommit("branches/bleeding_edge", msg)
199       else:
200         self.GitUpload(author=self._options.author,
201                        force=self._options.force_upload,
202                        bypass_hooks=True)
203         self.GitDCommit()
204       print "Successfully changed the version."
205     finally:
206       # Clean up.
207       self.GitCheckout("bleeding_edge")
208       self.DeleteBranch(VERSION_BRANCH)
209
210
211 class BumpUpVersion(ScriptsBase):
212   def _PrepareOptions(self, parser):
213     parser.add_argument("--dry_run", help="Don't commit the new version.",
214                         default=False, action="store_true")
215
216   def _ProcessOptions(self, options):  # pragma: no cover
217     if not options.dry_run and not options.author:
218       print "Specify your chromium.org email with -a"
219       return False
220     options.wait_for_lgtm = False
221     options.force_readline_defaults = True
222     options.force_upload = True
223     return True
224
225   def _Config(self):
226     return {
227       "PERSISTFILE_BASENAME": "/tmp/v8-bump-up-version-tempfile",
228     }
229
230   def _Steps(self):
231     return [
232       Preparation,
233       GetCurrentBleedingEdgeVersion,
234       LastChangeBailout,
235       FetchLKGR,
236       GetLKGRVersion,
237       LKGRVersionUpToDateBailout,
238       GetTrunkVersion,
239       CalculateVersion,
240       CheckTreeStatus,
241       ChangeVersion,
242     ]
243
244 if __name__ == "__main__":  # pragma: no cover
245   sys.exit(BumpUpVersion().Run())