13
if sys.version_info < (2, 4):
14
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.4+\n")
17
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
18
# './setup.py' or the equivalent with another path, should always be at the
19
# start of the path, so this should find the right one...
22
def get_long_description():
23
dirname = os.path.dirname(__file__)
24
readme = os.path.join(dirname, 'README')
25
f = open(readme, 'rb')
15
33
# META INFORMATION FOR SETUP
17
META_INFO = {'name': 'bzr',
18
'version': bzrlib.__version__,
19
'author': 'Canonical Ltd',
20
'author_email': 'bazaar-ng@lists.ubuntu.com',
21
'url': 'http://www.bazaar-vcs.org/',
22
'description': 'Friendly distributed version control system',
23
'license': 'GNU GPL v2',
34
# see http://docs.python.org/dist/meta-data.html
37
'version': bzrlib.__version__,
38
'author': 'Canonical Ltd',
39
'author_email': 'bazaar@lists.canonical.com',
40
'url': 'http://www.bazaar-vcs.org/',
41
'description': 'Friendly distributed version control system',
42
'license': 'GNU GPL v2',
43
'download_url': 'http://bazaar-vcs.org/Download',
44
'long_description': get_long_description(),
46
'Development Status :: 6 - Mature',
47
'Environment :: Console',
48
'Intended Audience :: Developers',
49
'Intended Audience :: System Administrators',
50
'License :: OSI Approved :: GNU General Public License (GPL)',
51
'Operating System :: Microsoft :: Windows',
52
'Operating System :: OS Independent',
53
'Operating System :: POSIX',
54
'Programming Language :: Python',
55
'Programming Language :: C',
56
'Topic :: Software Development :: Version Control',
26
60
# The list of packages is automatically generated later. Add other things
27
61
# that are part of BZRLIB here.
150
156
########################
158
command_classes = {'install_scripts': my_install_scripts,
160
from distutils import log
161
from distutils.errors import CCompilerError, DistutilsPlatformError
162
from distutils.extension import Extension
165
from Pyrex.Distutils import build_ext
168
# try to build the extension from the prior generated source.
170
print ("The python package 'Pyrex' is not available."
171
" If the .c files are available,")
172
print ("they will be built,"
173
" but modifying the .pyx files will not rebuild them.")
175
from distutils.command.build_ext import build_ext
180
class build_ext_if_possible(build_ext):
185
except DistutilsPlatformError, e:
187
log.warn('Extensions cannot be built, '
188
'will use the Python versions instead')
190
def build_extension(self, ext):
192
build_ext.build_extension(self, ext)
193
except CCompilerError:
194
log.warn('Building of "%s" extension failed, '
195
'will use the Python version instead' % (ext.name,))
198
# Override the build_ext if we have Pyrex available
199
command_classes['build_ext'] = build_ext_if_possible
200
unavailable_files = []
203
def add_pyrex_extension(module_name, **kwargs):
204
"""Add a pyrex module to build.
206
This will use Pyrex to auto-generate the .c file if it is available.
207
Otherwise it will fall back on the .c file. If the .c file is not
208
available, it will warn, and not add anything.
210
You can pass any extra options to Extension through kwargs. One example is
213
:param module_name: The python path to the module. This will be used to
214
determine the .pyx and .c files to use.
216
path = module_name.replace('.', '/')
217
pyrex_name = path + '.pyx'
220
ext_modules.append(Extension(module_name, [pyrex_name], **kwargs))
222
if not os.path.isfile(c_name):
223
unavailable_files.append(c_name)
225
ext_modules.append(Extension(module_name, [c_name], **kwargs))
228
add_pyrex_extension('bzrlib._dirstate_helpers_c')
229
add_pyrex_extension('bzrlib._knit_load_data_c')
230
if sys.platform == 'win32':
231
# pyrex uses the macro WIN32 to detect the platform, even though it should
232
# be using something like _WIN32 or MS_WINDOWS, oh well, we can give it the
234
add_pyrex_extension('bzrlib._walkdirs_win32',
235
define_macros=[('WIN32', None)])
236
ext_modules.append(Extension('bzrlib._patiencediff_c', ['bzrlib/_patiencediff_c.c']))
239
if unavailable_files:
240
print 'C extension(s) not found:'
241
print ' %s' % ('\n '.join(unavailable_files),)
242
print 'The python versions will be used instead.'
246
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
248
packages.append('tbzrcommands')
250
# ModuleFinder can't handle runtime changes to __path__, but
251
# win32com uses them. Hook this in so win32com.shell is found.
254
for p in win32com.__path__[1:]:
255
modulefinder.AddPackagePath("win32com", p)
256
for extra in ["win32com.shell"]:
258
m = sys.modules[extra]
259
for p in m.__path__[1:]:
260
modulefinder.AddPackagePath(extra, p)
262
# TBZR points to the TBZR directory
263
tbzr_root = os.environ["TBZR"]
265
# Ensure tbzrlib itself is on sys.path
266
sys.path.append(tbzr_root)
268
# Ensure our COM "entry-point" is on sys.path
269
sys.path.append(os.path.join(tbzr_root, "shellext", "python"))
271
packages.append("tbzrlib")
272
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
273
win32ui crawler.Crawler""".split())
277
create_exe = False, # we only want a .dll
279
com_targets.append(tbzr)
281
# tbzrcache executables - a "console" version for debugging and a
282
# GUI version that is generally used.
284
script = os.path.join(tbzr_root, "Scripts", "tbzrcache.py"),
285
icon_resources = [(0,'bzr.ico')],
287
console_targets.append(tbzrcache)
289
# Make a windows version which is the same except for the base name.
290
tbzrcachew = tbzrcache.copy()
291
tbzrcachew["dest_base"]="tbzrcachew"
292
gui_targets.append(tbzrcachew)
294
# ditto for the tbzrcommand tool
296
script = os.path.join(tbzr_root, "Scripts", "tbzrcommand.py"),
297
icon_resources = [(0,'bzr.ico')],
299
console_targets.append(tbzrcommand)
300
tbzrcommandw = tbzrcommand.copy()
301
tbzrcommandw["dest_base"]="tbzrcommandw"
302
gui_targets.append(tbzrcommandw)
306
script = os.path.join(tbzr_root, "Scripts", "tbzrtest.py"),
308
console_targets.append(tbzrtest)
310
# A utility to see python output from the shell extension - this will
311
# die when we get a c++ extension
312
# any .py file from pywin32's win32 lib will do (other than
313
# win32traceutil itself that is)
315
win32_lib_dir = os.path.dirname(winerror.__file__)
316
tracer = dict(script = os.path.join(win32_lib_dir, "win32traceutil.py"),
317
dest_base="tbzr_tracer")
318
console_targets.append(tracer)
321
def get_qbzr_py2exe_info(includes, excludes, packages):
322
# PyQt4 itself still escapes the plugin detection code for some reason...
323
packages.append('PyQt4')
324
excludes.append('PyQt4.elementtree.ElementTree')
325
includes.append('sip') # extension module required for Qt.
326
packages.append('pygments') # colorizer for qbzr
327
# but we can avoid many Qt4 Dlls.
329
"""QtAssistantClient4.dll QtCLucene4.dll QtDesigner4.dll
330
QtHelp4.dll QtNetwork4.dll QtOpenGL4.dll QtScript4.dll
331
QtSql4.dll QtTest4.dll QtWebKit4.dll QtXml4.dll
332
qscintilla2.dll""".split())
333
# the qt binaries might not be on PATH...
334
qt_dir = os.path.join(sys.prefix, "PyQt4", "bin")
335
path = os.environ.get("PATH","")
336
if qt_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
337
os.environ["PATH"] = path + os.pathsep + qt_dir
152
340
if 'bdist_wininst' in sys.argv:
155
docs = glob.glob('doc/*.htm') + ['doc/default.css']
343
for root, dirs, files in os.walk('doc'):
346
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
347
or f == 'quick-start-summary.svg'):
348
r.append(os.path.join(root, f))
352
target = os.path.join('Doc\\Bazaar', relative)
354
target = 'Doc\\Bazaar'
355
docs.append((target, r))
156
358
# python's distutils-based win32 installer
157
359
ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
360
'ext_modules': ext_modules,
159
'data_files': [('Doc/Bazaar', docs)],
362
'data_files': find_docs(),
363
# for building pyrex extensions
364
'cmdclass': {'build_ext': build_ext_if_possible},
162
367
ARGS.update(META_INFO)
188
418
version = version_str,
189
419
description = META_INFO['description'],
190
420
author = META_INFO['author'],
191
copyright = "(c) Canonical Ltd, 2005-2006",
421
copyright = "(c) Canonical Ltd, 2005-2007",
192
422
company_name = "Canonical Ltd.",
193
423
comments = META_INFO['description'],
195
options_list = {"py2exe": {"packages": BZRLIB['packages'] +
197
"excludes": ["Tkinter", "medusa"],
426
packages = BZRLIB['packages']
427
packages.remove('bzrlib')
428
packages = [i for i in packages if not i.startswith('bzrlib.plugins')]
430
for i in glob.glob('bzrlib\\*.py'):
431
module = i[:-3].replace('\\', '.')
432
if module.endswith('__init__'):
433
module = module[:-len('__init__')]
434
includes.append(module)
436
additional_packages = set()
437
if sys.version.startswith('2.4'):
438
# adding elementtree package
439
additional_packages.add('elementtree')
440
elif sys.version.startswith('2.5'):
441
additional_packages.add('xml.etree')
444
warnings.warn('Unknown Python version.\n'
445
'Please check setup.py script for compatibility.')
447
# Although we currently can't enforce it, we consider it an error for
448
# py2exe to report any files are "missing". Such modules we know aren't
449
# used should be listed here.
450
excludes = """Tkinter psyco ElementPath r_hmac
451
ImaginaryModule cElementTree elementtree.ElementTree
452
Crypto.PublicKey._fastmath
453
medusa medusa.filesys medusa.ftp_server
454
tools tools.doc_generate
455
resource validate""".split()
458
# email package from std python library use lazy import,
459
# so we need to explicitly add all package
460
additional_packages.add('email')
461
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
462
# a result, packages like 'email.Parser' show as missing. Tell py2exe
465
for oldname in getattr(email, '_LOWERNAMES', []):
466
excludes.append("email." + oldname)
467
for oldname in getattr(email, '_MIMENAMES', []):
468
excludes.append("email.MIME" + oldname)
470
# text files for help topis
471
text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
472
topics_files = [('lib/help_topics/en', text_topics)]
476
# XXX - should we consider having the concept of an 'official' build,
477
# which hard-codes the list of plugins, gets more upset if modules are
479
plugins = None # will be a set after plugin sniffing...
480
for root, dirs, files in os.walk('bzrlib/plugins'):
481
if root == 'bzrlib/plugins':
485
if os.path.splitext(i)[1] not in [".py", ".pyd", ".dll"]:
487
if i == '__init__.py' and root == 'bzrlib/plugins':
489
x.append(os.path.join(root, i))
491
target_dir = root[len('bzrlib/'):] # install to 'plugins/...'
492
plugins_files.append((target_dir, x))
493
# find modules for built-in plugins
494
import tools.package_mf
495
mf = tools.package_mf.CustomModuleFinder()
496
mf.run_package('bzrlib/plugins')
497
packs, mods = mf.get_result()
498
additional_packages.update(packs)
499
includes.extend(mods)
501
console_targets = [target,
502
'tools/win32/bzr_postinstall.py',
507
if 'qbzr' in plugins:
508
get_qbzr_py2exe_info(includes, excludes, packages)
510
if "TBZR" in os.environ:
511
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
512
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
513
# can be downloaded from (username=guest, blank password):
514
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays/version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
515
if not os.path.isfile(os.environ.get('TORTOISE_OVERLAYS_MSI_WIN32',
517
raise RuntimeError("Please set TORTOISE_OVERLAYS_MSI_WIN32 to the"
518
" location of the Win32 TortoiseOverlays .msi"
520
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
523
# print this warning to stderr as output is redirected, so it is seen
524
# at build time. Also to stdout so it appears in the log
525
for f in (sys.stderr, sys.stdout):
527
"Skipping TBZR binaries - please set TBZR to a directory to enable"
529
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
531
dll_excludes.append("MSWSOCK.dll")
532
options_list = {"py2exe": {"packages": packages + list(additional_packages),
533
"includes": includes,
534
"excludes": excludes,
535
"dll_excludes": dll_excludes,
198
536
"dist_dir": "win32_bzr.exe",
201
541
setup(options=options_list,
203
'tools/win32/bzr_postinstall.py',
205
zipfile='lib/library.zip')
542
console=console_targets,
544
com_server=com_targets,
545
zipfile='lib/library.zip',
546
data_files=topics_files + plugins_files,
547
cmdclass={'install_data': install_data_with_bytecompile},
551
# ad-hoc for easy_install
553
if not 'bdist_egg' in sys.argv:
554
# generate and install bzr.1 only with plain install, not easy_install one
555
DATA_FILES = [('man/man1', ['bzr.1'])]
209
558
ARGS = {'scripts': ['bzr'],
210
'data_files': [('man/man1', ['bzr.1'])],
211
'cmdclass': {'build': bzr_build,
212
'install_scripts': my_install_scripts,
559
'data_files': DATA_FILES,
560
'cmdclass': command_classes,
561
'ext_modules': ext_modules,
216
564
ARGS.update(META_INFO)
217
565
ARGS.update(BZRLIB)
218
566
ARGS.update(PKG_DATA)