~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-09-01 10:47:27 UTC
  • Revision ID: mbp@sourcefrog.net-20050901104726-63429108ad8454e1
- split ExternalCommand class into its own file

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
from bzrlib.branch import find_branch
39
39
from bzrlib import BZRDIR
40
40
 
41
 
 
42
41
plugin_cmds = {}
43
42
 
44
43
 
206
205
    plugins_override
207
206
        If true, plugin commands can override builtins.
208
207
    """
 
208
    from bzrlib.externalcommand import ExternalCommand
 
209
 
209
210
    cmd_name = str(cmd_name)            # not unicode
210
211
 
211
212
    # first look up this command under the specified name
295
296
        return _unsquish_command_name(self.__class__.__name__)
296
297
 
297
298
 
298
 
class ExternalCommand(Command):
299
 
    """Class to wrap external commands.
300
 
 
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.
304
 
 
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
308
 
    forward.
309
 
 
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
312
 
    script.
313
 
    """
314
 
 
315
 
    def find_command(cls, cmd):
316
 
        import os.path
317
 
        bzrpath = os.environ.get('BZRPATH', '')
318
 
 
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)
323
 
 
324
 
        return None
325
 
 
326
 
    find_command = classmethod(find_command)
327
 
 
328
 
    def __init__(self, path):
329
 
        self.path = path
330
 
 
331
 
        pipe = os.popen('%s --bzr-usage' % path, 'r')
332
 
        self.takes_options = pipe.readline().split()
333
 
 
334
 
        for opt in self.takes_options:
335
 
            if not opt in OPTIONS:
336
 
                raise BzrError("Unknown option '%s' returned by external command %s"
337
 
                               % (opt, path))
338
 
 
339
 
        # TODO: Is there any way to check takes_args is valid here?
340
 
        self.takes_args = pipe.readline().split()
341
 
 
342
 
        if pipe.close() is not None:
343
 
            raise BzrError("Failed funning '%s --bzr-usage'" % path)
344
 
 
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)
349
 
 
350
 
    def __call__(self, options, arguments):
351
 
        Command.__init__(self, options, arguments)
352
 
        return self
353
 
 
354
 
    def name(self):
355
 
        raise NotImplementedError()
356
 
 
357
 
    def run(self, **kargs):
358
 
        raise NotImplementedError()
359
 
        
360
 
        opts = []
361
 
        args = []
362
 
 
363
 
        keys = kargs.keys()
364
 
        keys.sort()
365
 
        for name in keys:
366
 
            optname = name.replace('_','-')
367
 
            value = kargs[name]
368
 
            if OPTIONS.has_key(optname):
369
 
                # it's an option
370
 
                opts.append('--%s' % optname)
371
 
                if value is not None and value is not True:
372
 
                    opts.append(str(value))
373
 
            else:
374
 
                # it's an arg, or arg list
375
 
                if type(value) is not list:
376
 
                    value = [value]
377
 
                for v in value:
378
 
                    if v is not None:
379
 
                        args.append(str(v))
380
 
 
381
 
        self.status = os.spawnv(os.P_WAIT, self.path, [self.path] + opts + args)
382
 
        return self.status
383
 
 
384
 
 
385
 
 
386
299
def parse_spec(spec):
387
300
    """
388
301
    >>> parse_spec(None)