OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2012 The Chromium 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 """ This module contains miscellaneous tools used by the buildbot scripts. """ | |
7 | |
8 import os | |
9 | |
10 from git_utils import GIT | |
11 import shell_utils | |
12 | |
13 | |
14 # Absolute path to the root of this Skia buildbot checkout. | |
15 BUILDBOT_PATH = os.path.realpath(os.path.join( | |
16 os.path.dirname(os.path.abspath(__file__)), | |
17 os.pardir, os.pardir, os.pardir)) | |
borenet
2014/06/20 16:39:04
This should probably be removed, but there are thi
rmistry
2014/06/20 16:44:03
SGTM
borenet
2014/06/20 16:55:02
If it's okay with you, I'll wait until we start de
| |
18 | |
19 | |
20 def ArgsToDict(argv): | |
21 """ Collect command-line arguments of the form '--key value' into a | |
22 dictionary. Fail if the arguments do not fit this format. """ | |
23 dictionary = {} | |
24 PREFIX = '--' | |
25 # Expect the first arg to be the path to the script, which we don't want. | |
26 argv = argv[1:] | |
27 while argv: | |
28 if argv[0].startswith(PREFIX): | |
29 dictionary[argv[0][len(PREFIX):]] = argv[1] | |
30 argv = argv[2:] | |
31 else: | |
32 raise Exception('Malformed input: %s' % argv) | |
33 return dictionary | |
34 | |
35 | |
36 def ConfirmOptionsSet(name_value_dict): | |
37 """Raise an exception if any of the given command-line options were not set. | |
38 | |
39 name_value_dict: dictionary mapping option names to option values | |
40 """ | |
41 for (name, value) in name_value_dict.iteritems(): | |
42 if value is None: | |
43 raise Exception('missing command-line option %s; rerun with --help' % | |
44 name) | |
45 | |
46 | |
47 def GetAbsPath(relative_path): | |
48 """My own implementation of os.path.abspath() that better handles paths | |
49 which approach Window's 260-character limit. | |
50 See https://code.google.com/p/skia/issues/detail?id=674 | |
51 | |
52 This implementation adds path components one at a time, resolving the | |
53 absolute path each time, to take advantage of any chdirs into outer | |
54 directories that will shorten the total path length. | |
55 | |
56 TODO(epoger): share a single implementation with bench_graph_svg.py, instead | |
57 of pasting this same code into both files.""" | |
58 if os.path.isabs(relative_path): | |
59 return relative_path | |
60 path_parts = relative_path.split(os.sep) | |
61 abs_path = os.path.abspath('.') | |
62 for path_part in path_parts: | |
63 abs_path = os.path.abspath(os.path.join(abs_path, path_part)) | |
64 return abs_path | |
65 | |
66 | |
67 class ChDir(object): | |
68 """Enter and exit the given directory appropriately.""" | |
69 | |
70 def __init__(self, directory): | |
71 """Instantiate the ChDir. | |
72 | |
73 Args: | |
74 directory: string; the directory to enter. | |
75 """ | |
76 self._destination = directory | |
77 self._origin = None | |
78 | |
79 def __enter__(self): | |
80 """Change to the destination directory. | |
81 | |
82 Does not check whether the directory exists. | |
83 """ | |
84 self._origin = os.getcwd() | |
85 print 'chdir %s' % self._destination | |
86 os.chdir(self._destination) | |
87 | |
88 def __exit__(self, *args): | |
89 """Change back to the original directory.""" | |
90 print 'chdir %s' % self._origin | |
91 os.chdir(self._origin) | |
92 | |
93 | |
94 class GitBranch(object): | |
95 """Class to manage git branches. | |
96 | |
97 This class allows one to create a new branch in a repository to make changes, | |
98 then it commits the changes, switches to master branch, and deletes the | |
99 created temporary branch upon exit. | |
100 """ | |
101 def __init__(self, branch_name, commit_msg, upload=True, commit_queue=False): | |
102 self._branch_name = branch_name | |
103 self._commit_msg = commit_msg | |
104 self._upload = upload | |
105 self._commit_queue = commit_queue | |
106 self._patch_set = 0 | |
107 | |
108 def __enter__(self): | |
109 shell_utils.run([GIT, 'reset', '--hard', 'HEAD']) | |
110 shell_utils.run([GIT, 'checkout', 'master']) | |
111 if self._branch_name in shell_utils.run([GIT, 'branch']): | |
112 shell_utils.run([GIT, 'branch', '-D', self._branch_name]) | |
113 shell_utils.run([GIT, 'checkout', '-b', self._branch_name, | |
114 '-t', 'origin/master']) | |
115 return self | |
116 | |
117 def commit_and_upload(self, use_commit_queue=False): | |
118 shell_utils.run([GIT, 'commit', '-a', '-m', | |
119 self._commit_msg]) | |
120 upload_cmd = [GIT, 'cl', 'upload', '-f', '--bypass-hooks', | |
121 '--bypass-watchlists'] | |
122 self._patch_set += 1 | |
123 if self._patch_set > 1: | |
124 upload_cmd.extend(['-t', 'Patch set %d' % self._patch_set]) | |
125 if use_commit_queue: | |
126 upload_cmd.append('--use-commit-queue') | |
127 shell_utils.run(upload_cmd) | |
128 | |
129 def __exit__(self, exc_type, _value, _traceback): | |
130 if self._upload: | |
131 # Only upload if no error occurred. | |
132 try: | |
133 if exc_type is None: | |
134 self.commit_and_upload(use_commit_queue=self._commit_queue) | |
135 finally: | |
136 shell_utils.run([GIT, 'checkout', 'master']) | |
137 shell_utils.run([GIT, 'branch', '-D', self._branch_name]) | |
138 | |
OLD | NEW |