1
1
#! /usr/bin/env python
3
# This is an installation script for bzr. Run it with
4
# './setup.py install', or
5
# './setup.py --help' for more options
7
# Reinvocation stolen from bzr, we need python2.4 by virtue of bzr_man
8
# including bzrlib.help
13
version_info = sys.version_info
14
except AttributeError:
15
version_info = 1, 5 # 1.5 or older
17
REINVOKE = "__BZR_REINVOKE"
19
KNOWN_PYTHONS = ('python2.4',)
21
if version_info < NEED_VERS:
22
if not os.environ.has_key(REINVOKE):
23
# mutating os.environ doesn't work in old Pythons
24
os.putenv(REINVOKE, "1")
25
for python in KNOWN_PYTHONS:
27
os.execvp(python, [python] + sys.argv)
30
print >>sys.stderr, "bzr: error: cannot find a suitable python interpreter"
31
print >>sys.stderr, " (need %d.%d or later)" % NEED_VERS
3
"""Installation script for brz.
5
'./setup.py install', or
6
'./setup.py --help' for more options
15
if sys.version_info < (2, 7):
16
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.7+\n")
33
if hasattr(os, "unsetenv"):
19
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
20
# './setup.py' or the equivalent with another path, should always be at the
21
# start of the path, so this should find the right one...
24
def get_long_description():
25
dirname = os.path.dirname(__file__)
26
readme = os.path.join(dirname, 'README')
27
f = open(readme, 'rb')
35
# META INFORMATION FOR SETUP
36
# see http://docs.python.org/dist/meta-data.html
39
'version': breezy.__version__,
40
'maintainer': 'Breezy Developers',
41
'maintainer_email': 'team@breezy-vcs.org',
42
'url': 'https://www.breezy-vcs.org/',
43
'description': 'Friendly distributed version control system',
44
'license': 'GNU GPL v2',
45
'download_url': 'https://launchpad.net/brz/+download',
46
'long_description': get_long_description(),
48
'Development Status :: 6 - Mature',
49
'Environment :: Console',
50
'Intended Audience :: Developers',
51
'Intended Audience :: System Administrators',
52
'License :: OSI Approved :: GNU General Public License (GPL)',
53
'Operating System :: Microsoft :: Windows',
54
'Operating System :: OS Independent',
55
'Operating System :: POSIX',
56
'Programming Language :: Python',
57
'Programming Language :: C',
58
'Topic :: Software Development :: Version Control',
62
# The list of packages is automatically generated later. Add other things
63
# that are part of BZRLIB here.
66
PKG_DATA = {# install files from selftest suite
67
'package_data': {'breezy': ['doc/api/*.txt',
68
'tests/test_patches_data/*',
69
'help_topics/en/*.txt',
70
'tests/ssl_certs/ca.crt',
71
'tests/ssl_certs/server_without_pass.key',
72
'tests/ssl_certs/server_with_pass.key',
73
'tests/ssl_certs/server.crt',
77
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
78
langfile = filepath[len("breezy/locale/"):]
79
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
80
I18N_FILES.append((targetpath, [filepath]))
82
def get_breezy_packages():
83
"""Recurse through the breezy directory, and extract the package names"""
86
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
87
for root, dirs, files in os.walk(base_path):
88
if '__init__.py' in files:
89
assert root.startswith(base_path)
90
# Get just the path below breezy
91
package_path = root[len(base_path):]
92
# Remove leading and trailing slashes
93
package_path = package_path.strip('\\/')
95
package_name = 'breezy'
97
package_name = ('breezy.' +
98
package_path.replace('/', '.').replace('\\', '.'))
99
packages.append(package_name)
100
return sorted(packages)
103
BZRLIB['packages'] = get_breezy_packages()
106
from distutils import log
37
107
from distutils.core import setup
108
from distutils.version import LooseVersion
38
109
from distutils.command.install_scripts import install_scripts
110
from distutils.command.install_data import install_data
39
111
from distutils.command.build import build
41
113
###############################
45
117
class my_install_scripts(install_scripts):
46
118
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
119
Create brz.bat for win32.
53
122
install_scripts.run(self) # standard action
55
124
if sys.platform == "win32":
57
scripts_dir = self.install_dir
58
script_path = os.path.join(scripts_dir, "bzr")
59
batch_str = "@%s %s %%*\n" % (sys.executable, script_path)
60
batch_path = script_path + ".bat"
126
scripts_dir = os.path.join(sys.prefix, 'Scripts')
127
script_path = self._quoted_path(os.path.join(scripts_dir,
129
python_exe = self._quoted_path(sys.executable)
130
args = self._win_batch_args()
131
batch_str = "@%s %s %s" % (python_exe, script_path, args)
132
batch_path = os.path.join(self.install_dir, "brz.bat")
61
133
f = file(batch_path, "w")
62
134
f.write(batch_str)
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
136
print(("Created: %s" % batch_path))
138
e = sys.exc_info()[1]
139
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
141
def _quoted_path(self, path):
143
return '"' + path + '"'
147
def _win_batch_args(self):
148
from breezy.win32utils import winver
149
if winver == 'Windows NT':
152
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
153
#/class my_install_scripts
69
156
class bzr_build(build):
70
157
"""Customized build distutils action.
161
sub_commands = build.sub_commands + [
162
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
168
from tools import generate_docs
169
generate_docs.main(argv=["brz", "man"])
79
172
########################
81
174
########################
86
author_email='mbp@sourcefrog.net',
87
url='http://www.bazaar-ng.org/',
88
description='Friendly distributed version control system',
96
'bzrlib.store.revision',
97
'bzrlib.store.versioned',
99
'bzrlib.tests.blackbox',
100
'bzrlib.tests.branch_implementations',
101
'bzrlib.tests.bzrdir_implementations',
102
'bzrlib.tests.interrepository_implementations',
103
'bzrlib.tests.interversionedfile_implementations',
104
'bzrlib.tests.repository_implementations',
105
'bzrlib.tests.revisionstore_implementations',
106
'bzrlib.tests.workingtree_implementations',
108
'bzrlib.transport.http',
111
'bzrlib.util.elementtree',
112
'bzrlib.util.effbot.org',
113
'bzrlib.util.configobj',
116
cmdclass={'install_scripts': my_install_scripts, 'build': bzr_build},
117
data_files=[('man/man1', ['bzr.1'])],
118
# todo: install the txt files from bzrlib.doc.api.
176
from breezy.bzr_distutils import build_mo
178
command_classes = {'install_scripts': my_install_scripts,
180
'build_mo': build_mo,
182
from distutils import log
183
from distutils.errors import CCompilerError, DistutilsPlatformError
184
from distutils.extension import Extension
187
from Cython.Distutils import build_ext
188
from Cython.Compiler.Version import version as cython_version
191
# try to build the extension from the prior generated source.
193
print("The python package 'Cython' is not available."
194
" If the .c files are available,")
195
print("they will be built,"
196
" but modifying the .pyx files will not rebuild them.")
198
from distutils.command.build_ext import build_ext
201
cython_version_info = LooseVersion(cython_version)
204
class build_ext_if_possible(build_ext):
206
user_options = build_ext.user_options + [
207
('allow-python-fallback', None,
208
"When an extension cannot be built, allow falling"
209
" back to the pure-python implementation.")
212
def initialize_options(self):
213
build_ext.initialize_options(self)
214
self.allow_python_fallback = False
219
except DistutilsPlatformError:
220
e = sys.exc_info()[1]
221
if not self.allow_python_fallback:
222
log.warn('\n Cannot build extensions.\n'
223
' Use "build_ext --allow-python-fallback" to use'
224
' slower python implementations instead.\n')
227
log.warn('\n Extensions cannot be built.\n'
228
' Using the slower Python implementations instead.\n')
230
def build_extension(self, ext):
232
build_ext.build_extension(self, ext)
233
except CCompilerError:
234
if not self.allow_python_fallback:
235
log.warn('\n Cannot build extension "%s".\n'
236
' Use "build_ext --allow-python-fallback" to use'
237
' slower python implementations instead.\n'
240
log.warn('\n Building of "%s" extension failed.\n'
241
' Using the slower Python implementation instead.'
245
# Override the build_ext if we have Cython available
246
command_classes['build_ext'] = build_ext_if_possible
247
unavailable_files = []
250
def add_cython_extension(module_name, libraries=None, extra_source=[]):
251
"""Add a cython module to build.
253
This will use Cython to auto-generate the .c file if it is available.
254
Otherwise it will fall back on the .c file. If the .c file is not
255
available, it will warn, and not add anything.
257
You can pass any extra options to Extension through kwargs. One example is
260
:param module_name: The python path to the module. This will be used to
261
determine the .pyx and .c files to use.
263
path = module_name.replace('.', '/')
264
cython_name = path + '.pyx'
267
if sys.platform == 'win32':
268
# cython uses the macro WIN32 to detect the platform, even though it
269
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
270
# give it the right value.
271
define_macros.append(('WIN32', None))
273
source = [cython_name]
275
if not os.path.isfile(c_name):
276
unavailable_files.append(c_name)
280
source.extend(extra_source)
281
include_dirs = ['breezy']
282
ext_modules.append(Extension(module_name, source,
283
define_macros=define_macros, libraries=libraries,
284
include_dirs=include_dirs))
287
add_cython_extension('breezy._simple_set_pyx')
288
ext_modules.append(Extension('breezy._static_tuple_c',
289
['breezy/_static_tuple_c.c']))
290
add_cython_extension('breezy._annotator_pyx')
291
add_cython_extension('breezy._bencode_pyx')
292
add_cython_extension('breezy._chunks_to_lines_pyx')
293
add_cython_extension('breezy.bzr._groupcompress_pyx',
294
extra_source=['breezy/bzr/diff-delta.c'])
295
add_cython_extension('breezy.bzr._knit_load_data_pyx')
296
add_cython_extension('breezy._known_graph_pyx')
297
add_cython_extension('breezy._rio_pyx')
298
if sys.platform == 'win32':
299
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
300
libraries=['Ws2_32'])
301
add_cython_extension('breezy._walkdirs_win32')
303
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
304
add_cython_extension('breezy._readdir_pyx')
305
add_cython_extension('breezy.bzr._chk_map_pyx')
306
ext_modules.append(Extension('breezy._patiencediff_c',
307
['breezy/_patiencediff_c.c']))
308
add_cython_extension('breezy.bzr._btree_serializer_pyx')
311
if unavailable_files:
312
print('C extension(s) not found:')
313
print((' %s' % ('\n '.join(unavailable_files),)))
314
print('The python versions will be used instead.')
318
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
319
gui_targets, data_files):
320
packages.append('tbzrcommands')
322
# ModuleFinder can't handle runtime changes to __path__, but
323
# win32com uses them. Hook this in so win32com.shell is found.
326
import cPickle as pickle
327
for p in win32com.__path__[1:]:
328
modulefinder.AddPackagePath("win32com", p)
329
for extra in ["win32com.shell"]:
331
m = sys.modules[extra]
332
for p in m.__path__[1:]:
333
modulefinder.AddPackagePath(extra, p)
335
# TBZR points to the TBZR directory
336
tbzr_root = os.environ["TBZR"]
338
# Ensure tbreezy itself is on sys.path
339
sys.path.append(tbzr_root)
341
packages.append("tbreezy")
343
# collect up our icons.
345
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
346
icos = [] # list of (path_root, relative_ico_path)
347
# First always brz's icon and its in the root of the brz tree.
348
icos.append(('', 'brz.ico'))
349
for root, dirs, files in os.walk(ico_root):
350
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
351
for f in files if f.endswith('.ico')])
352
# allocate an icon ID for each file and the full path to the ico
353
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
354
for rid, (ico_dir, ico_name) in enumerate(icos)]
355
# create a string resource with the mapping. Might as well save the
356
# runtime some effort and write a pickle.
357
# Runtime expects unicode objects with forward-slash seps.
358
fse = sys.getfilesystemencoding()
359
map_items = [(f.replace('\\', '/').decode(fse), rid)
360
for rid, (_, f) in enumerate(icos)]
361
ico_map = dict(map_items)
362
# Create a new resource type of 'ICON_MAP', and use ID=1
363
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
365
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
366
win32ui crawler.Crawler""".split())
368
# tbzrcache executables - a "console" version for debugging and a
369
# GUI version that is generally used.
371
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
372
icon_resources = icon_resources,
373
other_resources = other_resources,
375
console_targets.append(tbzrcache)
377
# Make a windows version which is the same except for the base name.
378
tbzrcachew = tbzrcache.copy()
379
tbzrcachew["dest_base"]="tbzrcachew"
380
gui_targets.append(tbzrcachew)
382
# ditto for the tbzrcommand tool
384
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
385
icon_resources = icon_resources,
386
other_resources = other_resources,
388
console_targets.append(tbzrcommand)
389
tbzrcommandw = tbzrcommand.copy()
390
tbzrcommandw["dest_base"]="tbzrcommandw"
391
gui_targets.append(tbzrcommandw)
393
# A utility to see python output from both C++ and Python based shell
395
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
396
console_targets.append(tracer)
398
# The C++ implemented shell extensions.
399
dist_dir = os.path.join(tbzr_root, "shellext", "build")
400
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
401
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
404
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
405
# PyQt4 itself still escapes the plugin detection code for some reason...
406
includes.append('PyQt4.QtCore')
407
includes.append('PyQt4.QtGui')
408
includes.append('PyQt4.QtTest')
409
includes.append('sip') # extension module required for Qt.
410
packages.append('pygments') # colorizer for qbzr
411
packages.append('docutils') # html formatting
412
includes.append('win32event') # for qsubprocess stuff
413
# the qt binaries might not be on PATH...
414
# They seem to install to a place like C:\Python25\PyQt4\*
415
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
416
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
417
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
418
if os.path.isdir(pyqt_bin_dir):
419
path = os.environ.get("PATH", "")
420
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
421
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
422
# also add all imageformat plugins to distribution
423
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
424
base_dirs_to_check = []
425
if os.path.isdir(pyqt_dir):
426
base_dirs_to_check.append(pyqt_dir)
432
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
433
if pyqt4_base_dir != pyqt_dir:
434
base_dirs_to_check.append(pyqt4_base_dir)
435
if not base_dirs_to_check:
436
log.warn("Can't find PyQt4 installation -> not including imageformat"
440
for base_dir in base_dirs_to_check:
441
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
442
if os.path.isdir(plug_dir):
443
for fname in os.listdir(plug_dir):
444
# Include plugin dlls, but not debugging dlls
445
fullpath = os.path.join(plug_dir, fname)
446
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
447
files.append(fullpath)
449
data_files.append(('imageformats', files))
451
log.warn('PyQt4 was found, but we could not find any imageformat'
452
' plugins. Are you sure your configuration is correct?')
455
def get_svn_py2exe_info(includes, excludes, packages):
456
packages.append('subvertpy')
457
packages.append('sqlite3')
460
def get_git_py2exe_info(includes, excludes, packages):
461
packages.append('dulwich')
464
def get_fastimport_py2exe_info(includes, excludes, packages):
465
# This is the python-fastimport package, not to be confused with the
466
# brz-fastimport plugin.
467
packages.append('fastimport')
470
if 'bdist_wininst' in sys.argv:
473
for root, dirs, files in os.walk('doc'):
476
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
477
or f == 'quick-start-summary.svg'):
478
r.append(os.path.join(root, f))
482
target = os.path.join('Doc\\Breezy', relative)
484
target = 'Doc\\Breezy'
485
docs.append((target, r))
488
# python's distutils-based win32 installer
489
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
490
'ext_modules': ext_modules,
492
'data_files': find_docs(),
493
# for building cython extensions
494
'cmdclass': command_classes,
497
ARGS.update(META_INFO)
499
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
500
ARGS.update(PKG_DATA)
504
elif 'py2exe' in sys.argv:
508
# pick real brz version
512
for i in breezy.version_info[:4]:
517
version_number.append(str(i))
518
version_str = '.'.join(version_number)
520
# An override to install_data used only by py2exe builds, which arranges
521
# to byte-compile any .py files in data_files (eg, our plugins)
522
# Necessary as we can't rely on the user having the relevant permissions
523
# to the "Program Files" directory to generate them on the fly.
524
class install_data_with_bytecompile(install_data):
526
from distutils.util import byte_compile
528
install_data.run(self)
530
py2exe = self.distribution.get_command_obj('py2exe', False)
531
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
532
# time before living with docstring stripping
534
compile_names = [f for f in self.outfiles if f.endswith('.py')]
535
# Round mtime to nearest even second so that installing on a FAT
536
# filesystem bytecode internal and script timestamps will match
537
for f in compile_names:
538
mtime = os.stat(f).st_mtime
539
remainder = mtime % 2
542
os.utime(f, (mtime, mtime))
543
byte_compile(compile_names,
545
force=self.force, prefix=self.install_dir,
546
dry_run=self.dry_run)
547
self.outfiles.extend([f + 'o' for f in compile_names])
548
# end of class install_data_with_bytecompile
550
target = py2exe.build_exe.Target(script = "brz",
552
icon_resources = [(0,'brz.ico')],
553
name = META_INFO['name'],
554
version = version_str,
555
description = META_INFO['description'],
556
author = META_INFO['author'],
557
copyright = "(c) Canonical Ltd, 2005-2010",
558
company_name = "Canonical Ltd.",
559
comments = META_INFO['description'],
561
gui_target = copy.copy(target)
562
gui_target.dest_base = "bzrw"
564
packages = BZRLIB['packages']
565
packages.remove('breezy')
566
packages = [i for i in packages if not i.startswith('breezy.plugins')]
568
for i in glob.glob('breezy\\*.py'):
569
module = i[:-3].replace('\\', '.')
570
if module.endswith('__init__'):
571
module = module[:-len('__init__')]
572
includes.append(module)
574
additional_packages = set()
575
if sys.version.startswith('2.7'):
576
additional_packages.add('xml.etree')
579
warnings.warn('Unknown Python version.\n'
580
'Please check setup.py script for compatibility.')
582
# Although we currently can't enforce it, we consider it an error for
583
# py2exe to report any files are "missing". Such modules we know aren't
584
# used should be listed here.
585
excludes = """Tkinter psyco ElementPath r_hmac
586
ImaginaryModule cElementTree elementtree.ElementTree
587
Crypto.PublicKey._fastmath
589
resource validate""".split()
592
# email package from std python library use lazy import,
593
# so we need to explicitly add all package
594
additional_packages.add('email')
595
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
596
# a result, packages like 'email.Parser' show as missing. Tell py2exe
599
for oldname in getattr(email, '_LOWERNAMES', []):
600
excludes.append("email." + oldname)
601
for oldname in getattr(email, '_MIMENAMES', []):
602
excludes.append("email.MIME" + oldname)
604
# text files for help topis
605
text_topics = glob.glob('breezy/help_topics/en/*.txt')
606
topics_files = [('lib/help_topics/en', text_topics)]
610
# XXX - should we consider having the concept of an 'official' build,
611
# which hard-codes the list of plugins, gets more upset if modules are
613
plugins = None # will be a set after plugin sniffing...
614
for root, dirs, files in os.walk('breezy/plugins'):
615
if root == 'breezy/plugins':
617
# We ship plugins as normal files on the file-system - however,
618
# the build process can cause *some* of these plugin files to end
619
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
620
# library.zip, and then saw import errors related to that as the
621
# rest of the svn plugin wasn't. So we tell py2exe to leave the
622
# plugins out of the .zip file
623
excludes.extend(["breezy.plugins." + d for d in dirs])
626
# Throw away files we don't want packaged. Note that plugins may
627
# have data files with all sorts of extensions so we need to
628
# be conservative here about what we ditch.
629
ext = os.path.splitext(i)[1]
630
if ext.endswith('~') or ext in [".pyc", ".swp"]:
632
if i == '__init__.py' and root == 'breezy/plugins':
634
x.append(os.path.join(root, i))
636
target_dir = root[len('breezy/'):] # install to 'plugins/...'
637
plugins_files.append((target_dir, x))
638
# find modules for built-in plugins
639
import tools.package_mf
640
mf = tools.package_mf.CustomModuleFinder()
641
mf.run_package('breezy/plugins')
642
packs, mods = mf.get_result()
643
additional_packages.update(packs)
644
includes.extend(mods)
646
console_targets = [target,
647
'tools/win32/bzr_postinstall.py',
649
gui_targets = [gui_target]
650
data_files = topics_files + plugins_files + I18N_FILES
652
if 'qbzr' in plugins:
653
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
656
get_svn_py2exe_info(includes, excludes, packages)
659
get_git_py2exe_info(includes, excludes, packages)
661
if 'fastimport' in plugins:
662
get_fastimport_py2exe_info(includes, excludes, packages)
664
if "TBZR" in os.environ:
665
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
666
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
667
# can be downloaded from (username=guest, blank password):
668
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
669
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
670
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
671
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
672
'TORTOISE_OVERLAYS_MSI_X64'):
673
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
675
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
677
"\nPlease set %s to the location of the relevant"
678
"\nTortoiseOverlays .msi installer file."
679
" The installers can be found at"
681
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
682
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
683
gui_targets, data_files)
685
# print this warning to stderr as output is redirected, so it is seen
686
# at build time. Also to stdout so it appears in the log
687
for f in (sys.stderr, sys.stdout):
688
f.write("Skipping TBZR binaries - "
689
"please set TBZR to a directory to enable\n")
691
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
693
dll_excludes.extend(["MSWSOCK.dll",
698
options_list = {"py2exe": {"packages": packages + list(additional_packages),
699
"includes": includes,
700
"excludes": excludes,
701
"dll_excludes": dll_excludes,
702
"dist_dir": "win32_bzr.exe",
704
"custom_boot_script":
705
"tools/win32/py2exe_boot_common.py",
709
# We want the libaray.zip to have optimize = 2, but the exe to have
710
# optimize = 1, so that .py files that get compilied at run time
711
# (e.g. user installed plugins) dont have their doc strings removed.
712
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
713
def build_executable(self, *args, **kwargs):
715
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
718
if __name__ == '__main__':
719
command_classes['install_data'] = install_data_with_bytecompile
720
command_classes['py2exe'] = py2exe_no_oo_exe
721
setup(options=options_list,
722
console=console_targets,
724
zipfile='lib/library.zip',
725
data_files=data_files,
726
cmdclass=command_classes,
730
# ad-hoc for easy_install
732
if not 'bdist_egg' in sys.argv:
733
# generate and install brz.1 only with plain install, not the
735
DATA_FILES = [('man/man1', ['brz.1'])]
737
DATA_FILES = DATA_FILES + I18N_FILES
739
ARGS = {'scripts': ['brz'],
740
'data_files': DATA_FILES,
741
'cmdclass': command_classes,
742
'ext_modules': ext_modules,
745
ARGS.update(META_INFO)
747
ARGS.update(PKG_DATA)
749
if __name__ == '__main__':