Mercurial > hg > gut
annotate gut/main.py @ 8:0c0ade65b9f9
fix errors
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Wed, 21 Jul 2010 16:37:23 -0700 |
parents | 67ec22ce347c |
children | b344537797de |
rev | line source |
---|---|
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
2 """ |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
3 a workflow for git |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
4 """ |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
5 |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
6 import os |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
7 import subprocess |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
8 import sys |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
9 |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
10 from command import CommandParser |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
11 |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
12 def call(command, **kw): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
13 if isinstance(command, basestring): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
14 kw['shell'] = True |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
15 output = kw.pop('output', True) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
16 if output or kw.pop('pipe', False): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
17 kw['stdout'] = subprocess.PIPE |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
18 kw['stderr'] = subprocess.PIPE |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
19 check = kw.pop('check', True) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
20 process = subprocess.Popen(command, **kw) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
21 stdout, stderr = process.communicate() |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
22 code = process.poll() |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
23 if check and code: |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
24 if isinstance(command, basestring): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
25 cmdstr = command |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
26 else: |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
27 cmdstr = ' '.join(command) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
28 raise SystemExit("Command `%s` exited with code %d" % (cmdstr, code)) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
29 if output: |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
30 print stdout |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
31 print stderr |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
32 return dict(stdout=stdout, stderr=stderr, code=code) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
33 |
2 | 34 def fake_call(command, **kw): |
35 if isinstance(command, basestring): | |
36 print command | |
37 else: | |
38 print ' '.join(command) | |
39 | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
40 class gut(object): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
41 """ |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
42 a workflow for git |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
43 """ |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
44 |
6 | 45 def __init__(self, remote=None, simulate=False, branches=('master',)): |
2 | 46 """ |
47 - remote: name of the remote repository in .git/config | |
48 - simulate: print what calls will be used but don't run them | |
6 | 49 - branches: branches to apply to |
2 | 50 """ |
6 | 51 |
8 | 52 self.simulate = simulate |
53 | |
6 | 54 # sanity check |
7 | 55 try: |
56 self.root() | |
57 except SystemExit: | |
58 print "Not in a git repository" | |
59 sys.exit(1) | |
6 | 60 |
2 | 61 self.remote = remote |
6 | 62 self.branches = branches |
2 | 63 if simulate: |
64 globals()['call'] = fake_call | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
65 |
6 | 66 |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
67 def update(self): |
6 | 68 """update the master""" |
69 branch = self.branch() | |
70 if self.simulate: | |
71 branch = '<branch>' | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
72 call(['git', 'checkout', 'master']) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
73 call(['git', 'pull', 'origin', 'master']) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
74 if self.remote: |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
75 call(['git', 'pull', self.remote, 'master']) |
6 | 76 call(['git', 'checkout', branch]) |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
77 |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
78 def feature(self, name): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
79 """make a new feature branch""" |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
80 call(['git', 'checkout', 'master']) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
81 call(['git', 'checkout', '-b', name]) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
82 call(['git', 'push', 'origin', name]) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
83 |
6 | 84 def patch(self, output=None, logfile=None): |
85 """ | |
86 generate a patch for review | |
87 - output: name of patch | |
88 - logfile: name of file to output the log to [DEFAULT: stdout] | |
89 """ | |
90 self.update() | |
2 | 91 diff = call(['git', 'diff', 'master'], pipe=True, output=False) |
92 log = call(['git', 'log', 'master..'], pipe=True, output=False) | |
93 if self.simulate: | |
94 return | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
95 if not output: |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
96 output = self.branch() + '.diff' |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
97 diff = diff['stdout'] |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
98 log = log['stdout'] |
4
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
99 |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
100 # format the log |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
101 lines = [] |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
102 oldline = None |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
103 for line in log.splitlines(): |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
104 if not line: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
105 continue |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
106 if line[0].strip(): |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
107 if oldline: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
108 lines.append(oldline) |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
109 oldline = None |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
110 incomment = False |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
111 continue |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
112 line = line.strip() |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
113 if line.startswith('*'): |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
114 if oldline: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
115 lines.append(oldline) |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
116 oldline = None |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
117 lines.append(line[1:].strip()) |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
118 continue |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
119 if oldline: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
120 oldline = oldline + ' ' + line |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
121 else: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
122 oldline = line |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
123 else: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
124 if oldline: |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
125 lines.append(oldline) |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
126 log = '\n\n'.join(['* %s' % line for line in lines]) |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
127 |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
128 f = file(output, 'w') # write the output to a patch file |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
129 print >> f, diff |
190ce22e7e83
scour the log and format it like a civilized human being
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
130 f.close() |
6 | 131 |
132 # output the log | |
133 if logfile: | |
134 f = file(logfile, 'w') # write the log to a file | |
135 print >> f, log | |
136 else: | |
137 return log | |
138 | |
139 def apply(self): | |
140 """ | |
141 apply the existing feature branch to master as a patch | |
142 """ | |
143 | |
144 # sanity check | |
145 branch = self.branch() | |
8 | 146 if self.simulate: |
147 branch = '<branch>' | |
6 | 148 assert branch != 'master', "Can't apply master to itself!" |
149 assert self.branches, "No branches defined!" | |
150 | |
151 # get the patch | |
152 self.patch(branch + '.diff', branch + '.log') | |
153 diff = os.path.abspath(branch + '.diff') | |
154 log = os.path.abspath(branch + '.log') | |
155 | |
156 # apply the patch | |
8 | 157 if not self.simulate: |
158 cwd = os.getcwd() | |
159 os.chdir(self.root()) | |
6 | 160 for b in self.branches: |
161 call(['git', 'checkout', b]) | |
162 call(['patch -p1 < %s' % diff]) | |
163 call(['git', 'commit', '-a', '-F', log]) | |
164 call(['git', 'push', 'origin', b]) | |
165 if self.remote: | |
166 call(['git', 'push', self.remote, b]) | |
167 | |
168 # cleanup | |
169 call(['git', 'checkout', branch]) | |
8 | 170 if not self.simulate: |
171 os.chdir(cwd) | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
172 |
7 | 173 def delete(self): |
174 """delete the current feature branch""" | |
175 # sanity check | |
176 branch = self.branch() | |
177 assert branch != 'master', "You can't delete the master!" | |
178 call(['git', 'checkout', 'master']) | |
179 call(['git', '-D', branch]) | |
180 | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
181 def branch(self): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
182 """print what branch you're on""" |
3 | 183 output = call(['git', 'branch'], output=False, pipe=True) |
2 | 184 if self.simulate: |
6 | 185 return |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
186 for line in output['stdout'].splitlines(): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
187 if line.startswith('*'): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
188 return line[1:].strip() |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
189 |
6 | 190 def root(self): |
191 """return (relative) root location of repository""" | |
8 | 192 |
193 if self.simulate: | |
194 return '<root>' | |
6 | 195 output = call(['git', 'rev-parse', '--show-cdup'], output=False, pipe=True) |
196 location = output['stdout'].strip() | |
197 if not location: | |
198 return '.' | |
199 return location | |
200 | |
0
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
201 def main(args=sys.argv[1:]): |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
202 parser = CommandParser(gut) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
203 parser.invoke(args) |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
204 |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
205 if __name__ == '__main__': |
9688c72a93c3
initial commit of gut, probably doesnt actually work
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
206 main() |