Back to index

moin  1.9.0~rc2
setup.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: iso-8859-1 -*-
00003 """
00004     MoinMoin installer
00005 
00006     @copyright: 2001-2005 by Jürgen Hermann <jh@web.de>,
00007                 2006-2007 by MoinMoin:ThomasWaldmann
00008     @license: GNU GPL, see COPYING for details.
00009 """
00010 
00011 import os, sys, glob
00012 
00013 import distutils
00014 from distutils.core import setup
00015 from distutils.command.build_scripts import build_scripts
00016 
00017 from MoinMoin.version import release, revision
00018 
00019 
00020 #############################################################################
00021 ### Helpers
00022 #############################################################################
00023 
00024 def isbad(name):
00025     """ Whether name should not be installed """
00026     return (name.startswith('.') or
00027             name.startswith('#') or
00028             name.endswith('.pickle') or
00029             name == 'CVS')
00030 
00031 def isgood(name):
00032     """ Whether name should be installed """
00033     return not isbad(name)
00034 
00035 def makeDataFiles(prefix, dir):
00036     """ Create distutils data_files structure from dir
00037 
00038     distutil will copy all file rooted under dir into prefix, excluding
00039     dir itself, just like 'ditto src dst' works, and unlike 'cp -r src
00040     dst, which copy src into dst'.
00041 
00042     Typical usage:
00043         # install the contents of 'wiki' under sys.prefix+'share/moin'
00044         data_files = makeDataFiles('share/moin', 'wiki')
00045 
00046     For this directory structure:
00047         root
00048             file1
00049             file2
00050             dir
00051                 file
00052                 subdir
00053                     file
00054 
00055     makeDataFiles('prefix', 'root')  will create this distutil data_files structure:
00056         [('prefix', ['file1', 'file2']),
00057          ('prefix/dir', ['file']),
00058          ('prefix/dir/subdir', ['file'])]
00059 
00060     """
00061     # Strip 'dir/' from of path before joining with prefix
00062     dir = dir.rstrip('/')
00063     strip = len(dir) + 1
00064     found = []
00065     os.path.walk(dir, visit, (prefix, strip, found))
00066     return found
00067 
00068 def visit((prefix, strip, found), dirname, names):
00069     """ Visit directory, create distutil tuple
00070 
00071     Add distutil tuple for each directory using this format:
00072         (destination, [dirname/file1, dirname/file2, ...])
00073 
00074     distutil will copy later file1, file2, ... info destination.
00075     """
00076     files = []
00077     # Iterate over a copy of names, modify names
00078     for name in names[:]:
00079         path = os.path.join(dirname, name)
00080         # Ignore directories -  we will visit later
00081         if os.path.isdir(path):
00082             # Remove directories we don't want to visit later
00083             if isbad(name):
00084                 names.remove(name)
00085             continue
00086         elif isgood(name):
00087             files.append(path)
00088     destination = os.path.join(prefix, dirname[strip:])
00089     found.append((destination, files))
00090 
00091 def make_filelist(dir, strip_prefix=''):
00092     """ package_data is pretty stupid: if the globs that can be given there
00093         match a directory, then setup.py install will fall over that later,
00094         because it expects only files.
00095         Use make_filelist(dir, strip) to create a list of all FILES below dir,
00096         stripping off the strip_prefix at the left side.
00097     """
00098     found = []
00099     def _visit((found, strip), dirname, names):
00100         files = []
00101         for name in names:
00102             path = os.path.join(dirname, name)
00103             if os.path.isfile(path):
00104                 if path.startswith(strip):
00105                     path = path[len(strip):]
00106                 files.append(path)
00107         found.extend(files)
00108 
00109     os.path.walk(dir, _visit, (found, strip_prefix))
00110     return found
00111 
00112 #############################################################################
00113 ### Build script files
00114 #############################################################################
00115 
00116 class build_scripts_create(build_scripts):
00117     """ Overload the build_scripts command and create the scripts
00118         from scratch, depending on the target platform.
00119 
00120         You have to define the name of your package in an inherited
00121         class (due to the delayed instantiation of command classes
00122         in distutils, this cannot be passed to __init__).
00123 
00124         The scripts are created in an uniform scheme: they start the
00125         run() function in the module
00126 
00127             <packagename>.script.<mangled_scriptname>
00128 
00129         The mangling of script names replaces '-' and '/' characters
00130         with '-' and '.', so that they are valid module paths.
00131     """
00132     package_name = None
00133 
00134     def copy_scripts(self):
00135         """ Create each script listed in 'self.scripts'
00136         """
00137         if not self.package_name:
00138             raise Exception("You have to inherit build_scripts_create and"
00139                 " provide a package name")
00140 
00141         self.mkpath(self.build_dir)
00142         for script in self.scripts:
00143             outfile = os.path.join(self.build_dir, os.path.basename(script))
00144 
00145             #if not self.force and not newer(script, outfile):
00146             #    self.announce("not copying %s (up-to-date)" % script)
00147             #    continue
00148 
00149             if self.dry_run:
00150                 self.announce("would create %s" % outfile)
00151                 continue
00152 
00153             module = os.path.splitext(os.path.basename(script))[0]
00154             module = module.replace('-', '_').replace('/', '.')
00155             script_vars = {
00156                 'python': os.path.normpath(sys.executable),
00157                 'package': self.package_name,
00158                 'module': module,
00159                 'package_location': '/usr/lib/python/site-packages', # FIXME: we need to know the correct path
00160             }
00161 
00162             self.announce("creating %s" % outfile)
00163             file = open(outfile, 'w')
00164 
00165             try:
00166                 if sys.platform == "win32":
00167                     file.write('@echo off\n'
00168                         'if NOT "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%$\n'
00169                         'if     "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%*\n'
00170                         % script_vars)
00171                 else:
00172                     file.write("#! %(python)s\n"
00173                         "#Fix and uncomment those 2 lines if your moin command doesn't find the MoinMoin package:\n"
00174                         "#import sys\n"
00175                         "#sys.path.insert(0, '%(package_location)s')\n"
00176                         "from %(package)s.script.%(module)s import run\n"
00177                         "run()\n"
00178                         % script_vars)
00179             finally:
00180                 file.close()
00181                 os.chmod(outfile, 0755)
00182 
00183 
00184 class build_scripts_moin(build_scripts_create):
00185     package_name = 'MoinMoin'
00186 
00187 
00188 def scriptname(path):
00189     """ Helper for building a list of script names from a list of
00190         module files.
00191     """
00192     script = os.path.splitext(os.path.basename(path))[0]
00193     script = script.replace('_', '-')
00194     if sys.platform == "win32":
00195         script = script + ".bat"
00196     return script
00197 
00198 # build list of scripts from their implementation modules
00199 moin_scripts = [scriptname(fn) for fn in glob.glob('MoinMoin/script/[!_]*.py')]
00200 
00201 
00202 #############################################################################
00203 ### Call setup()
00204 #############################################################################
00205 
00206 setup_args = {
00207     'name': "moin",
00208     'version': release,
00209     'description': "MoinMoin %s is an easy to use, full-featured and extensible wiki software package" % (release, ),
00210     'author': "Juergen Hermann et al.",
00211     'author_email': "moin-user@lists.sourceforge.net",
00212     # maintainer(_email) not active because distutils/register can't handle author and maintainer at once
00213     'download_url': 'http://static.moinmo.in/files/moin-%s.tar.gz' % (release, ),
00214     'url': "http://moinmo.in/",
00215     'license': "GNU GPL",
00216     'long_description': """
00217     MoinMoin is an easy to use, full-featured and extensible wiki software
00218     package written in Python. It can fulfill a wide range of roles, such as
00219     a personal notes organizer deployed on a laptop or home web server,
00220     a company knowledge base deployed on an intranet, or an Internet server
00221     open to individuals sharing the same interests, goals or projects.""",
00222     'classifiers': """Development Status :: 5 - Production/Stable
00223 Environment :: No Input/Output (Daemon)
00224 Environment :: Web Environment
00225 Environment :: Win32 (MS Windows)
00226 Intended Audience :: Customer Service
00227 Intended Audience :: Developers
00228 Intended Audience :: Education
00229 Intended Audience :: End Users/Desktop
00230 Intended Audience :: Financial and Insurance Industry
00231 Intended Audience :: Healthcare Industry
00232 Intended Audience :: Information Technology
00233 Intended Audience :: Legal Industry
00234 Intended Audience :: Manufacturing
00235 Intended Audience :: Other Audience
00236 Intended Audience :: Religion
00237 Intended Audience :: Science/Research
00238 Intended Audience :: System Administrators
00239 Intended Audience :: Telecommunications Industry
00240 License :: OSI Approved :: GNU General Public License (GPL)
00241 Natural Language :: Chinese (Simplified)
00242 Natural Language :: Chinese (Traditional)
00243 Natural Language :: Danish
00244 Natural Language :: Dutch
00245 Natural Language :: English
00246 Natural Language :: French
00247 Natural Language :: German
00248 Natural Language :: Hebrew
00249 Natural Language :: Hungarian
00250 Natural Language :: Italian
00251 Natural Language :: Javanese
00252 Natural Language :: Korean
00253 Natural Language :: Norwegian
00254 Natural Language :: Russian
00255 Natural Language :: Serbian
00256 Natural Language :: Spanish
00257 Natural Language :: Vietnamese
00258 Operating System :: MacOS :: MacOS X
00259 Operating System :: Microsoft :: Windows
00260 Operating System :: Microsoft :: Windows :: Windows 95/98/2000
00261 Operating System :: Microsoft :: Windows :: Windows NT/2000
00262 Operating System :: OS Independent
00263 Operating System :: POSIX
00264 Operating System :: POSIX :: BSD :: FreeBSD
00265 Operating System :: POSIX :: Linux
00266 Operating System :: Unix
00267 Programming Language :: Python
00268 Topic :: Communications :: Conferencing
00269 Topic :: Internet :: WWW/HTTP :: Dynamic Content
00270 Topic :: Office/Business :: Groupware
00271 Topic :: Text Processing :: Markup""".splitlines(),
00272 
00273     'packages': [
00274         'jabberbot',
00275         'MoinMoin',
00276         'MoinMoin.action',
00277         'MoinMoin.auth',
00278         'MoinMoin.auth.openidrp_ext',
00279         'MoinMoin.config',
00280         'MoinMoin.converter',
00281         'MoinMoin.datastruct',
00282         'MoinMoin.datastruct.backends',
00283         'MoinMoin.events',
00284         'MoinMoin.filter',
00285         'MoinMoin.formatter',
00286         'MoinMoin.i18n',
00287         'MoinMoin.i18n.tools',
00288         'MoinMoin.logfile',
00289         'MoinMoin.macro',
00290         'MoinMoin.mail',
00291         'MoinMoin.parser',
00292         'MoinMoin.script',
00293         'MoinMoin.script.account',
00294         'MoinMoin.script.cli',
00295         'MoinMoin.script.export',
00296         'MoinMoin.script.import',
00297         'MoinMoin.script.index',
00298         'MoinMoin.script.maint',
00299         'MoinMoin.script.migration',
00300         'MoinMoin.script.old',
00301         'MoinMoin.script.old.migration',
00302         'MoinMoin.script.old.xmlrpc-tools',
00303         'MoinMoin.script.server',
00304         'MoinMoin.script.xmlrpc',
00305         'MoinMoin.search',
00306         'MoinMoin.search.Xapian',
00307         'MoinMoin.search.queryparser',
00308         'MoinMoin.security',
00309         'MoinMoin.stats',
00310         'MoinMoin.support',
00311         'MoinMoin.support.flup',
00312         'MoinMoin.support.flup.client',
00313         'MoinMoin.support.flup.server',
00314         'MoinMoin.support.pygments',
00315         'MoinMoin.support.pygments.filters',
00316         'MoinMoin.support.pygments.formatters',
00317         'MoinMoin.support.pygments.lexers',
00318         'MoinMoin.support.pygments.styles',
00319         'MoinMoin.support.werkzeug',
00320         'MoinMoin.support.werkzeug.contrib',
00321         'MoinMoin.support.werkzeug.debug',
00322         'MoinMoin.support.xappy',
00323         'MoinMoin.support.parsedatetime',
00324         'MoinMoin.theme',
00325         'MoinMoin.userform',
00326         'MoinMoin.userprefs',
00327         'MoinMoin.util',
00328         'MoinMoin.web',
00329         'MoinMoin.web.static',
00330         'MoinMoin.widget',
00331         'MoinMoin.wikixml',
00332         'MoinMoin.xmlrpc',
00333 
00334         # all other _tests are missing here, either we have all or nothing:
00335         #'MoinMoin._tests',
00336     ],
00337 
00338     'package_dir': {'MoinMoin.i18n': 'MoinMoin/i18n',
00339                     'MoinMoin.web.static': 'MoinMoin/web/static',
00340                    },
00341     'package_data': {'MoinMoin.i18n': ['README', 'Makefile', 'MoinMoin.pot', 'POTFILES.in',
00342                                        '*.po',
00343                                        'tools/*',
00344                                        'jabberbot/*',
00345                                       ],
00346                      'MoinMoin.web.static': make_filelist('MoinMoin/web/static/htdocs',
00347                                                           strip_prefix='MoinMoin/web/static/'),
00348                     },
00349 
00350     # Override certain command classes with our own ones
00351     'cmdclass': {
00352         'build_scripts': build_scripts_moin,
00353     },
00354 
00355     'scripts': moin_scripts,
00356 
00357     # This copies the contents of wiki dir under sys.prefix/share/moin
00358     # Do not put files that should not be installed in the wiki dir, or
00359     # clean the dir before you make the distribution tarball.
00360     'data_files': makeDataFiles('share/moin', 'wiki')
00361 }
00362 
00363 if hasattr(distutils.dist.DistributionMetadata, 'get_keywords'):
00364     setup_args['keywords'] = "wiki web"
00365 
00366 if hasattr(distutils.dist.DistributionMetadata, 'get_platforms'):
00367     setup_args['platforms'] = "any"
00368 
00369 
00370 if __name__ == '__main__':
00371     try:
00372         setup(**setup_args)
00373     except distutils.errors.DistutilsPlatformError, ex:
00374         print
00375         print str(ex)
00376 
00377         print """
00378 POSSIBLE CAUSE
00379 
00380 "distutils" often needs developer support installed to work
00381 correctly, which is usually located in a separate package
00382 called "python%d.%d-dev(el)".
00383 
00384 Please contact the system administrator to have it installed.
00385 """ % sys.version_info[:2]
00386         sys.exit(1)
00387