~mvo/ubuntu-sso-client/strawman-lp711413

« back to all changes in this revision

Viewing changes to setup.py

Updated the setup.py to generate a minimun .exe installation to be used on Windows.

Show diffs side-by-side

added added

removed removed

Lines of Context:
232
232
                                current_file.endswith('_rc.py'):
233
233
                    os.unlink(os.path.join(dirpath, current_file))
234
234
 
235
 
# pylint: disable=W0621
 
235
def set_py2exe_paths():
 
236
    """Set the path so that py2exe finds the required modules."""
 
237
    import lazr
 
238
    # pylint: disable=F0401
 
239
    import win32com
 
240
    # pylint: enable=F0401
 
241
    try:
 
242
        import py2exe.mf as modulefinder
 
243
    except ImportError:
 
244
        import modulefinder
 
245
 
 
246
    # py2exe 0.6.4 introduced a replacement modulefinder.
 
247
    # This means we have to add package paths there,
 
248
    # not to the built-in one.  If this new modulefinder gets
 
249
    # integrated into Python, then we might be able to revert
 
250
    # this some day. If this doesn't work, try import modulefinder
 
251
    for package_path in win32com.__path__[1:]:
 
252
        modulefinder.AddPackagePath("win32com", package_path)
 
253
    for extra_mod in ["win32com.server" ,"win32com.client"]: 
 
254
        __import__(extra_mod)
 
255
        module = sys.modules[extra_mod]
 
256
        for module_path in module.__path__[1:]:
 
257
            modulefinder.AddPackagePath(extra_mod, module_path)
 
258
 
 
259
    # lazr uses namespaces packages, which does add some problems to py2exe
 
260
    # the following is a way to work arround the issue
 
261
    for p in lazr.__path__:
 
262
        modulefinder.AddPackagePath(__name__, p) 
 
263
 
 
264
def get_py2exe_extension():
 
265
    """Return an extension class of py2exe."""
 
266
    import os
 
267
    import glob
 
268
    import lazr.restfulclient
 
269
    from py2exe.build_exe import py2exe as build_exe
 
270
 
 
271
    class MediaCollector(build_exe):
 
272
        """Extension that copies lazr missing data."""
 
273
 
 
274
        def _add_module_data(self, module_name):
 
275
            """Add the data from a given path."""
 
276
            # Create the media subdir where the
 
277
            # Python files are collected.
 
278
            media = module_name.replace('.', os.path.sep)
 
279
            full = os.path.join(self.collect_dir, media)
 
280
            if not os.path.exists(full):
 
281
                self.mkpath(full)
 
282
 
 
283
            # Copy the media files to the collection dir.
 
284
            # Also add the copied file to the list of compiled
 
285
            # files so it will be included in zipfile.
 
286
            module = __import__(module_name, None, None, [''])
 
287
            for path in module.__path__:
 
288
                for f in glob.glob(path + '/*'):  # does not like os.path.sep
 
289
                    log.info('Copying file %s', f)
 
290
                    name = os.path.basename(f)
 
291
                    if not os.path.isdir(f):
 
292
                        self.copy_file(f, os.path.join(full, name))
 
293
                        self.compiled_files.append(os.path.join(media, name))
 
294
                    else:
 
295
                        self.copy_tree(f, os.path.join(full, name))
 
296
 
 
297
        def copy_extensions(self, extensions):
 
298
            """Copy the missing extensions."""
 
299
            build_exe.copy_extensions(self, extensions)
 
300
            for module in ['lazr.uri', 'lazr.restfulclient',
 
301
                           'lazr.authentication', 'wadllib']:
 
302
                self._add_module_data(module)
 
303
 
 
304
    return MediaCollector
 
305
 
236
306
def setup_windows():
237
307
    """Provide the required info to setup the project on windows."""
 
308
    set_py2exe_paths()
238
309
    scripts = []
239
310
    data_files = []
240
311
    packages = ['ubuntu_sso', 'ubuntu_sso.qt', 'ubuntu_sso.utils',
242
313
                'ubuntu_sso.main']
243
314
    extra = {}
244
315
    cmdclass = {'build' : SSOWindowsBuild,
245
 
                'clean' : SSOWindowsClean}
 
316
                'clean' : SSOWindowsClean,
 
317
                'py2exe' : get_py2exe_extension()}
246
318
 
247
319
    # for PyQt, see http://www.py2exe.org/index.cgi/Py2exeAndPyQt
248
 
    includes = ['sip',]
249
 
 
 
320
    includes = ['sip', 'email', 'ubuntu_sso.qt.gui',
 
321
                'ubuntu_sso.qt.controllers', 'PyQt4.QtNetwork']
 
322
    # exclude the modules that are not part of widows, this will not do much
 
323
    # besides the fact that the warnings wont be returned.
 
324
    excludes = ['dbus', 'dbus.mainloop.glib', 'osx_keychain', 'gobject',
 
325
                'gnomekeyring']
250
326
    # Qt4 plugins, see http://stackoverflow.com/questions/2206406/
251
327
    def qt4_plugins(subdir, *dlls):
252
328
        """Add the required plugins so that we can package them."""
256
332
 
257
333
    data_files.append(qt4_plugins('imageformats', 'qico4.dll',
258
334
                                       'qsvg4.dll'))
259
 
    # ModuleFinder can't handle runtime changes to __path__,
260
 
    # but win32com uses them
261
 
    try:
262
 
        # py2exe 0.6.4 introduced a replacement modulefinder.
263
 
        # This means we have to add package paths there,
264
 
        # not to the built-in one.  If this new modulefinder gets
265
 
        # integrated into Python, then we might be able to revert
266
 
        # this some day. If this doesn't work, try import modulefinder
267
 
        # pylint: disable=F0401
268
 
        try:
269
 
            import py2exe.mf as modulefinder
270
 
        except ImportError:
271
 
            import modulefinder
272
 
 
273
 
        import win32com
274
 
        # pylint: enable=F0401
275
 
        for package_path in win32com.__path__[1:]:
276
 
            modulefinder.AddPackagePath("win32com", package_path)
277
 
        for extra_mod in ["win32com.server" ,"win32com.client"]: 
278
 
            __import__(extra_mod)
279
 
            module = sys.modules[extra_mod]
280
 
            for module_path in module.__path__[1:]:
281
 
                modulefinder.AddPackagePath(extra_mod, module_path)
282
 
    except ImportError:
283
 
        # no build path setup, no worries.
284
 
        pass
285
335
 
286
336
    extra['options'] = {
287
337
           'py2exe' : {
 
338
               'bundle_files' : 1,
288
339
               'skip_archive' : 0,
289
340
               'includes' : includes,
290
 
               'optimize' : 1
 
341
               'optimize' : 1,
 
342
               'dll_excludes': [ "mswsock.dll", "powrprof.dll" ]
291
343
           }
292
344
        }
293
345
    # add the console script so that py2exe compiles it
294
346
    extra['console'] = ['bin/windows-ubuntu-sso-login',]
 
347
    extra['zipfile'] = None
295
348
    return scripts, data_files, packages, extra, cmdclass
296
349
 
297
350
def setup_linux():
328
381
            'to Ubuntu services via SSO',
329
382
        url='https://launchpad.net/ubuntu-sso-client',
330
383
        scripts=scripts,
331
 
        data_files = data_files,
 
384
        data_files=data_files,
332
385
        packages=packages,
333
386
        cmdclass=cmdclass,
334
387
        **extra)