~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-05-10 03:50:45 UTC
  • Revision ID: mbp@sourcefrog.net-20050510035045-c70b89a0b0a705b7
- External-command patch from mpe

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
 
    else:
62
 
        raise BzrCommandError("unknown command %r" % cmd)
 
61
 
 
62
    cmdclass = ExternalCommand.find_command(cmd)
 
63
    if cmdclass:
 
64
        return cmd, cmdclass
 
65
 
 
66
    raise BzrCommandError("unknown command %r" % cmd)
63
67
 
64
68
 
65
69
class Command:
111
115
        return 0
112
116
 
113
117
 
 
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
        pipe = os.popen('%s --bzr-usage' % path, 'r')
 
149
        self.takes_options = pipe.readline().split()
 
150
        self.takes_args = pipe.readline().split()
 
151
        pipe.close()
 
152
 
 
153
        pipe = os.popen('%s --bzr-help' % path, 'r')
 
154
        self.__doc__ = pipe.read()
 
155
        pipe.close()
 
156
 
 
157
    def __call__(self, options, arguments):
 
158
        Command.__init__(self, options, arguments)
 
159
        return self
 
160
 
 
161
    def run(self, **kargs):
 
162
        opts = []
 
163
        args = []
 
164
 
 
165
        keys = kargs.keys()
 
166
        keys.sort()
 
167
        for name in keys:
 
168
            value = kargs[name]
 
169
            if OPTIONS.has_key(name):
 
170
                # it's an option
 
171
                opts.append('--%s' % name)
 
172
                if value is not None and value is not True:
 
173
                    opts.append(str(value))
 
174
            else:
 
175
                # it's an arg, or arg list
 
176
                if type(value) is not list:
 
177
                    value = [value]
 
178
                for v in value:
 
179
                    if v is not None:
 
180
                        args.append(str(v))
 
181
 
 
182
        self.status = os.spawnv(os.P_WAIT, self.path, [self.path] + opts + args)
 
183
        return self.status
 
184
 
114
185
 
115
186
class cmd_status(Command):
116
187
    """Display status summary.