~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

  • Committer: Alexander Belchenko
  • Date: 2006-12-29 07:53:17 UTC
  • mto: This revision was merged to the branch mainline in revision 2219.
  • Revision ID: bialix@ukr.net-20061229075317-uizaktke7o25g1z4
Bugfix #68124: Allow plugins import from zip archives.

Show diffs side-by-side

added added

removed removed

Lines of Context:
113
113
    dirs.insert(0, os.path.dirname(plugins.__file__))
114
114
 
115
115
    load_from_dirs(dirs)
 
116
    load_from_zips(dirs)
116
117
 
117
118
 
118
119
def load_from_dirs(dirs):
183
184
                ## import pdb; pdb.set_trace()
184
185
                warning('Unable to load plugin %r from %r' % (name, d))
185
186
                log_exception_quietly()
 
187
 
 
188
 
 
189
def load_from_zips(zips):
 
190
    """Load bzr plugins from zip archives with zipimport.
 
191
    It's similar to load_from_dirs but plugins searched inside archives.
 
192
    """
 
193
    import zipfile
 
194
    import zipimport
 
195
 
 
196
    valid_suffixes = ('.py', '.pyc', '.pyo')    # only python modules/packages
 
197
                                                # is allowed
 
198
    for zip_name in zips:
 
199
        if '.zip' not in zip_name:
 
200
            continue
 
201
        try:
 
202
            ziobj = zipimport.zipimporter(zip_name)
 
203
        except zipimport.ZipImportError:
 
204
            # not a valid zip
 
205
            continue
 
206
        mutter('Looking for plugins in %r', zip_name)
 
207
 
 
208
        # use zipfile to get list of files/dirs inside zip
 
209
        z = zipfile.ZipFile(ziobj.archive)
 
210
        namelist = z.namelist()
 
211
        z.close()
 
212
 
 
213
        if ziobj.prefix:
 
214
            prefix = ziobj.prefix.replace('\\','/')
 
215
            ix = len(prefix)
 
216
            namelist = [name[ix:]
 
217
                        for name in namelist
 
218
                        if name.startswith(prefix)]
 
219
 
 
220
        mutter('Names in archive: %r', namelist)
 
221
 
 
222
        for name in namelist:
 
223
            if not name or name.endswith('/'):
 
224
                continue
 
225
 
 
226
            head, tail = os.path.split(name)
 
227
            if '/' in head:
 
228
                # we don't need looking in subdirectories
 
229
                continue
 
230
 
 
231
            base, suffix = os.path.splitext(tail)
 
232
            if suffix not in valid_suffixes:
 
233
                continue
 
234
 
 
235
            if base == '__init__':
 
236
                # package
 
237
                plugin_name = head
 
238
            elif head == '':
 
239
                # module
 
240
                plugin_name = base
 
241
            else:
 
242
                continue
 
243
 
 
244
            if not plugin_name:
 
245
                continue
 
246
            if getattr(plugins, plugin_name, None):
 
247
                mutter('Plugin name %s already loaded', plugin_name)
 
248
                continue
 
249
 
 
250
            try:
 
251
                plugin = ziobj.load_module(plugin_name)
 
252
                setattr(plugins, plugin_name, plugin)
 
253
                mutter('Load plugin %s from zip %r', plugin_name, zip_name)
 
254
            except zipimport.ZipImportError, e:
 
255
                mutter('Unable to load plugin %r from %r: %s',
 
256
                       plugin_name, zip_name, str(e))
 
257
                continue
 
258
            except KeyboardInterrupt:
 
259
                raise
 
260
            except Exception, e:
 
261
                ## import pdb; pdb.set_trace()
 
262
                warning('Unable to load plugin %r from %r'
 
263
                        % (name, zip_name))
 
264
                log_exception_quietly()