~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-05-09 06:09:42 UTC
  • Revision ID: mbp@sourcefrog.net-20050509060942-d9c9efd7feed0894
- more indicators at top of test output
- tidy up remotebranch stuff

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
    for cmdname, cmdclass in get_all_cmds():
59
59
        if cmd in cmdclass.aliases:
60
60
            return cmdname, cmdclass
61
 
 
62
 
    cmdclass = ExternalCommand.find_command(cmd)
63
 
    if cmdclass:
64
 
        return cmd, cmdclass
65
 
 
66
 
    raise BzrCommandError("unknown command %r" % cmd)
 
61
    else:
 
62
        raise BzrCommandError("unknown command %r" % cmd)
67
63
 
68
64
 
69
65
class Command:
115
111
        return 0
116
112
 
117
113
 
118
 
class ExternalCommand(Command):
119
 
    """Class to wrap external commands.
120
 
 
121
 
    We cheat a little here, when get_cmd_class() calls us we actually give it back
122
 
    an object we construct that has the appropriate path, help, options etc for the
123
 
    specified command.
124
 
 
125
 
    When run_bzr() tries to instantiate that 'class' it gets caught by the __call__
126
 
    method, which we override to call the Command.__init__ method. That then calls
127
 
    our run method which is pretty straight forward.
128
 
 
129
 
    The only wrinkle is that we have to map bzr's dictionary of options and arguments
130
 
    back into command line options and arguments for the script.
131
 
    """
132
 
 
133
 
    def find_command(cls, cmd):
134
 
        bzrpath = os.environ.get('BZRPATH', '')
135
 
 
136
 
        for dir in bzrpath.split(':'):
137
 
            path = os.path.join(dir, cmd)
138
 
            if os.path.isfile(path):
139
 
                return ExternalCommand(path)
140
 
 
141
 
        return None
142
 
 
143
 
    find_command = classmethod(find_command)
144
 
 
145
 
    def __init__(self, path):
146
 
        self.path = path
147
 
 
148
 
        # TODO: If either of these fail, we should detect that and
149
 
        # assume that path is not really a bzr plugin after all.
150
 
 
151
 
        pipe = os.popen('%s --bzr-usage' % path, 'r')
152
 
        self.takes_options = pipe.readline().split()
153
 
        self.takes_args = pipe.readline().split()
154
 
        pipe.close()
155
 
 
156
 
        pipe = os.popen('%s --bzr-help' % path, 'r')
157
 
        self.__doc__ = pipe.read()
158
 
        pipe.close()
159
 
 
160
 
    def __call__(self, options, arguments):
161
 
        Command.__init__(self, options, arguments)
162
 
        return self
163
 
 
164
 
    def run(self, **kargs):
165
 
        opts = []
166
 
        args = []
167
 
 
168
 
        keys = kargs.keys()
169
 
        keys.sort()
170
 
        for name in keys:
171
 
            value = kargs[name]
172
 
            if OPTIONS.has_key(name):
173
 
                # it's an option
174
 
                opts.append('--%s' % name)
175
 
                if value is not None and value is not True:
176
 
                    opts.append(str(value))
177
 
            else:
178
 
                # it's an arg, or arg list
179
 
                if type(value) is not list:
180
 
                    value = [value]
181
 
                for v in value:
182
 
                    if v is not None:
183
 
                        args.append(str(v))
184
 
 
185
 
        self.status = os.spawnv(os.P_WAIT, self.path, [self.path] + opts + args)
186
 
        return self.status
187
 
 
188
114
 
189
115
class cmd_status(Command):
190
116
    """Display status summary.
453
379
        show_diff(Branch('.'), revision, file_list)
454
380
 
455
381
 
456
 
        
457
 
 
458
 
 
459
382
class cmd_deleted(Command):
460
383
    """List files deleted in the working tree.
461
384
 
478
401
                else:
479
402
                    print path
480
403
 
481
 
 
482
 
class cmd_modified(Command):
483
 
    """List files modified in working tree."""
484
 
    hidden = True
485
 
    def run(self):
486
 
        import statcache
487
 
        b = Branch('.')
488
 
        inv = b.read_working_inventory()
489
 
        sc = statcache.update_cache(b, inv)
490
 
        basis = b.basis_tree()
491
 
        basis_inv = basis.inventory
492
 
        
493
 
        # We used to do this through iter_entries(), but that's slow
494
 
        # when most of the files are unmodified, as is usually the
495
 
        # case.  So instead we iterate by inventory entry, and only
496
 
        # calculate paths as necessary.
497
 
 
498
 
        for file_id in basis_inv:
499
 
            cacheentry = sc.get(file_id)
500
 
            if not cacheentry:                 # deleted
501
 
                continue
502
 
            ie = basis_inv[file_id]
503
 
            if cacheentry[statcache.SC_SHA1] != ie.text_sha1:
504
 
                path = inv.id2path(file_id)
505
 
                print path
506
 
                
507
 
        
508
 
 
509
404
class cmd_root(Command):
510
405
    """Show the tree root directory.
511
406
 
514
409
    takes_args = ['filename?']
515
410
    def run(self, filename=None):
516
411
        """Print the branch root."""
517
 
        from branch import find_branch
518
 
        b = find_branch(filename)
519
 
        print getattr(b, 'base', None) or getattr(b, 'baseurl')
 
412
        print bzrlib.branch.find_branch_root(filename)
 
413
 
520
414
 
521
415
 
522
416
class cmd_log(Command):
529
423
    takes_args = ['filename?']
530
424
    takes_options = ['timezone', 'verbose', 'show-ids']
531
425
    def run(self, filename=None, timezone='original', verbose=False, show_ids=False):
532
 
        from branch import find_branch
533
 
        b = find_branch((filename or '.'), lock_mode='r')
 
426
        b = Branch((filename or '.'), lock_mode='r')
534
427
        if filename:
535
428
            filename = b.relpath(filename)
536
429
        bzrlib.show_log(b, filename,
589
482
 
590
483
 
591
484
class cmd_ignore(Command):
592
 
    """Ignore a command or pattern
593
 
 
594
 
    To remove patterns from the ignore list, edit the .bzrignore file.
595
 
 
596
 
    If the pattern contains a slash, it is compared to the whole path
597
 
    from the branch root.  Otherwise, it is comapred to only the last
598
 
    component of the path.
599
 
 
600
 
    Ignore patterns are case-insensitive on case-insensitive systems.
601
 
 
602
 
    Note: wildcards must be quoted from the shell on Unix.
603
 
 
604
 
    examples:
605
 
        bzr ignore ./Makefile
606
 
        bzr ignore '*.class'
607
 
    """
 
485
    """Ignore a command or pattern"""
608
486
    takes_args = ['name_pattern']
609
487
    
610
488
    def run(self, name_pattern):
641
519
 
642
520
 
643
521
class cmd_ignored(Command):
644
 
    """List ignored files and the patterns that matched them.
645
 
 
646
 
    See also: bzr ignore"""
 
522
    """List ignored files and the patterns that matched them."""
647
523
    def run(self):
648
524
        tree = Branch('.').working_tree()
649
525
        for path, file_class, kind, file_id in tree.list_files():
659
535
 
660
536
    example:
661
537
        bzr lookup-revision 33
662
 
    """
 
538
        """
663
539
    hidden = True
664
540
    takes_args = ['revno']
665
541
    
829
705
        help.help(topic)
830
706
 
831
707
 
832
 
class cmd_update_stat_cache(Command):
833
 
    """Update stat-cache mapping inodes to SHA-1 hashes.
834
 
 
835
 
    For testing only."""
836
 
    hidden = True
837
 
    def run(self):
838
 
        import statcache
839
 
        b = Branch('.')
840
 
        statcache.update_cache(b)
841
 
 
842
 
 
843
708
######################################################################
844
709
# main routine
845
710
 
1098
963
            return 2
1099
964
        except Exception, e:
1100
965
            quiet = False
1101
 
            if (isinstance(e, IOError) 
1102
 
                and hasattr(e, 'errno')
1103
 
                and e.errno == errno.EPIPE):
 
966
            if isinstance(e, IOError) and e.errno == errno.EPIPE:
1104
967
                quiet = True
1105
968
                msg = 'broken pipe'
1106
969
            else: