295
296
return _unsquish_command_name(self.__class__.__name__)
298
class ExternalCommand(Command):
299
"""Class to wrap external commands.
301
We cheat a little here, when get_cmd_class() calls us we actually
302
give it back an object we construct that has the appropriate path,
303
help, options etc for the specified command.
305
When run_bzr() tries to instantiate that 'class' it gets caught by
306
the __call__ method, which we override to call the Command.__init__
307
method. That then calls our run method which is pretty straight
310
The only wrinkle is that we have to map bzr's dictionary of options
311
and arguments back into command line options and arguments for the
315
def find_command(cls, cmd):
317
bzrpath = os.environ.get('BZRPATH', '')
319
for dir in bzrpath.split(os.pathsep):
320
path = os.path.join(dir, cmd)
321
if os.path.isfile(path):
322
return ExternalCommand(path)
326
find_command = classmethod(find_command)
328
def __init__(self, path):
331
pipe = os.popen('%s --bzr-usage' % path, 'r')
332
self.takes_options = pipe.readline().split()
334
for opt in self.takes_options:
335
if not opt in OPTIONS:
336
raise BzrError("Unknown option '%s' returned by external command %s"
339
# TODO: Is there any way to check takes_args is valid here?
340
self.takes_args = pipe.readline().split()
342
if pipe.close() is not None:
343
raise BzrError("Failed funning '%s --bzr-usage'" % path)
345
pipe = os.popen('%s --bzr-help' % path, 'r')
346
self.__doc__ = pipe.read()
347
if pipe.close() is not None:
348
raise BzrError("Failed funning '%s --bzr-help'" % path)
350
def __call__(self, options, arguments):
351
Command.__init__(self, options, arguments)
355
raise NotImplementedError()
357
def run(self, **kargs):
358
raise NotImplementedError()
366
optname = name.replace('_','-')
368
if OPTIONS.has_key(optname):
370
opts.append('--%s' % optname)
371
if value is not None and value is not True:
372
opts.append(str(value))
374
# it's an arg, or arg list
375
if type(value) is not list:
381
self.status = os.spawnv(os.P_WAIT, self.path, [self.path] + opts + args)
386
299
def parse_spec(spec):
388
301
>>> parse_spec(None)