setup.py
author Reimar Bauer <rb.proj AT googlemail DOT com>
Mon, 19 Jan 2009 01:20:04 +0100
changeset 4247 c76d50dac855
parent 3439 b9879146620d
permissions -rw-r--r--
text_html_text_moin_wiki: bug fix for GuiEditorBreaksIndentedTable
tw-public@0
     1
#!/usr/bin/env python
tw-public@0
     2
# -*- coding: iso-8859-1 -*-
tw-public@0
     3
"""
tw-public@0
     4
    MoinMoin installer
tw-public@0
     5
tw@1179
     6
    @copyright: 2001-2005 by Jürgen Hermann <jh@web.de>,
tw@3115
     7
                2006-2007 by MoinMoin:ThomasWaldmann
tw-public@0
     8
    @license: GNU GPL, see COPYING for details.
tw-public@0
     9
"""
tw-public@0
    10
tw@1180
    11
import os, sys, glob
tw-public@0
    12
tw-public@0
    13
import distutils
tw-public@0
    14
from distutils.core import setup
tw-public@0
    15
from distutils.command.build_scripts import build_scripts
tw-public@0
    16
tw-public@0
    17
from MoinMoin.version import release, revision
tw-public@0
    18
tw@933
    19
# we need this for distutils from python 2.3 compatibility, python 2.4 has the
tw@2286
    20
# 'package_data' keyword to the 'setup' function to install data in packages
tw@933
    21
# see http://wiki.python.org/moin/DistutilsInstallDataScattered
tw@933
    22
from distutils.command.install_data import install_data
tw@933
    23
class smart_install_data(install_data):
tw@933
    24
    def run(self):
tw@933
    25
        i18n_data_files = [(target, files) for (target, files) in self.data_files if target.startswith('MoinMoin/i18n')]
tw@933
    26
        share_data_files = [(target, files) for (target, files) in self.data_files if target.startswith('share/moin')]
tw@933
    27
        # first install the share/moin stuff:
tw@933
    28
        self.data_files = share_data_files
tw@933
    29
        install_data.run(self)
tw@933
    30
        # now we need to install the *.po files to the package dir:
tw@933
    31
        # need to change self.install_dir to the library dir
tw@933
    32
        install_cmd = self.get_finalized_command('install')
tw@933
    33
        self.install_dir = getattr(install_cmd, 'install_lib')
tw@933
    34
        self.data_files = i18n_data_files
tw@933
    35
        return install_data.run(self)
tw-public@0
    36
tw-public@0
    37
#############################################################################
tw-public@0
    38
### Helpers
tw-public@0
    39
#############################################################################
tw-public@0
    40
tw-public@0
    41
def isbad(name):
tw-public@0
    42
    """ Whether name should not be installed """
tw-public@0
    43
    return (name.startswith('.') or
tw-public@0
    44
            name.startswith('#') or
tw-public@0
    45
            name.endswith('.pickle') or
tw-public@0
    46
            name == 'CVS')
tw-public@0
    47
tw-public@0
    48
def isgood(name):
tw-public@0
    49
    """ Whether name should be installed """
tw-public@0
    50
    return not isbad(name)
tw-public@0
    51
tw-public@0
    52
def makeDataFiles(prefix, dir):
tw-public@0
    53
    """ Create distutils data_files structure from dir
tw-public@0
    54
tw-public@0
    55
    distutil will copy all file rooted under dir into prefix, excluding
tw-public@0
    56
    dir itself, just like 'ditto src dst' works, and unlike 'cp -r src
tw-public@0
    57
    dst, which copy src into dst'.
tw-public@0
    58
tw-public@0
    59
    Typical usage:
tw-public@0
    60
        # install the contents of 'wiki' under sys.prefix+'share/moin'
tw-public@0
    61
        data_files = makeDataFiles('share/moin', 'wiki')
tw-public@0
    62
tw-public@0
    63
    For this directory structure:
tw-public@0
    64
        root
tw-public@0
    65
            file1
tw-public@0
    66
            file2
tw-public@0
    67
            dir
tw-public@0
    68
                file
tw-public@0
    69
                subdir
tw-public@0
    70
                    file
tw-public@0
    71
tw-public@0
    72
    makeDataFiles('prefix', 'root')  will create this distutil data_files structure:
tw-public@0
    73
        [('prefix', ['file1', 'file2']),
tw-public@0
    74
         ('prefix/dir', ['file']),
tw-public@0
    75
         ('prefix/dir/subdir', ['file'])]
tw-public@0
    76
tw-public@0
    77
    """
tw-public@0
    78
    # Strip 'dir/' from of path before joining with prefix
tw-public@0
    79
    dir = dir.rstrip('/')
tw-public@0
    80
    strip = len(dir) + 1
tw-public@0
    81
    found = []
tw@933
    82
    os.path.walk(dir, visit, (prefix, strip, found))
tw-public@0
    83
    return found
tw-public@0
    84
tw-public@0
    85
def visit((prefix, strip, found), dirname, names):
tw-public@0
    86
    """ Visit directory, create distutil tuple
tw-public@0
    87
tw-public@0
    88
    Add distutil tuple for each directory using this format:
tw-public@0
    89
        (destination, [dirname/file1, dirname/file2, ...])
tw-public@0
    90
tw-public@0
    91
    distutil will copy later file1, file2, ... info destination.
tw-public@0
    92
    """
tw-public@0
    93
    files = []
tw-public@0
    94
    # Iterate over a copy of names, modify names
tw-public@0
    95
    for name in names[:]:
tw-public@0
    96
        path = os.path.join(dirname, name)
tw-public@0
    97
        # Ignore directories -  we will visit later
tw-public@0
    98
        if os.path.isdir(path):
tw-public@0
    99
            # Remove directories we don't want to visit later
tw-public@0
   100
            if isbad(name):
tw-public@0
   101
                names.remove(name)
tw-public@0
   102
            continue
tw-public@0
   103
        elif isgood(name):
tw-public@0
   104
            files.append(path)
tw-public@0
   105
    destination = os.path.join(prefix, dirname[strip:])
tw-public@0
   106
    found.append((destination, files))
tw@933
   107
tw-public@0
   108
tw-public@0
   109
#############################################################################
tw-public@0
   110
### Build script files
tw-public@0
   111
#############################################################################
tw-public@0
   112
tw-public@0
   113
class build_scripts_create(build_scripts):
tw-public@0
   114
    """ Overload the build_scripts command and create the scripts
tw-public@0
   115
        from scratch, depending on the target platform.
tw-public@0
   116
tw-public@0
   117
        You have to define the name of your package in an inherited
tw-public@0
   118
        class (due to the delayed instantiation of command classes
tw-public@0
   119
        in distutils, this cannot be passed to __init__).
tw-public@0
   120
tw-public@0
   121
        The scripts are created in an uniform scheme: they start the
tw-public@0
   122
        run() function in the module
tw-public@0
   123
tw@497
   124
            <packagename>.script.<mangled_scriptname>
tw-public@0
   125
tw-public@0
   126
        The mangling of script names replaces '-' and '/' characters
tw@2286
   127
        with '-' and '.', so that they are valid module paths.
tw-public@0
   128
    """
tw-public@0
   129
    package_name = None
tw-public@0
   130
tw-public@0
   131
    def copy_scripts(self):
tw-public@0
   132
        """ Create each script listed in 'self.scripts'
tw-public@0
   133
        """
tw-public@0
   134
        if not self.package_name:
tw-public@0
   135
            raise Exception("You have to inherit build_scripts_create and"
tw-public@0
   136
                " provide a package name")
tw@933
   137
tw-public@0
   138
        self.mkpath(self.build_dir)
tw-public@0
   139
        for script in self.scripts:
tw-public@0
   140
            outfile = os.path.join(self.build_dir, os.path.basename(script))
tw-public@0
   141
tw-public@0
   142
            #if not self.force and not newer(script, outfile):
tw-public@0
   143
            #    self.announce("not copying %s (up-to-date)" % script)
tw-public@0
   144
            #    continue
tw-public@0
   145
tw-public@0
   146
            if self.dry_run:
tw-public@0
   147
                self.announce("would create %s" % outfile)
tw-public@0
   148
                continue
tw-public@0
   149
tw-public@0
   150
            module = os.path.splitext(os.path.basename(script))[0]
tw@1180
   151
            module = module.replace('-', '_').replace('/', '.')
tw-public@0
   152
            script_vars = {
tw-public@0
   153
                'python': os.path.normpath(sys.executable),
tw-public@0
   154
                'package': self.package_name,
tw-public@0
   155
                'module': module,
tw@1832
   156
                'package_location': '/usr/lib/python/site-packages', # FIXME: we need to know the correct path
tw-public@0
   157
            }
tw-public@0
   158
tw-public@0
   159
            self.announce("creating %s" % outfile)
tw-public@0
   160
            file = open(outfile, 'w')
tw-public@0
   161
tw-public@0
   162
            try:
tw-public@0
   163
                if sys.platform == "win32":
tw-public@0
   164
                    file.write('@echo off\n'
tw@497
   165
                        'if NOT "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%$\n'
tw@497
   166
                        'if     "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%*\n'
tw-public@0
   167
                        % script_vars)
tw-public@0
   168
                else:
tw@778
   169
                    file.write("#! %(python)s\n"
tw@778
   170
                        "#Fix and uncomment those 2 lines if your moin command doesn't find the MoinMoin package:\n"
tw@778
   171
                        "#import sys\n"
tw@778
   172
                        "#sys.path.insert(0, '%(package_location)s')\n"
tw@778
   173
                        "from %(package)s.script.%(module)s import run\n"
tw@778
   174
                        "run()\n"
tw-public@0
   175
                        % script_vars)
tw-public@0
   176
            finally:
tw-public@0
   177
                file.close()
tw-public@0
   178
                os.chmod(outfile, 0755)
tw-public@0
   179
tw-public@0
   180
tw-public@0
   181
class build_scripts_moin(build_scripts_create):
tw-public@0
   182
    package_name = 'MoinMoin'
tw-public@0
   183
tw-public@0
   184
tw-public@0
   185
def scriptname(path):
tw-public@0
   186
    """ Helper for building a list of script names from a list of
tw-public@0
   187
        module files.
tw-public@0
   188
    """
tw-public@0
   189
    script = os.path.splitext(os.path.basename(path))[0]
tw@1180
   190
    script = script.replace('_', '-')
tw-public@0
   191
    if sys.platform == "win32":
tw-public@0
   192
        script = script + ".bat"
tw-public@0
   193
    return script
tw-public@0
   194
tw-public@0
   195
# build list of scripts from their implementation modules
tw@1866
   196
moin_scripts = [scriptname(fn) for fn in glob.glob('MoinMoin/script/[!_]*.py')]
tw-public@0
   197
tw-public@0
   198
tw-public@0
   199
#############################################################################
tw-public@0
   200
### Call setup()
tw-public@0
   201
#############################################################################
tw-public@0
   202
tw-public@0
   203
setup_args = {
tw@3439
   204
    'name': "moin",
tw-public@0
   205
    'version': release,
alex@3276
   206
    'description': "MoinMoin %s is an easy to use, full-featured and extensible wiki software package" % (release, ),
alex@3276
   207
    'author': "Juergen Hermann et al.",
alex@3276
   208
    'author_email': "moin-user@lists.sourceforge.net",
tw@3434
   209
    # maintainer(_email) not active because distutils/register can't handle author and maintainer at once
tw@3434
   210
    'download_url': 'http://static.moinmo.in/files/moin-%s.tar.gz' % (release, ),
tw@3115
   211
    'url': "http://moinmo.in/",
tw-public@0
   212
    'license': "GNU GPL",
tw-public@0
   213
    'long_description': """
alex@3276
   214
    MoinMoin is an easy to use, full-featured and extensible wiki software
alex@3276
   215
    package written in Python. It can fulfill a wide range of roles, such as
alex@3276
   216
    a personal notes organizer deployed on a laptop or home web server,
alex@3276
   217
    a company knowledge base deployed on an intranet, or an Internet server
alex@3276
   218
    open to individuals sharing the same interests, goals or projects.""",
alex@3276
   219
    'classifiers': """Development Status :: 5 - Production/Stable
alex@3276
   220
Environment :: No Input/Output (Daemon)
alex@3276
   221
Environment :: Web Environment
alex@3276
   222
Environment :: Win32 (MS Windows)
alex@3276
   223
Intended Audience :: Customer Service
alex@3276
   224
Intended Audience :: Developers
alex@3276
   225
Intended Audience :: Education
alex@3276
   226
Intended Audience :: End Users/Desktop
alex@3276
   227
Intended Audience :: Financial and Insurance Industry
alex@3276
   228
Intended Audience :: Healthcare Industry
alex@3276
   229
Intended Audience :: Information Technology
alex@3276
   230
Intended Audience :: Legal Industry
alex@3276
   231
Intended Audience :: Manufacturing
alex@3276
   232
Intended Audience :: Other Audience
alex@3276
   233
Intended Audience :: Religion
alex@3276
   234
Intended Audience :: Science/Research
alex@3276
   235
Intended Audience :: System Administrators
alex@3276
   236
Intended Audience :: Telecommunications Industry
alex@3276
   237
License :: OSI Approved :: GNU General Public License (GPL)
alex@3276
   238
Natural Language :: Chinese (Simplified)
alex@3276
   239
Natural Language :: Chinese (Traditional)
alex@3276
   240
Natural Language :: Danish
alex@3276
   241
Natural Language :: Dutch
alex@3276
   242
Natural Language :: English
alex@3276
   243
Natural Language :: French
alex@3276
   244
Natural Language :: German
alex@3276
   245
Natural Language :: Hebrew
alex@3276
   246
Natural Language :: Hungarian
alex@3276
   247
Natural Language :: Italian
alex@3276
   248
Natural Language :: Javanese
alex@3276
   249
Natural Language :: Korean
alex@3276
   250
Natural Language :: Norwegian
alex@3276
   251
Natural Language :: Russian
alex@3276
   252
Natural Language :: Serbian
alex@3276
   253
Natural Language :: Spanish
alex@3276
   254
Natural Language :: Vietnamese
alex@3276
   255
Operating System :: MacOS :: MacOS X
alex@3276
   256
Operating System :: Microsoft :: Windows
alex@3276
   257
Operating System :: Microsoft :: Windows :: Windows 95/98/2000
alex@3276
   258
Operating System :: Microsoft :: Windows :: Windows NT/2000
alex@3276
   259
Operating System :: OS Independent
alex@3276
   260
Operating System :: POSIX
alex@3276
   261
Operating System :: POSIX :: BSD :: FreeBSD
alex@3276
   262
Operating System :: POSIX :: Linux
alex@3276
   263
Operating System :: Unix
alex@3276
   264
Programming Language :: Python
alex@3276
   265
Topic :: Communications :: Conferencing
alex@3276
   266
Topic :: Internet :: WWW/HTTP :: Dynamic Content
alex@3276
   267
Topic :: Office/Business :: Groupware
alex@3276
   268
Topic :: Text Processing :: Markup""".splitlines(),
alex@3276
   269
tw-public@0
   270
    'packages': [
tw@3537
   271
        'jabberbot',
tw-public@0
   272
        'MoinMoin',
tw-public@0
   273
        'MoinMoin.action',
tw@878
   274
        'MoinMoin.auth',
tw@1060
   275
        'MoinMoin.config',
tw-public@0
   276
        'MoinMoin.converter',
florian@2598
   277
        'MoinMoin.events',
tw@497
   278
        'MoinMoin.filter',
tw-public@0
   279
        'MoinMoin.formatter',
tw-public@0
   280
        'MoinMoin.i18n',
tw@686
   281
        'MoinMoin.i18n.tools',
tw-public@0
   282
        'MoinMoin.logfile',
tw-public@0
   283
        'MoinMoin.macro',
tw@878
   284
        'MoinMoin.mail',
tw-public@0
   285
        'MoinMoin.parser',
tw@654
   286
        'MoinMoin.request',
tw@497
   287
        'MoinMoin.script',
tw@501
   288
        'MoinMoin.script.account',
tw@497
   289
        'MoinMoin.script.cli',
tw@554
   290
        'MoinMoin.script.export',
tw@554
   291
        'MoinMoin.script.import',
fpletz@807
   292
        'MoinMoin.script.index',
tw@503
   293
        'MoinMoin.script.maint',
tw@497
   294
        'MoinMoin.script.migration',
tw@498
   295
        'MoinMoin.script.old',
tw@499
   296
        'MoinMoin.script.old.migration',
tw@498
   297
        'MoinMoin.script.old.xmlrpc-tools',
tw@3025
   298
        'MoinMoin.script.server',
tw@1185
   299
        'MoinMoin.script.xmlrpc',
tw@1156
   300
        'MoinMoin.search',
tw@746
   301
        'MoinMoin.security',
tw-public@0
   302
        'MoinMoin.server',
tw-public@0
   303
        'MoinMoin.stats',
tw-public@0
   304
        'MoinMoin.support',
fpletz@804
   305
        'MoinMoin.support.xapwrap',
fpletz@1472
   306
        'MoinMoin.support.parsedatetime',
tw-public@0
   307
        'MoinMoin.theme',
tw@3130
   308
        'MoinMoin.userform',
tw@3130
   309
        'MoinMoin.userprefs',
tw-public@0
   310
        'MoinMoin.util',
tw-public@0
   311
        'MoinMoin.widget',
tw-public@0
   312
        'MoinMoin.wikixml',
tw-public@0
   313
        'MoinMoin.xmlrpc',
tw-public@0
   314
tw@3090
   315
        # all other _tests are missing here, either we have all or nothing:
tw@3090
   316
        #'MoinMoin._tests',
tw-public@0
   317
    ],
tw-public@0
   318
tw@933
   319
    # We can use package_* instead of the smart_install_data hack when we
tw@933
   320
    # require Python 2.4.
tw@933
   321
    #'package_dir': { 'MoinMoin.i18n': 'MoinMoin/i18n', },
tw@933
   322
    #'package_data': { 'MoinMoin.i18n': ['README', 'Makefile', 'MoinMoin.pot', 'POTFILES.in',
tw@933
   323
    #                                    '*.po',
tw@933
   324
    #                                    'tools/*',], },
tw@757
   325
tw-public@0
   326
    # Override certain command classes with our own ones
tw-public@0
   327
    'cmdclass': {
tw-public@0
   328
        'build_scripts': build_scripts_moin,
tw@933
   329
        'install_data': smart_install_data, # hack needed for 2.3
tw-public@0
   330
    },
tw-public@0
   331
tw-public@0
   332
    'scripts': moin_scripts,
tw-public@0
   333
tw@933
   334
    # This copies the contents of wiki dir under sys.prefix/share/moin
tw-public@0
   335
    # Do not put files that should not be installed in the wiki dir, or
tw-public@0
   336
    # clean the dir before you make the distribution tarball.
tw@933
   337
    'data_files': makeDataFiles('share/moin', 'wiki') + makeDataFiles('MoinMoin/i18n', 'MoinMoin/i18n')
tw-public@0
   338
}
tw-public@0
   339
tw-public@0
   340
if hasattr(distutils.dist.DistributionMetadata, 'get_keywords'):
tw-public@0
   341
    setup_args['keywords'] = "wiki web"
tw-public@0
   342
tw-public@0
   343
if hasattr(distutils.dist.DistributionMetadata, 'get_platforms'):
alex@3276
   344
    setup_args['platforms'] = "any"
tw-public@0
   345
tw-public@0
   346
tw-public@0
   347
try:
tw@1869
   348
    setup(**setup_args)
tw-public@0
   349
except distutils.errors.DistutilsPlatformError, ex:
tw-public@0
   350
    print
tw-public@0
   351
    print str(ex)
tw@933
   352
tw-public@0
   353
    print """
tw-public@0
   354
POSSIBLE CAUSE
tw-public@0
   355
tw-public@0
   356
"distutils" often needs developer support installed to work
tw@2286
   357
correctly, which is usually located in a separate package
tw-public@0
   358
called "python%d.%d-dev(el)".
tw-public@0
   359
tw-public@0
   360
Please contact the system administrator to have it installed.
tw-public@0
   361
""" % sys.version_info[:2]
tw-public@0
   362
    sys.exit(1)
tw-public@0
   363