diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | cf31fe9b4fb650b27e19f5d7ee7297e383660caf (patch) | |
tree | d04ca6a45d579dca5e5469606c48c405aee68f4b /subcmds/upload.py | |
download | git-repo-cf31fe9b4fb650b27e19f5d7ee7297e383660caf.tar.gz |
Initial Contributionv1.0
Diffstat (limited to 'subcmds/upload.py')
-rw-r--r-- | subcmds/upload.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/subcmds/upload.py b/subcmds/upload.py new file mode 100644 index 00000000..ad05050e --- /dev/null +++ b/subcmds/upload.py | |||
@@ -0,0 +1,180 @@ | |||
1 | # | ||
2 | # Copyright (C) 2008 The Android Open Source Project | ||
3 | # | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | # you may not use this file except in compliance with the License. | ||
6 | # You may obtain a copy of the License at | ||
7 | # | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | # | ||
10 | # Unless required by applicable law or agreed to in writing, software | ||
11 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | # See the License for the specific language governing permissions and | ||
14 | # limitations under the License. | ||
15 | |||
16 | import re | ||
17 | import sys | ||
18 | |||
19 | from command import InteractiveCommand | ||
20 | from editor import Editor | ||
21 | from error import UploadError | ||
22 | |||
23 | def _die(fmt, *args): | ||
24 | msg = fmt % args | ||
25 | print >>sys.stderr, 'error: %s' % msg | ||
26 | sys.exit(1) | ||
27 | |||
28 | class Upload(InteractiveCommand): | ||
29 | common = True | ||
30 | helpSummary = "Upload changes for code review" | ||
31 | helpUsage=""" | ||
32 | %prog [<project>]... | ||
33 | """ | ||
34 | helpDescription = """ | ||
35 | The '%prog' command is used to send changes to the Gerrit code | ||
36 | review system. It searches for changes in local projects that do | ||
37 | not yet exist in the corresponding remote repository. If multiple | ||
38 | changes are found, '%prog' opens an editor to allow the | ||
39 | user to choose which change to upload. After a successful upload, | ||
40 | repo prints the URL for the change in the Gerrit code review system. | ||
41 | |||
42 | '%prog' searches for uploadable changes in all projects listed | ||
43 | at the command line. Projects can be specified either by name, or | ||
44 | by a relative or absolute path to the project's local directory. If | ||
45 | no projects are specified, '%prog' will search for uploadable | ||
46 | changes in all projects listed in the manifest. | ||
47 | """ | ||
48 | |||
49 | def _SingleBranch(self, branch): | ||
50 | project = branch.project | ||
51 | name = branch.name | ||
52 | date = branch.date | ||
53 | list = branch.commits | ||
54 | |||
55 | print 'Upload project %s/:' % project.relpath | ||
56 | print ' branch %s (%2d commit%s, %s):' % ( | ||
57 | name, | ||
58 | len(list), | ||
59 | len(list) != 1 and 's' or '', | ||
60 | date) | ||
61 | for commit in list: | ||
62 | print ' %s' % commit | ||
63 | |||
64 | sys.stdout.write('(y/n)? ') | ||
65 | answer = sys.stdin.readline().strip() | ||
66 | if answer in ('y', 'Y', 'yes', '1', 'true', 't'): | ||
67 | self._UploadAndReport([branch]) | ||
68 | else: | ||
69 | _die("upload aborted by user") | ||
70 | |||
71 | def _MultipleBranches(self, pending): | ||
72 | projects = {} | ||
73 | branches = {} | ||
74 | |||
75 | script = [] | ||
76 | script.append('# Uncomment the branches to upload:') | ||
77 | for project, avail in pending: | ||
78 | script.append('#') | ||
79 | script.append('# project %s/:' % project.relpath) | ||
80 | |||
81 | b = {} | ||
82 | for branch in avail: | ||
83 | name = branch.name | ||
84 | date = branch.date | ||
85 | list = branch.commits | ||
86 | |||
87 | if b: | ||
88 | script.append('#') | ||
89 | script.append('# branch %s (%2d commit%s, %s):' % ( | ||
90 | name, | ||
91 | len(list), | ||
92 | len(list) != 1 and 's' or '', | ||
93 | date)) | ||
94 | for commit in list: | ||
95 | script.append('# %s' % commit) | ||
96 | b[name] = branch | ||
97 | |||
98 | projects[project.relpath] = project | ||
99 | branches[project.name] = b | ||
100 | script.append('') | ||
101 | |||
102 | script = Editor.EditString("\n".join(script)).split("\n") | ||
103 | |||
104 | project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$') | ||
105 | branch_re = re.compile(r'^\s*branch\s*([^\s(]+)\s*\(.*') | ||
106 | |||
107 | project = None | ||
108 | todo = [] | ||
109 | |||
110 | for line in script: | ||
111 | m = project_re.match(line) | ||
112 | if m: | ||
113 | name = m.group(1) | ||
114 | project = projects.get(name) | ||
115 | if not project: | ||
116 | _die('project %s not available for upload', name) | ||
117 | continue | ||
118 | |||
119 | m = branch_re.match(line) | ||
120 | if m: | ||
121 | name = m.group(1) | ||
122 | if not project: | ||
123 | _die('project for branch %s not in script', name) | ||
124 | branch = branches[project.name].get(name) | ||
125 | if not branch: | ||
126 | _die('branch %s not in %s', name, project.relpath) | ||
127 | todo.append(branch) | ||
128 | if not todo: | ||
129 | _die("nothing uncommented for upload") | ||
130 | self._UploadAndReport(todo) | ||
131 | |||
132 | def _UploadAndReport(self, todo): | ||
133 | have_errors = False | ||
134 | for branch in todo: | ||
135 | try: | ||
136 | branch.UploadForReview() | ||
137 | branch.uploaded = True | ||
138 | except UploadError, e: | ||
139 | branch.error = e | ||
140 | branch.uploaded = False | ||
141 | have_errors = True | ||
142 | |||
143 | print >>sys.stderr, '' | ||
144 | print >>sys.stderr, '--------------------------------------------' | ||
145 | |||
146 | if have_errors: | ||
147 | for branch in todo: | ||
148 | if not branch.uploaded: | ||
149 | print >>sys.stderr, '[FAILED] %-15s %-15s (%s)' % ( | ||
150 | branch.project.relpath + '/', \ | ||
151 | branch.name, \ | ||
152 | branch.error) | ||
153 | print >>sys.stderr, '' | ||
154 | |||
155 | for branch in todo: | ||
156 | if branch.uploaded: | ||
157 | print >>sys.stderr, '[OK ] %-15s %s' % ( | ||
158 | branch.project.relpath + '/', | ||
159 | branch.name) | ||
160 | print >>sys.stderr, '%s' % branch.tip_url | ||
161 | print >>sys.stderr, '' | ||
162 | |||
163 | if have_errors: | ||
164 | sys.exit(1) | ||
165 | |||
166 | def Execute(self, opt, args): | ||
167 | project_list = self.GetProjects(args) | ||
168 | pending = [] | ||
169 | |||
170 | for project in project_list: | ||
171 | avail = project.GetUploadableBranches() | ||
172 | if avail: | ||
173 | pending.append((project, avail)) | ||
174 | |||
175 | if not pending: | ||
176 | print >>sys.stdout, "no branches ready for upload" | ||
177 | elif len(pending) == 1 and len(pending[0][1]) == 1: | ||
178 | self._SingleBranch(pending[0][1][0]) | ||
179 | else: | ||
180 | self._MultipleBranches(pending) | ||