|
31
by Colin Walters
fix python reexecution bits (now pass make check) |
1 |
#!/usr/bin/env python
|
|
1
by Colin Walters
initial import |
2 |
# -*- mode: python; coding: utf-8 -*-
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
3 |
# vim:smartindent cinwords=if,elif,else,for,while,try,except,finally,def,class:ts=4:sts=4:sta:et:ai:shiftwidth=4
|
4 |
#
|
|
|
1
by Colin Walters
initial import |
5 |
# arch-tag: Simple patch queue manager for tla
|
|
47
by Colin Walters
great tla-pqm => arch-pqm conversion (me, wlandry) |
6 |
# Copyright © 2003,2004 Colin Walters <walters@verbum.org>
|
|
174.2.2
by Tim Penhey
Updates following review. |
7 |
# Copyright © 2004 Canonical Ltd.
|
|
142
by Robert Collins
Add project awareness to branch specs. |
8 |
# Author: Robert Collins <robertc@robertcollins.net>
|
|
72
by Robert Collins
merge in arx support improvements from walter landry |
9 |
# Copyright © 2003, 2005 Walter Landry
|
|
1
by Colin Walters
initial import |
10 |
|
11 |
# This program is free software; you can redistribute it and/or modify
|
|
12 |
# it under the terms of the GNU General Public License as published by
|
|
13 |
# the Free Software Foundation; either version 2 of the License, or
|
|
14 |
# (at your option) any later version.
|
|
15 |
||
16 |
# This program is distributed in the hope that it will be useful,
|
|
17 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 |
# GNU General Public License for more details.
|
|
20 |
||
21 |
# You should have received a copy of the GNU General Public License
|
|
22 |
# along with this program; if not, write to the Free Software
|
|
23 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
24 |
||
|
30
by Colin Walters
some junk to try finding Python 2.3 if it isn't /usr/bin/python |
25 |
import os,sys |
|
174.5.2
by Daniel Watkins
Copied bzr's Python version checking. |
26 |
|
27 |
try: |
|
28 |
version_info = sys.version_info |
|
29 |
except AttributeError: |
|
30 |
version_info = 1, 5 # 1.5 or older |
|
31 |
||
32 |
REINVOKE = "__PQM_REINVOKE" |
|
33 |
NEED_VERS = (2, 4) |
|
34 |
KNOWN_PYTHONS = ('python2.4', 'python2.5') |
|
35 |
||
36 |
if version_info < NEED_VERS: |
|
37 |
if not os.environ.has_key(REINVOKE): |
|
38 |
# mutating os.environ doesn't work in old Pythons
|
|
39 |
os.putenv(REINVOKE, "1") |
|
40 |
for python in KNOWN_PYTHONS: |
|
41 |
try: |
|
42 |
os.execvp(python, [python] + sys.argv) |
|
43 |
except OSError: |
|
44 |
pass
|
|
45 |
sys.stderr.write("error: cannot find a suitable python interpreter") |
|
46 |
sys.stderr.write(" (need %d.%d or later)" % NEED_VERS) |
|
47 |
sys.exit(1) |
|
48 |
||
49 |
if hasattr(os, "unsetenv"): |
|
50 |
os.unsetenv(REINVOKE) |
|
51 |
||
|
194
by Robert Collins
Remove usage of popen2. |
52 |
import string, stat, re, glob, getopt, time, traceback, gzip, getpass |
|
239.1.6
by Robert Collins
Move EmailScript into queue/email.py. |
53 |
import smtplib |
|
34
by Colin Walters
major refactoring |
54 |
import logging, logging.handlers |
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
55 |
import pqm |
56 |
from pqm import * |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
57 |
from pqm.PQMConfigParser import ConfigParser |
58 |
from pqm.commandline import parse_command_line |
|
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
59 |
from pqm.core import get_script_queue, PatchQueueManager |
|
174.7.4
by Tim Penhey
Move some code around in preparation. |
60 |
from pqm.errors import PQMCmdFailure, PQMException |
|
130
by Robert Collins
Extract LockFile to a module. |
61 |
from pqm.lockfile import LockFile |
|
239.1.6
by Robert Collins
Move EmailScript into queue/email.py. |
62 |
from pqm.script import Command |
63 |
from pqm.queue.email import read_email |
|
|
1
by Colin Walters
initial import |
64 |
|
|
47
by Colin Walters
great tla-pqm => arch-pqm conversion (me, wlandry) |
65 |
|
|
32
by Colin Walters
clean up execution of tla |
66 |
def runtla_internal(sender, cmd, *args): |
|
47
by Colin Walters
great tla-pqm => arch-pqm conversion (me, wlandry) |
67 |
return apply(popen_noshell, [arch_path, cmd] + list(args)) |
|
32
by Colin Walters
clean up execution of tla |
68 |
|
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
69 |
|
|
32
by Colin Walters
clean up execution of tla |
70 |
def runtla(sender, cmd, *args): |
71 |
(status, msg, output) = apply(runtla_internal, [sender, cmd] + list(args)) |
|
72 |
if not ((status is None) or (status == 0)): |
|
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
73 |
raise PQMTlaFailure(sender, ["VCS command %s %s failed (%s): %s" % (cmd, args, status, msg)] + output) |
|
34
by Colin Walters
major refactoring |
74 |
return output |
|
32
by Colin Walters
clean up execution of tla |
75 |
|
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
76 |
def do_read_mode(logger, options, mail_reply, mail_server, from_address, fromaddr): |
|
3
by Colin Walters
tons of fixes |
77 |
sender = None |
78 |
try: |
|
|
65
by Robert Collins
pickup new logging, and gnupg hash: filtering |
79 |
(sender, subject, msg, sig) = read_email(logger) |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
80 |
if options.verify_sigs: |
81 |
sigid, siguid = verify_sig( |
|
82 |
sender, msg, sig, 1, logger, options.keyring) |
|
|
34
by Colin Walters
major refactoring |
83 |
open(transaction_file, 'a').write(sigid + '\n') |
|
5
by Colin Walters
add autotools infrastructure, lots of other stuff |
84 |
fname = 'patch.%d' % (time.time()) |
85 |
logger.info('new patch ' + fname) |
|
86 |
f = open('tmp.' + fname, 'w') |
|
87 |
f.write('From: ' + sender + '\n') |
|
|
15
by Colin Walters
merge test passes, woot! |
88 |
f.write('Subject: ' + subject + '\n') |
|
5
by Colin Walters
add autotools infrastructure, lots of other stuff |
89 |
f.write(string.join(re.split('\r?\n', msg), '\n')) # canonicalize line endings |
90 |
f.close() |
|
|
12
by Colin Walters
make first test pass, but it only sorta works |
91 |
os.rename('tmp.' + fname, fname) |
|
3
by Colin Walters
tons of fixes |
92 |
except: |
|
9
by Colin Walters
much more hackery |
93 |
if sender and mail_reply: |
|
3
by Colin Walters
tons of fixes |
94 |
server = smtplib.SMTP(mail_server) |
95 |
tb=string.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback), '') |
|
|
5
by Colin Walters
add autotools infrastructure, lots of other stuff |
96 |
server.sendmail(from_address, [sender], 'From: %s\r\nTo: %s\r\nSubject: error processing requests\r\n\r\n' % (fromaddr, sender) + 'An error was encountered:\n' + tb) |
|
3
by Colin Walters
tons of fixes |
97 |
server.quit() |
98 |
logger.exception("Caught exception") |
|
|
5
by Colin Walters
add autotools infrastructure, lots of other stuff |
99 |
sys.exit(1) |
|
19
by Colin Walters
only acquire lockfile for running |
100 |
sys.exit(0) |
101 |
||
|
67
by Robert Collins
New release, supports branch permissions, replay, debug output and baz 1.0 |
102 |
arch_path = 'baz' |
|
64
by Robert Collins
merge in Canonical pqm improvements |
103 |
arch_impl = None |
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
104 |
logfile_name = 'pqm.log' |
|
64
by Robert Collins
merge in Canonical pqm improvements |
105 |
default_mail_log_level = logging.ERROR |
106 |
precommit_hook = [] |
|
107 |
||
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
108 |
(options, args) = parse_command_line(sys.argv[1:]) |
109 |
||
110 |
if options.show_version: |
|
111 |
print "pqm %s" % pqm.__version__ |
|
112 |
sys.exit(0) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
113 |
|
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
114 |
logger = logging.getLogger("pqm") |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
115 |
# TODO: move the logging confuration somewhere else.
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
116 |
logger.setLevel(logging.DEBUG) |
|
239.1.18
by Robert Collins
Adjust StreamHandler construction to be compatible with 2.6 and 2.7. |
117 |
stderr_handler = logging.StreamHandler(sys.stderr) |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
118 |
stderr_handler.setLevel(options.loglevel) |
119 |
stderr_handler.setFormatter(logging.Formatter(fmt="%(name)s [%(thread)d] %(levelname)s: %(message)s")) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
120 |
logger.addHandler(stderr_handler) |
121 |
||
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
122 |
if not (options.read_mode or options.run_mode): |
|
64
by Robert Collins
merge in Canonical pqm improvements |
123 |
logger.error("Either --read or --run must be specified") |
124 |
sys.exit(1) |
|
125 |
||
126 |
configp = ConfigParser() |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
127 |
logger.debug("Reading config files: %s" % (options.configfile_names,)) |
128 |
configp.read(options.configfile_names) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
129 |
|
130 |
if configp.has_option('DEFAULT', 'arch_path'): |
|
131 |
arch_path = configp.get('DEFAULT', 'arch_path') |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
132 |
elif configp.has_option('DEFAULT', 'tlapath'): |
|
64
by Robert Collins
merge in Canonical pqm improvements |
133 |
logger.warn("Option 'tlapath' is deprecated") |
134 |
arch_path = configp.get('DEFAULT', 'tlapath') |
|
135 |
||
136 |
if os.access(arch_path, os.X_OK): |
|
137 |
logger.error("Can't execute \"%s\", please fix arch_path" % (arch_path,)) |
|
138 |
sys.exit(1) |
|
139 |
||
|
74
by Robert Collins
move CommandRunner code through to the library, and start testing star-merge command inputs |
140 |
# ugly transitional code
|
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
141 |
pqm.logger = logger |
|
64
by Robert Collins
merge in Canonical pqm improvements |
142 |
if configp.has_option('DEFAULT', 'arch_impl'): |
143 |
impl = configp.get('DEFAULT', 'arch_impl') |
|
144 |
if impl == 'tla': |
|
145 |
arch_impl = TlaHandler() |
|
146 |
elif impl == 'arx': |
|
147 |
arch_impl = ArXHandler() |
|
|
67
by Robert Collins
New release, supports branch permissions, replay, debug output and baz 1.0 |
148 |
elif impl == 'baz': |
|
68
by Robert Collins
merge in Pascal Hakims work, adjusting to retain baz 1.0 support |
149 |
arch_impl = Baz1_1Handler() |
150 |
elif impl == 'baz1.0': |
|
151 |
arch_impl = Baz1_0Handler() |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
152 |
else: |
153 |
logger.error("Unknown arch_impl \"%s\"" % (impl,)) |
|
154 |
sys.exit(1) |
|
|
143
by Robert Collins
Overhaul of command running logic to start clear Command separation: move Merge to MergeCommand. |
155 |
# FIXME: move this into a nicer place.
|
|
174.7.4
by Tim Penhey
Move some code around in preparation. |
156 |
Command.arch_impl = arch_impl |
157 |
Command.arch_path = arch_path |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
158 |
|
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
159 |
pqm.gpgv_path = configp.get_option('DEFAULT', 'gpgv_path', 'gpgv') |
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
160 |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
161 |
# The command line paramter overrides the setting in the config file.
|
162 |
if options.verify_sigs: |
|
163 |
options.verify_sigs = configp.get_boolean_option( |
|
164 |
'DEFAULT', 'verify_sigs', True) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
165 |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
166 |
if options.queuedir: |
167 |
queuedir = options.queuedir |
|
168 |
else: |
|
169 |
queuedir = get_queuedir(configp, logger, args) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
170 |
queuedir=os.path.abspath(queuedir) |
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
171 |
|
172 |
manager = PatchQueueManager(queuedir, configp, options, logger) |
|
173 |
||
174 |
if manager.from_address is None: |
|
175 |
logger.error("No from_address specified") |
|
176 |
sys.exit(1) |
|
177 |
||
178 |
# Still temporary hack. Tim Penhey 2008-05-29
|
|
179 |
pqm.pqm_subdir = manager.control_dir |
|
180 |
# ugly transitional code
|
|
181 |
pqm.logger = logger |
|
182 |
pqm.workdir = manager.work_dir |
|
183 |
pqm.runtla = runtla |
|
184 |
pqm.precommit_hook = precommit_hook |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
185 |
|
186 |
if not configp.has_option('DEFAULT', 'dont_set_home'): |
|
|
142
by Robert Collins
Add project awareness to branch specs. |
187 |
os.environ['HOME'] = queuedir |
|
64
by Robert Collins
merge in Canonical pqm improvements |
188 |
|
|
198
by Robert Collins
Results from manual qa: import cycles, and wrong object being called for start/stop test run. |
189 |
if not options.keyring and options.verify_sigs: |
|
64
by Robert Collins
merge in Canonical pqm improvements |
190 |
if configp.has_option('DEFAULT', 'keyring'): |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
191 |
options.keyring = configp.get('DEFAULT', 'keyring') |
|
64
by Robert Collins
merge in Canonical pqm improvements |
192 |
else: |
193 |
logger.error("No keyring specified on command line or in config files.") |
|
194 |
sys.exit(1) |
|
|
198
by Robert Collins
Results from manual qa: import cycles, and wrong object being called for start/stop test run. |
195 |
if options.verify_sigs and not os.access(options.keyring, os.R_OK): |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
196 |
logger.error("Couldn't access keyring %s" % (options.keyring,)) |
|
64
by Robert Collins
merge in Canonical pqm improvements |
197 |
sys.exit(1) |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
198 |
|
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
199 |
manager.make_directories() |
|
153
by Robert Collins
Generate incremental status output from precommit hooks. |
200 |
os.chdir(queuedir) |
201 |
||
|
154
by Robert Collins
Change StatusFile creation to not depend upon pqm_subdir being set. |
202 |
rev_optionhandler = pqm.BranchSpecOptionHandler(configp, queuedir=queuedir) |
|
144
by Robert Collins
Implement per-project status pages. |
203 |
if len(rev_optionhandler._specs) == 0: |
|
141
by Robert Collins
Rename allowed_revisioons to branch_specs |
204 |
logger.error("No branches to manage!") |
|
64
by Robert Collins
merge in Canonical pqm improvements |
205 |
sys.exit(1) |
|
144
by Robert Collins
Implement per-project status pages. |
206 |
for spec in rev_optionhandler._specs: |
207 |
logger.info("managing branch(s): " + spec) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
208 |
|
209 |
||
210 |
if configp.has_option('DEFAULT', 'logfile'): |
|
211 |
logfile_name = configp.get('DEFAULT', 'logfile') |
|
212 |
||
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
213 |
if not options.no_log: |
|
64
by Robert Collins
merge in Canonical pqm improvements |
214 |
if not os.path.isabs(logfile_name): |
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
215 |
logfile_name = os.path.join(manager.control_dir, logfile_name) |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
216 |
logger.debug("Adding log file: %s" % logfile_name) |
|
64
by Robert Collins
merge in Canonical pqm improvements |
217 |
filehandler = logging.FileHandler(logfile_name) |
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
218 |
if options.loglevel >= logging.WARN: |
|
64
by Robert Collins
merge in Canonical pqm improvements |
219 |
filehandler.setLevel(logging.INFO) |
220 |
else: |
|
221 |
filehandler.setLevel(logging.DEBUG) |
|
222 |
logger.addHandler(filehandler) |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
223 |
filehandler.setFormatter(logging.Formatter( |
224 |
fmt="%(asctime)s %(name)s [%(thread)d] %(levelname)s: %(message)s", |
|
225 |
datefmt="%b %d %H:%M:%S")) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
226 |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
227 |
if not options.debug_mode: |
|
64
by Robert Collins
merge in Canonical pqm improvements |
228 |
# Don't log to stderr past this point
|
229 |
logger.removeHandler(stderr_handler) |
|
230 |
||
231 |
transaction_file = os.path.join(queuedir, 'transactions-completed') |
|
232 |
if os.access(transaction_file, os.R_OK): |
|
233 |
lines = open(transaction_file).readlines() |
|
234 |
for line in lines: |
|
|
115
by Robert Collins
Patch from Walter Landry to rename arch-pqm to pqm throughout. |
235 |
pqm.used_transactions[line[0:-1]] = 1 |
|
64
by Robert Collins
merge in Canonical pqm improvements |
236 |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
237 |
if options.read_mode: |
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
238 |
do_read_mode(logger, options, manager.mail_reply, manager.mail_server, |
239 |
manager.from_address, manager.nice_from_address) |
|
|
174.2.1
by Tim Penhey
Changed from getopt to optparse to parse command line arguments. |
240 |
|
241 |
assert(options.run_mode) |
|
242 |
||
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
243 |
script_queue = get_script_queue( |
|
217
by Robert Collins
Use a PQM instance rather than the global workdir variable to obtain the queuedir for launchpadlib support. |
244 |
queuedir, logger, rev_optionhandler, configp, options, manager) |
|
174.8.1
by Tim Penhey
Alright! Tests all pass again. |
245 |
|
246 |
manager.run(script_queue) |
|
247 |
||
|
1
by Colin Walters
initial import |
248 |
logger.info("main thread exiting...") |
249 |
sys.exit(0) |
|
|
64
by Robert Collins
merge in Canonical pqm improvements |
250 |