|
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 |
|