~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: John Arbash Meinel
  • Date: 2007-03-14 20:15:52 UTC
  • mto: (2353.4.2 locking)
  • mto: This revision was merged to the branch mainline in revision 2360.
  • Revision ID: john@arbash-meinel.com-20070314201552-bjtfua57456dviep
Update the lock code and test code so that if more than one
lock implementation is available, they will both be tested.

It is quite a bit of overhead, for a case where we are likely to only have 1
real lock implementation per platform, but hey, for now we have 2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    option,
45
45
    osutils,
46
46
    trace,
47
 
    win32utils,
48
47
    )
49
48
""")
50
49
 
138
137
    plugins_override
139
138
        If true, plugin commands can override builtins.
140
139
    """
141
 
    try:
142
 
        return _get_cmd_object(cmd_name, plugins_override)
143
 
    except KeyError:
144
 
        raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
145
 
 
146
 
 
147
 
def _get_cmd_object(cmd_name, plugins_override=True):
148
 
    """Worker for get_cmd_object which raises KeyError rather than BzrCommandError."""
149
140
    from bzrlib.externalcommand import ExternalCommand
150
141
 
151
142
    # We want only 'ascii' command names, but the user may have typed
168
159
    cmd_obj = ExternalCommand.find_command(cmd_name)
169
160
    if cmd_obj:
170
161
        return cmd_obj
171
 
    raise KeyError
 
162
 
 
163
    raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
172
164
 
173
165
 
174
166
class Command(object):
241
233
        if self.__doc__ == Command.__doc__:
242
234
            warn("No help message set for %r" % self)
243
235
 
244
 
    def _maybe_expand_globs(self, file_list):
245
 
        """Glob expand file_list if the platform does not do that itself.
246
 
        
247
 
        :return: A possibly empty list of unicode paths.
248
 
 
249
 
        Introduced in bzrlib 0.18.
250
 
        """
251
 
        if not file_list:
252
 
            file_list = []
253
 
        if sys.platform == 'win32':
254
 
            file_list = win32utils.glob_expand(file_list)
255
 
        return list(file_list)
256
 
 
257
 
    def _usage(self):
258
 
        """Return single-line grammar for this command.
259
 
 
260
 
        Only describes arguments, not options.
261
 
        """
262
 
        s = 'bzr ' + self.name() + ' '
263
 
        for aname in self.takes_args:
264
 
            aname = aname.upper()
265
 
            if aname[-1] in ['$', '+']:
266
 
                aname = aname[:-1] + '...'
267
 
            elif aname[-1] == '?':
268
 
                aname = '[' + aname[:-1] + ']'
269
 
            elif aname[-1] == '*':
270
 
                aname = '[' + aname[:-1] + '...]'
271
 
            s += aname + ' '
272
 
                
273
 
        assert s[-1] == ' '
274
 
        s = s[:-1]
275
 
        return s
276
 
 
277
 
    def get_help_text(self, additional_see_also=None):
278
 
        """Return a text string with help for this command.
279
 
        
280
 
        :param additional_see_also: Additional help topics to be
281
 
            cross-referenced.
282
 
        """
283
 
        doc = self.help()
284
 
        if doc is None:
285
 
            raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
286
 
 
287
 
        result = ""
288
 
        result += 'usage: %s\n' % self._usage()
289
 
 
290
 
        if self.aliases:
291
 
            result += 'aliases: '
292
 
            result += ', '.join(self.aliases) + '\n'
293
 
 
294
 
        result += '\n'
295
 
 
296
 
        plugin_name = self.plugin_name()
297
 
        if plugin_name is not None:
298
 
            result += '(From plugin "%s")' % plugin_name
299
 
            result += '\n\n'
300
 
 
301
 
        result += doc
302
 
        if result[-1] != '\n':
303
 
            result += '\n'
304
 
        result += '\n'
305
 
        result += option.get_optparser(self.options()).format_option_help()
306
 
        see_also = self.get_see_also(additional_see_also)
307
 
        if see_also:
308
 
            result += '\nSee also: '
309
 
            result += ', '.join(see_also)
310
 
            result += '\n'
311
 
        return result
312
 
 
313
 
    def get_help_topic(self):
314
 
        """Return the commands help topic - its name."""
315
 
        return self.name()
316
 
 
317
 
    def get_see_also(self, additional_terms=None):
318
 
        """Return a list of help topics that are related to this ommand.
319
 
        
320
 
        The list is derived from the content of the _see_also attribute. Any
321
 
        duplicates are removed and the result is in lexical order.
322
 
        :param additional_terms: Additional help topics to cross-reference.
323
 
        :return: A list of help topics.
324
 
        """
325
 
        see_also = set(getattr(self, '_see_also', []))
326
 
        if additional_terms:
327
 
            see_also.update(additional_terms)
328
 
        return sorted(see_also)
329
 
 
330
236
    def options(self):
331
237
        """Return dict of valid options for this command.
332
238
 
333
239
        Maps from long option name to option object."""
334
240
        r = dict()
335
 
        r['help'] = option._help_option
 
241
        r['help'] = option.Option.OPTIONS['help']
336
242
        for o in self.takes_options:
337
243
            if isinstance(o, basestring):
338
244
                o = option.Option.OPTIONS[o]
365
271
        # bogus. So set the attribute, so we can find the correct encoding later.
366
272
        self.outf.encoding = output_encoding
367
273
 
 
274
    @deprecated_method(zero_eight)
 
275
    def run_argv(self, argv):
 
276
        """Parse command line and run.
 
277
        
 
278
        See run_argv_aliases for the 0.8 and beyond api.
 
279
        """
 
280
        return self.run_argv_aliases(argv)
 
281
 
368
282
    def run_argv_aliases(self, argv, alias_argv=None):
369
283
        """Parse the command line and run with extra aliases in alias_argv."""
370
284
        if argv is None:
373
287
            argv = []
374
288
        args, opts = parse_args(self, argv, alias_argv)
375
289
        if 'help' in opts:  # e.g. bzr add --help
376
 
            sys.stdout.write(self.get_help_text())
 
290
            from bzrlib.help import help_on_command
 
291
            help_on_command(self.name())
377
292
            return 0
378
293
        # mix arguments and options into one dictionary
379
294
        cmdargs = _match_argform(self.name(), self.takes_args, args)
548
463
 
549
464
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
550
465
    from bzrlib.lsprof import profile
 
466
    import cPickle
551
467
    ret, stats = profile(the_callable, *args, **kwargs)
552
468
    stats.sort()
553
469
    if filename is None:
554
470
        stats.pprint()
555
471
    else:
556
 
        stats.save(filename)
557
 
        trace.note('Profile data written to "%s".', filename)
 
472
        stats.freeze()
 
473
        cPickle.dump(stats, open(filename, 'w'), 2)
 
474
        print 'Profile data written to %r.' % filename
558
475
    return ret
559
476
 
560
477
 
679
596
    # 'command not found' error later.
680
597
 
681
598
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
682
 
    run = cmd_obj.run_argv_aliases
683
 
    run_argv = [argv, alias_argv]
 
599
    if not getattr(cmd_obj.run_argv, 'is_deprecated', False):
 
600
        run = cmd_obj.run_argv
 
601
        run_argv = [argv]
 
602
    else:
 
603
        run = cmd_obj.run_argv_aliases
 
604
        run_argv = [argv, alias_argv]
684
605
 
685
606
    try:
686
607
        if opt_lsprof:
727
648
def run_bzr_catch_errors(argv):
728
649
    try:
729
650
        return run_bzr(argv)
 
651
        # do this here inside the exception wrappers to catch EPIPE
 
652
        sys.stdout.flush()
730
653
    except (KeyboardInterrupt, Exception), e:
731
654
        # used to handle AssertionError and KeyboardInterrupt
732
655
        # specially here, but hopefully they're handled ok by the logger now
737
660
            pdb.post_mortem(sys.exc_traceback)
738
661
        return 3
739
662
 
740
 
 
741
 
class HelpCommandIndex(object):
742
 
    """A index for bzr help that returns commands."""
743
 
 
744
 
    def __init__(self):
745
 
        self.prefix = 'commands/'
746
 
 
747
 
    def get_topics(self, topic):
748
 
        """Search for topic amongst commands.
749
 
 
750
 
        :param topic: A topic to search for.
751
 
        :return: A list which is either empty or contains a single
752
 
            Command entry.
753
 
        """
754
 
        if topic and topic.startswith(self.prefix):
755
 
            topic = topic[len(self.prefix):]
756
 
        try:
757
 
            cmd = _get_cmd_object(topic)
758
 
        except KeyError:
759
 
            return []
760
 
        else:
761
 
            return [cmd]
762
 
 
763
 
 
764
663
if __name__ == '__main__':
765
664
    sys.exit(main(sys.argv))