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',
64
'fastimport': ['fastimport'],
68
# The list of packages is automatically generated later. Add other things
69
# that are part of BZRLIB here.
72
PKG_DATA = {# install files from selftest suite
73
'package_data': {'breezy': ['doc/api/*.txt',
74
'tests/test_patches_data/*',
75
'help_topics/en/*.txt',
76
'tests/ssl_certs/ca.crt',
77
'tests/ssl_certs/server_without_pass.key',
78
'tests/ssl_certs/server_with_pass.key',
79
'tests/ssl_certs/server.crt',
83
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
84
langfile = filepath[len("breezy/locale/"):]
85
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
86
I18N_FILES.append((targetpath, [filepath]))
88
def get_breezy_packages():
89
"""Recurse through the breezy directory, and extract the package names"""
92
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
93
for root, dirs, files in os.walk(base_path):
94
if '__init__.py' in files:
95
assert root.startswith(base_path)
96
# Get just the path below breezy
97
package_path = root[len(base_path):]
98
# Remove leading and trailing slashes
99
package_path = package_path.strip('\\/')
101
package_name = 'breezy'
103
package_name = ('breezy.' +
104
package_path.replace('/', '.').replace('\\', '.'))
105
packages.append(package_name)
106
return sorted(packages)
109
BZRLIB['packages'] = get_breezy_packages()
112
from distutils import log
37
113
from distutils.core import setup
114
from distutils.version import LooseVersion
38
115
from distutils.command.install_scripts import install_scripts
116
from distutils.command.install_data import install_data
39
117
from distutils.command.build import build
41
119
###############################
45
123
class my_install_scripts(install_scripts):
46
124
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
125
Create brz.bat for win32.
53
128
install_scripts.run(self) # standard action
55
130
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"
132
scripts_dir = os.path.join(sys.prefix, 'Scripts')
133
script_path = self._quoted_path(os.path.join(scripts_dir,
135
python_exe = self._quoted_path(sys.executable)
136
args = self._win_batch_args()
137
batch_str = "@%s %s %s" % (python_exe, script_path, args)
138
batch_path = os.path.join(self.install_dir, "brz.bat")
61
139
f = file(batch_path, "w")
62
140
f.write(batch_str)
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
142
print(("Created: %s" % batch_path))
144
e = sys.exc_info()[1]
145
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
147
def _quoted_path(self, path):
149
return '"' + path + '"'
153
def _win_batch_args(self):
154
from breezy.win32utils import winver
155
if winver == 'Windows NT':
158
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
159
#/class my_install_scripts
69
162
class bzr_build(build):
70
163
"""Customized build distutils action.
167
sub_commands = build.sub_commands + [
168
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
174
from tools import generate_docs
175
generate_docs.main(argv=["brz", "man"])
79
178
########################
81
180
########################
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.
182
from breezy.bzr_distutils import build_mo
184
command_classes = {'install_scripts': my_install_scripts,
186
'build_mo': build_mo,
188
from distutils import log
189
from distutils.errors import CCompilerError, DistutilsPlatformError
190
from distutils.extension import Extension
193
from Cython.Distutils import build_ext
194
from Cython.Compiler.Version import version as cython_version
197
# try to build the extension from the prior generated source.
199
print("The python package 'Cython' is not available."
200
" If the .c files are available,")
201
print("they will be built,"
202
" but modifying the .pyx files will not rebuild them.")
204
from distutils.command.build_ext import build_ext
207
cython_version_info = LooseVersion(cython_version)
210
class build_ext_if_possible(build_ext):
212
user_options = build_ext.user_options + [
213
('allow-python-fallback', None,
214
"When an extension cannot be built, allow falling"
215
" back to the pure-python implementation.")
218
def initialize_options(self):
219
build_ext.initialize_options(self)
220
self.allow_python_fallback = False
225
except DistutilsPlatformError:
226
e = sys.exc_info()[1]
227
if not self.allow_python_fallback:
228
log.warn('\n Cannot build extensions.\n'
229
' Use "build_ext --allow-python-fallback" to use'
230
' slower python implementations instead.\n')
233
log.warn('\n Extensions cannot be built.\n'
234
' Using the slower Python implementations instead.\n')
236
def build_extension(self, ext):
238
build_ext.build_extension(self, ext)
239
except CCompilerError:
240
if not self.allow_python_fallback:
241
log.warn('\n Cannot build extension "%s".\n'
242
' Use "build_ext --allow-python-fallback" to use'
243
' slower python implementations instead.\n'
246
log.warn('\n Building of "%s" extension failed.\n'
247
' Using the slower Python implementation instead.'
251
# Override the build_ext if we have Cython available
252
command_classes['build_ext'] = build_ext_if_possible
253
unavailable_files = []
256
def add_cython_extension(module_name, libraries=None, extra_source=[]):
257
"""Add a cython module to build.
259
This will use Cython to auto-generate the .c file if it is available.
260
Otherwise it will fall back on the .c file. If the .c file is not
261
available, it will warn, and not add anything.
263
You can pass any extra options to Extension through kwargs. One example is
266
:param module_name: The python path to the module. This will be used to
267
determine the .pyx and .c files to use.
269
path = module_name.replace('.', '/')
270
cython_name = path + '.pyx'
273
if sys.platform == 'win32':
274
# cython uses the macro WIN32 to detect the platform, even though it
275
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
276
# give it the right value.
277
define_macros.append(('WIN32', None))
279
source = [cython_name]
281
if not os.path.isfile(c_name):
282
unavailable_files.append(c_name)
286
source.extend(extra_source)
287
include_dirs = ['breezy']
288
ext_modules.append(Extension(module_name, source,
289
define_macros=define_macros, libraries=libraries,
290
include_dirs=include_dirs))
293
add_cython_extension('breezy._simple_set_pyx')
294
ext_modules.append(Extension('breezy._static_tuple_c',
295
['breezy/_static_tuple_c.c']))
296
add_cython_extension('breezy._annotator_pyx')
297
add_cython_extension('breezy._bencode_pyx')
298
add_cython_extension('breezy._chunks_to_lines_pyx')
299
add_cython_extension('breezy.bzr._groupcompress_pyx',
300
extra_source=['breezy/bzr/diff-delta.c'])
301
add_cython_extension('breezy.bzr._knit_load_data_pyx')
302
add_cython_extension('breezy._known_graph_pyx')
303
add_cython_extension('breezy._rio_pyx')
304
if sys.platform == 'win32':
305
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
306
libraries=['Ws2_32'])
307
add_cython_extension('breezy._walkdirs_win32')
309
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
310
add_cython_extension('breezy._readdir_pyx')
311
add_cython_extension('breezy.bzr._chk_map_pyx')
312
ext_modules.append(Extension('breezy._patiencediff_c',
313
['breezy/_patiencediff_c.c']))
314
add_cython_extension('breezy.bzr._btree_serializer_pyx')
317
if unavailable_files:
318
print('C extension(s) not found:')
319
print((' %s' % ('\n '.join(unavailable_files),)))
320
print('The python versions will be used instead.')
324
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
325
gui_targets, data_files):
326
packages.append('tbzrcommands')
328
# ModuleFinder can't handle runtime changes to __path__, but
329
# win32com uses them. Hook this in so win32com.shell is found.
332
import cPickle as pickle
333
for p in win32com.__path__[1:]:
334
modulefinder.AddPackagePath("win32com", p)
335
for extra in ["win32com.shell"]:
337
m = sys.modules[extra]
338
for p in m.__path__[1:]:
339
modulefinder.AddPackagePath(extra, p)
341
# TBZR points to the TBZR directory
342
tbzr_root = os.environ["TBZR"]
344
# Ensure tbreezy itself is on sys.path
345
sys.path.append(tbzr_root)
347
packages.append("tbreezy")
349
# collect up our icons.
351
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
352
icos = [] # list of (path_root, relative_ico_path)
353
# First always brz's icon and its in the root of the brz tree.
354
icos.append(('', 'brz.ico'))
355
for root, dirs, files in os.walk(ico_root):
356
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
357
for f in files if f.endswith('.ico')])
358
# allocate an icon ID for each file and the full path to the ico
359
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
360
for rid, (ico_dir, ico_name) in enumerate(icos)]
361
# create a string resource with the mapping. Might as well save the
362
# runtime some effort and write a pickle.
363
# Runtime expects unicode objects with forward-slash seps.
364
fse = sys.getfilesystemencoding()
365
map_items = [(f.replace('\\', '/').decode(fse), rid)
366
for rid, (_, f) in enumerate(icos)]
367
ico_map = dict(map_items)
368
# Create a new resource type of 'ICON_MAP', and use ID=1
369
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
371
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
372
win32ui crawler.Crawler""".split())
374
# tbzrcache executables - a "console" version for debugging and a
375
# GUI version that is generally used.
377
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
378
icon_resources = icon_resources,
379
other_resources = other_resources,
381
console_targets.append(tbzrcache)
383
# Make a windows version which is the same except for the base name.
384
tbzrcachew = tbzrcache.copy()
385
tbzrcachew["dest_base"]="tbzrcachew"
386
gui_targets.append(tbzrcachew)
388
# ditto for the tbzrcommand tool
390
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
391
icon_resources = icon_resources,
392
other_resources = other_resources,
394
console_targets.append(tbzrcommand)
395
tbzrcommandw = tbzrcommand.copy()
396
tbzrcommandw["dest_base"]="tbzrcommandw"
397
gui_targets.append(tbzrcommandw)
399
# A utility to see python output from both C++ and Python based shell
401
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
402
console_targets.append(tracer)
404
# The C++ implemented shell extensions.
405
dist_dir = os.path.join(tbzr_root, "shellext", "build")
406
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
407
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
410
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
411
# PyQt4 itself still escapes the plugin detection code for some reason...
412
includes.append('PyQt4.QtCore')
413
includes.append('PyQt4.QtGui')
414
includes.append('PyQt4.QtTest')
415
includes.append('sip') # extension module required for Qt.
416
packages.append('pygments') # colorizer for qbzr
417
packages.append('docutils') # html formatting
418
includes.append('win32event') # for qsubprocess stuff
419
# the qt binaries might not be on PATH...
420
# They seem to install to a place like C:\Python25\PyQt4\*
421
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
422
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
423
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
424
if os.path.isdir(pyqt_bin_dir):
425
path = os.environ.get("PATH", "")
426
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
427
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
428
# also add all imageformat plugins to distribution
429
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
430
base_dirs_to_check = []
431
if os.path.isdir(pyqt_dir):
432
base_dirs_to_check.append(pyqt_dir)
438
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
439
if pyqt4_base_dir != pyqt_dir:
440
base_dirs_to_check.append(pyqt4_base_dir)
441
if not base_dirs_to_check:
442
log.warn("Can't find PyQt4 installation -> not including imageformat"
446
for base_dir in base_dirs_to_check:
447
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
448
if os.path.isdir(plug_dir):
449
for fname in os.listdir(plug_dir):
450
# Include plugin dlls, but not debugging dlls
451
fullpath = os.path.join(plug_dir, fname)
452
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
453
files.append(fullpath)
455
data_files.append(('imageformats', files))
457
log.warn('PyQt4 was found, but we could not find any imageformat'
458
' plugins. Are you sure your configuration is correct?')
461
def get_svn_py2exe_info(includes, excludes, packages):
462
packages.append('subvertpy')
463
packages.append('sqlite3')
466
def get_git_py2exe_info(includes, excludes, packages):
467
packages.append('dulwich')
470
def get_fastimport_py2exe_info(includes, excludes, packages):
471
# This is the python-fastimport package, not to be confused with the
472
# brz-fastimport plugin.
473
packages.append('fastimport')
476
if 'bdist_wininst' in sys.argv:
479
for root, dirs, files in os.walk('doc'):
482
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
483
or f == 'quick-start-summary.svg'):
484
r.append(os.path.join(root, f))
488
target = os.path.join('Doc\\Breezy', relative)
490
target = 'Doc\\Breezy'
491
docs.append((target, r))
494
# python's distutils-based win32 installer
495
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
496
'ext_modules': ext_modules,
498
'data_files': find_docs(),
499
# for building cython extensions
500
'cmdclass': command_classes,
503
ARGS.update(META_INFO)
505
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
506
ARGS.update(PKG_DATA)
510
elif 'py2exe' in sys.argv:
514
# pick real brz version
518
for i in breezy.version_info[:4]:
523
version_number.append(str(i))
524
version_str = '.'.join(version_number)
526
# An override to install_data used only by py2exe builds, which arranges
527
# to byte-compile any .py files in data_files (eg, our plugins)
528
# Necessary as we can't rely on the user having the relevant permissions
529
# to the "Program Files" directory to generate them on the fly.
530
class install_data_with_bytecompile(install_data):
532
from distutils.util import byte_compile
534
install_data.run(self)
536
py2exe = self.distribution.get_command_obj('py2exe', False)
537
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
538
# time before living with docstring stripping
540
compile_names = [f for f in self.outfiles if f.endswith('.py')]
541
# Round mtime to nearest even second so that installing on a FAT
542
# filesystem bytecode internal and script timestamps will match
543
for f in compile_names:
544
mtime = os.stat(f).st_mtime
545
remainder = mtime % 2
548
os.utime(f, (mtime, mtime))
549
byte_compile(compile_names,
551
force=self.force, prefix=self.install_dir,
552
dry_run=self.dry_run)
553
self.outfiles.extend([f + 'o' for f in compile_names])
554
# end of class install_data_with_bytecompile
556
target = py2exe.build_exe.Target(script = "brz",
558
icon_resources = [(0,'brz.ico')],
559
name = META_INFO['name'],
560
version = version_str,
561
description = META_INFO['description'],
562
author = META_INFO['author'],
563
copyright = "(c) Canonical Ltd, 2005-2010",
564
company_name = "Canonical Ltd.",
565
comments = META_INFO['description'],
567
gui_target = copy.copy(target)
568
gui_target.dest_base = "bzrw"
570
packages = BZRLIB['packages']
571
packages.remove('breezy')
572
packages = [i for i in packages if not i.startswith('breezy.plugins')]
574
for i in glob.glob('breezy\\*.py'):
575
module = i[:-3].replace('\\', '.')
576
if module.endswith('__init__'):
577
module = module[:-len('__init__')]
578
includes.append(module)
580
additional_packages = set()
581
if sys.version.startswith('2.7'):
582
additional_packages.add('xml.etree')
585
warnings.warn('Unknown Python version.\n'
586
'Please check setup.py script for compatibility.')
588
# Although we currently can't enforce it, we consider it an error for
589
# py2exe to report any files are "missing". Such modules we know aren't
590
# used should be listed here.
591
excludes = """Tkinter psyco ElementPath r_hmac
592
ImaginaryModule cElementTree elementtree.ElementTree
593
Crypto.PublicKey._fastmath
595
resource validate""".split()
598
# email package from std python library use lazy import,
599
# so we need to explicitly add all package
600
additional_packages.add('email')
601
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
602
# a result, packages like 'email.Parser' show as missing. Tell py2exe
605
for oldname in getattr(email, '_LOWERNAMES', []):
606
excludes.append("email." + oldname)
607
for oldname in getattr(email, '_MIMENAMES', []):
608
excludes.append("email.MIME" + oldname)
610
# text files for help topis
611
text_topics = glob.glob('breezy/help_topics/en/*.txt')
612
topics_files = [('lib/help_topics/en', text_topics)]
616
# XXX - should we consider having the concept of an 'official' build,
617
# which hard-codes the list of plugins, gets more upset if modules are
619
plugins = None # will be a set after plugin sniffing...
620
for root, dirs, files in os.walk('breezy/plugins'):
621
if root == 'breezy/plugins':
623
# We ship plugins as normal files on the file-system - however,
624
# the build process can cause *some* of these plugin files to end
625
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
626
# library.zip, and then saw import errors related to that as the
627
# rest of the svn plugin wasn't. So we tell py2exe to leave the
628
# plugins out of the .zip file
629
excludes.extend(["breezy.plugins." + d for d in dirs])
632
# Throw away files we don't want packaged. Note that plugins may
633
# have data files with all sorts of extensions so we need to
634
# be conservative here about what we ditch.
635
ext = os.path.splitext(i)[1]
636
if ext.endswith('~') or ext in [".pyc", ".swp"]:
638
if i == '__init__.py' and root == 'breezy/plugins':
640
x.append(os.path.join(root, i))
642
target_dir = root[len('breezy/'):] # install to 'plugins/...'
643
plugins_files.append((target_dir, x))
644
# find modules for built-in plugins
645
import tools.package_mf
646
mf = tools.package_mf.CustomModuleFinder()
647
mf.run_package('breezy/plugins')
648
packs, mods = mf.get_result()
649
additional_packages.update(packs)
650
includes.extend(mods)
652
console_targets = [target,
653
'tools/win32/bzr_postinstall.py',
655
gui_targets = [gui_target]
656
data_files = topics_files + plugins_files + I18N_FILES
658
if 'qbzr' in plugins:
659
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
662
get_svn_py2exe_info(includes, excludes, packages)
665
get_git_py2exe_info(includes, excludes, packages)
667
if 'fastimport' in plugins:
668
get_fastimport_py2exe_info(includes, excludes, packages)
670
if "TBZR" in os.environ:
671
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
672
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
673
# can be downloaded from (username=guest, blank password):
674
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
675
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
676
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
677
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
678
'TORTOISE_OVERLAYS_MSI_X64'):
679
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
681
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
683
"\nPlease set %s to the location of the relevant"
684
"\nTortoiseOverlays .msi installer file."
685
" The installers can be found at"
687
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
688
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
689
gui_targets, data_files)
691
# print this warning to stderr as output is redirected, so it is seen
692
# at build time. Also to stdout so it appears in the log
693
for f in (sys.stderr, sys.stdout):
694
f.write("Skipping TBZR binaries - "
695
"please set TBZR to a directory to enable\n")
697
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
699
dll_excludes.extend(["MSWSOCK.dll",
704
options_list = {"py2exe": {"packages": packages + list(additional_packages),
705
"includes": includes,
706
"excludes": excludes,
707
"dll_excludes": dll_excludes,
708
"dist_dir": "win32_bzr.exe",
710
"custom_boot_script":
711
"tools/win32/py2exe_boot_common.py",
715
# We want the libaray.zip to have optimize = 2, but the exe to have
716
# optimize = 1, so that .py files that get compilied at run time
717
# (e.g. user installed plugins) dont have their doc strings removed.
718
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
719
def build_executable(self, *args, **kwargs):
721
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
724
if __name__ == '__main__':
725
command_classes['install_data'] = install_data_with_bytecompile
726
command_classes['py2exe'] = py2exe_no_oo_exe
727
setup(options=options_list,
728
console=console_targets,
730
zipfile='lib/library.zip',
731
data_files=data_files,
732
cmdclass=command_classes,
736
# ad-hoc for easy_install
738
if not 'bdist_egg' in sys.argv:
739
# generate and install brz.1 only with plain install, not the
741
DATA_FILES = [('man/man1', ['brz.1'])]
743
DATA_FILES = DATA_FILES + I18N_FILES
745
ARGS = {'scripts': ['brz'],
746
'data_files': DATA_FILES,
747
'cmdclass': command_classes,
748
'ext_modules': ext_modules,
751
ARGS.update(META_INFO)
753
ARGS.update(PKG_DATA)
755
if __name__ == '__main__':