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

Side by Side Diff: tools/push-to-trunk/common_includes.py

Issue 540973002: Add cwd to all shell commands in auto roll scripts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/push-to-trunk/chromium_roll.py ('k') | tools/push-to-trunk/git_recipes.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 the V8 project authors. All rights reserved. 2 # Copyright 2013 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following 10 # copyright notice, this list of conditions and the following
(...skipping 11 matching lines...) Expand all
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import argparse 29 import argparse
30 import datetime 30 import datetime
31 import httplib 31 import httplib
32 import glob
32 import imp 33 import imp
33 import json 34 import json
34 import os 35 import os
35 import re 36 import re
37 import shutil
36 import subprocess 38 import subprocess
37 import sys 39 import sys
38 import textwrap 40 import textwrap
39 import time 41 import time
40 import urllib 42 import urllib
41 import urllib2 43 import urllib2
42 44
43 from git_recipes import GitRecipesMixin 45 from git_recipes import GitRecipesMixin
44 from git_recipes import GitFailedException 46 from git_recipes import GitFailedException
45 47
46 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME" 48 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME"
47 BRANCHNAME = "BRANCHNAME" 49 BRANCHNAME = "BRANCHNAME"
48 DOT_GIT_LOCATION = "DOT_GIT_LOCATION" 50 DOT_GIT_LOCATION = "DOT_GIT_LOCATION"
49 VERSION_FILE = "VERSION_FILE" 51 VERSION_FILE = "VERSION_FILE"
50 CHANGELOG_FILE = "CHANGELOG_FILE" 52 CHANGELOG_FILE = "CHANGELOG_FILE"
51 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE" 53 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE"
52 COMMITMSG_FILE = "COMMITMSG_FILE" 54 COMMITMSG_FILE = "COMMITMSG_FILE"
53 PATCH_FILE = "PATCH_FILE" 55 PATCH_FILE = "PATCH_FILE"
54 56
57 # V8 base directory.
58 DEFAULT_CWD = os.path.dirname(
59 os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
60
55 61
56 def TextToFile(text, file_name): 62 def TextToFile(text, file_name):
57 with open(file_name, "w") as f: 63 with open(file_name, "w") as f:
58 f.write(text) 64 f.write(text)
59 65
60 66
61 def AppendToFile(text, file_name): 67 def AppendToFile(text, file_name):
62 with open(file_name, "a") as f: 68 with open(file_name, "a") as f:
63 f.write(text) 69 f.write(text)
64 70
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 version_keys = map(int, version.split(".")) 182 version_keys = map(int, version.split("."))
177 # Fill up to full version numbers to normalize comparison. 183 # Fill up to full version numbers to normalize comparison.
178 while len(version_keys) < 4: # pragma: no cover 184 while len(version_keys) < 4: # pragma: no cover
179 version_keys.append(0) 185 version_keys.append(0)
180 # Fill digits. 186 # Fill digits.
181 return ".".join(map("{0:04d}".format, version_keys)) 187 return ".".join(map("{0:04d}".format, version_keys))
182 188
183 189
184 # Some commands don't like the pipe, e.g. calling vi from within the script or 190 # Some commands don't like the pipe, e.g. calling vi from within the script or
185 # from subscripts like git cl upload. 191 # from subscripts like git cl upload.
186 def Command(cmd, args="", prefix="", pipe=True): 192 def Command(cmd, args="", prefix="", pipe=True, cwd=None):
193 cwd = cwd or os.getcwd()
187 # TODO(machenbach): Use timeout. 194 # TODO(machenbach): Use timeout.
188 cmd_line = "%s %s %s" % (prefix, cmd, args) 195 cmd_line = "%s %s %s" % (prefix, cmd, args)
189 print "Command: %s" % cmd_line 196 print "Command: %s" % cmd_line
197 print "in %s" % cwd
190 sys.stdout.flush() 198 sys.stdout.flush()
191 try: 199 try:
192 if pipe: 200 if pipe:
193 return subprocess.check_output(cmd_line, shell=True) 201 return subprocess.check_output(cmd_line, shell=True, cwd=cwd)
194 else: 202 else:
195 return subprocess.check_call(cmd_line, shell=True) 203 return subprocess.check_call(cmd_line, shell=True, cwd=cwd)
196 except subprocess.CalledProcessError: 204 except subprocess.CalledProcessError:
197 return None 205 return None
198 finally: 206 finally:
199 sys.stdout.flush() 207 sys.stdout.flush()
200 sys.stderr.flush() 208 sys.stderr.flush()
201 209
202 210
203 # Wrapper for side effects. 211 # Wrapper for side effects.
204 class SideEffectHandler(object): # pragma: no cover 212 class SideEffectHandler(object): # pragma: no cover
205 def Call(self, fun, *args, **kwargs): 213 def Call(self, fun, *args, **kwargs):
206 return fun(*args, **kwargs) 214 return fun(*args, **kwargs)
207 215
208 def Command(self, cmd, args="", prefix="", pipe=True): 216 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
209 return Command(cmd, args, prefix, pipe) 217 return Command(cmd, args, prefix, pipe, cwd=cwd)
210 218
211 def ReadLine(self): 219 def ReadLine(self):
212 return sys.stdin.readline().strip() 220 return sys.stdin.readline().strip()
213 221
214 def ReadURL(self, url, params=None): 222 def ReadURL(self, url, params=None):
215 # pylint: disable=E1121 223 # pylint: disable=E1121
216 url_fh = urllib2.urlopen(url, params, 60) 224 url_fh = urllib2.urlopen(url, params, 60)
217 try: 225 try:
218 return url_fh.read() 226 return url_fh.read()
219 finally: 227 finally:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 264
257 class Step(GitRecipesMixin): 265 class Step(GitRecipesMixin):
258 def __init__(self, text, requires, number, config, state, options, handler): 266 def __init__(self, text, requires, number, config, state, options, handler):
259 self._text = text 267 self._text = text
260 self._requires = requires 268 self._requires = requires
261 self._number = number 269 self._number = number
262 self._config = config 270 self._config = config
263 self._state = state 271 self._state = state
264 self._options = options 272 self._options = options
265 self._side_effect_handler = handler 273 self._side_effect_handler = handler
274
275 # The testing configuration might set a different default cwd.
276 self.default_cwd = self._config.get("DEFAULT_CWD") or DEFAULT_CWD
277
266 assert self._number >= 0 278 assert self._number >= 0
267 assert self._config is not None 279 assert self._config is not None
268 assert self._state is not None 280 assert self._state is not None
269 assert self._side_effect_handler is not None 281 assert self._side_effect_handler is not None
270 282
271 def __getitem__(self, key): 283 def __getitem__(self, key):
272 # Convenience method to allow direct [] access on step classes for 284 # Convenience method to allow direct [] access on step classes for
273 # manipulating the backed state dict. 285 # manipulating the backed state dict.
274 return self._state[key] 286 return self._state[key]
275 287
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 return result 346 return result
335 347
336 def ReadLine(self, default=None): 348 def ReadLine(self, default=None):
337 # Don't prompt in forced mode. 349 # Don't prompt in forced mode.
338 if self._options.force_readline_defaults and default is not None: 350 if self._options.force_readline_defaults and default is not None:
339 print "%s (forced)" % default 351 print "%s (forced)" % default
340 return default 352 return default
341 else: 353 else:
342 return self._side_effect_handler.ReadLine() 354 return self._side_effect_handler.ReadLine()
343 355
344 def Git(self, args="", prefix="", pipe=True, retry_on=None): 356 def Command(self, name, args, cwd=None):
345 cmd = lambda: self._side_effect_handler.Command("git", args, prefix, pipe) 357 cmd = lambda: self._side_effect_handler.Command(
358 name, args, "", True, cwd=cwd or self.default_cwd)
359 return self.Retry(cmd, None, [5])
360
361 def Git(self, args="", prefix="", pipe=True, retry_on=None, cwd=None):
362 cmd = lambda: self._side_effect_handler.Command(
363 "git", args, prefix, pipe, cwd=cwd or self.default_cwd)
346 result = self.Retry(cmd, retry_on, [5, 30]) 364 result = self.Retry(cmd, retry_on, [5, 30])
347 if result is None: 365 if result is None:
348 raise GitFailedException("'git %s' failed." % args) 366 raise GitFailedException("'git %s' failed." % args)
349 return result 367 return result
350 368
351 def SVN(self, args="", prefix="", pipe=True, retry_on=None): 369 def SVN(self, args="", prefix="", pipe=True, retry_on=None, cwd=None):
352 cmd = lambda: self._side_effect_handler.Command("svn", args, prefix, pipe) 370 cmd = lambda: self._side_effect_handler.Command(
371 "svn", args, prefix, pipe, cwd=cwd or self.default_cwd)
353 return self.Retry(cmd, retry_on, [5, 30]) 372 return self.Retry(cmd, retry_on, [5, 30])
354 373
355 def Editor(self, args): 374 def Editor(self, args):
356 if self._options.requires_editor: 375 if self._options.requires_editor:
357 return self._side_effect_handler.Command(os.environ["EDITOR"], args, 376 return self._side_effect_handler.Command(
358 pipe=False) 377 os.environ["EDITOR"],
378 args,
379 pipe=False,
380 cwd=self.default_cwd)
359 381
360 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None): 382 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None):
361 wait_plan = wait_plan or [3, 60, 600] 383 wait_plan = wait_plan or [3, 60, 600]
362 cmd = lambda: self._side_effect_handler.ReadURL(url, params) 384 cmd = lambda: self._side_effect_handler.ReadURL(url, params)
363 return self.Retry(cmd, retry_on, wait_plan) 385 return self.Retry(cmd, retry_on, wait_plan)
364 386
365 def GetDate(self): 387 def GetDate(self):
366 return self._side_effect_handler.GetDate() 388 return self._side_effect_handler.GetDate()
367 389
368 def Die(self, msg=""): 390 def Die(self, msg=""):
(...skipping 23 matching lines...) Expand all
392 msg = "Can't continue. Please delete branch %s and try again." % name 414 msg = "Can't continue. Please delete branch %s and try again." % name
393 self.Die(msg) 415 self.Die(msg)
394 416
395 def InitialEnvironmentChecks(self): 417 def InitialEnvironmentChecks(self):
396 # Cancel if this is not a git checkout. 418 # Cancel if this is not a git checkout.
397 if not os.path.exists(self._config[DOT_GIT_LOCATION]): # pragma: no cover 419 if not os.path.exists(self._config[DOT_GIT_LOCATION]): # pragma: no cover
398 self.Die("This is not a git checkout, this script won't work for you.") 420 self.Die("This is not a git checkout, this script won't work for you.")
399 421
400 # Cancel if EDITOR is unset or not executable. 422 # Cancel if EDITOR is unset or not executable.
401 if (self._options.requires_editor and (not os.environ.get("EDITOR") or 423 if (self._options.requires_editor and (not os.environ.get("EDITOR") or
402 Command("which", os.environ["EDITOR"]) is None)): # pragma: no cover 424 self.Command(
425 "which", os.environ["EDITOR"]) is None)): # pragma: no cover
403 self.Die("Please set your EDITOR environment variable, you'll need it.") 426 self.Die("Please set your EDITOR environment variable, you'll need it.")
404 427
405 def CommonPrepare(self): 428 def CommonPrepare(self):
406 # Check for a clean workdir. 429 # Check for a clean workdir.
407 if not self.GitIsWorkdirClean(): # pragma: no cover 430 if not self.GitIsWorkdirClean(): # pragma: no cover
408 self.Die("Workspace is not clean. Please commit or undo your changes.") 431 self.Die("Workspace is not clean. Please commit or undo your changes.")
409 432
410 # Persist current branch. 433 # Persist current branch.
411 self["current_branch"] = self.GitCurrentBranch() 434 self["current_branch"] = self.GitCurrentBranch()
412 435
413 # Fetch unfetched revisions. 436 # Fetch unfetched revisions.
414 self.GitSVNFetch() 437 self.GitSVNFetch()
415 438
416 def PrepareBranch(self): 439 def PrepareBranch(self):
417 # Delete the branch that will be created later if it exists already. 440 # Delete the branch that will be created later if it exists already.
418 self.DeleteBranch(self._config[BRANCHNAME]) 441 self.DeleteBranch(self._config[BRANCHNAME])
419 442
420 def CommonCleanup(self): 443 def CommonCleanup(self):
421 self.GitCheckout(self["current_branch"]) 444 self.GitCheckout(self["current_branch"])
422 if self._config[BRANCHNAME] != self["current_branch"]: 445 if self._config[BRANCHNAME] != self["current_branch"]:
423 self.GitDeleteBranch(self._config[BRANCHNAME]) 446 self.GitDeleteBranch(self._config[BRANCHNAME])
424 447
425 # Clean up all temporary files. 448 # Clean up all temporary files.
426 Command("rm", "-f %s*" % self._config[PERSISTFILE_BASENAME]) 449 for f in glob.iglob("%s*" % self._config[PERSISTFILE_BASENAME]):
450 if os.path.isfile(f):
451 os.remove(f)
452 if os.path.isdir(f):
453 shutil.rmtree(f)
427 454
428 def ReadAndPersistVersion(self, prefix=""): 455 def ReadAndPersistVersion(self, prefix=""):
429 def ReadAndPersist(var_name, def_name): 456 def ReadAndPersist(var_name, def_name):
430 match = re.match(r"^#define %s\s+(\d*)" % def_name, line) 457 match = re.match(r"^#define %s\s+(\d*)" % def_name, line)
431 if match: 458 if match:
432 value = match.group(1) 459 value = match.group(1)
433 self["%s%s" % (prefix, var_name)] = value 460 self["%s%s" % (prefix, var_name)] = value
434 for line in LinesInFile(self._config[VERSION_FILE]): 461 for line in LinesInFile(self._config[VERSION_FILE]):
435 for (var_name, def_name) in [("major", "MAJOR_VERSION"), 462 for (var_name, def_name) in [("major", "MAJOR_VERSION"),
436 ("minor", "MINOR_VERSION"), 463 ("minor", "MINOR_VERSION"),
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 help="Path to the script mapping google accounts.") 627 help="Path to the script mapping google accounts.")
601 parser.add_argument("-r", "--reviewer", default="", 628 parser.add_argument("-r", "--reviewer", default="",
602 help="The account name to be used for reviews.") 629 help="The account name to be used for reviews.")
603 parser.add_argument("--sheriff", default=False, action="store_true", 630 parser.add_argument("--sheriff", default=False, action="store_true",
604 help=("Determine current sheriff to review CLs. On " 631 help=("Determine current sheriff to review CLs. On "
605 "success, this will overwrite the reviewer " 632 "success, this will overwrite the reviewer "
606 "option.")) 633 "option."))
607 parser.add_argument("-s", "--step", 634 parser.add_argument("-s", "--step",
608 help="Specify the step where to start work. Default: 0.", 635 help="Specify the step where to start work. Default: 0.",
609 default=0, type=int) 636 default=0, type=int)
610
611 self._PrepareOptions(parser) 637 self._PrepareOptions(parser)
612 638
613 if args is None: # pragma: no cover 639 if args is None: # pragma: no cover
614 options = parser.parse_args() 640 options = parser.parse_args()
615 else: 641 else:
616 options = parser.parse_args(args) 642 options = parser.parse_args(args)
617 643
618 # Process common options. 644 # Process common options.
619 if options.step < 0: # pragma: no cover 645 if options.step < 0: # pragma: no cover
620 print "Bad step number %d" % options.step 646 print "Bad step number %d" % options.step
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 for (number, step_class) in enumerate(step_classes): 680 for (number, step_class) in enumerate(step_classes):
655 steps.append(MakeStep(step_class, number, self._state, self._config, 681 steps.append(MakeStep(step_class, number, self._state, self._config,
656 options, self._side_effect_handler)) 682 options, self._side_effect_handler))
657 for step in steps[options.step:]: 683 for step in steps[options.step:]:
658 if step.Run(): 684 if step.Run():
659 return 0 685 return 0
660 return 0 686 return 0
661 687
662 def Run(self, args=None): 688 def Run(self, args=None):
663 return self.RunSteps(self._Steps(), args) 689 return self.RunSteps(self._Steps(), args)
OLDNEW
« no previous file with comments | « tools/push-to-trunk/chromium_roll.py ('k') | tools/push-to-trunk/git_recipes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698