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.rst')
27
with open(readme, 'r') as f:
32
# META INFORMATION FOR SETUP
33
# see http://docs.python.org/dist/meta-data.html
36
'version': breezy.__version__,
37
'maintainer': 'Breezy Developers',
38
'maintainer_email': 'team@breezy-vcs.org',
39
'url': 'https://www.breezy-vcs.org/',
40
'description': 'Friendly distributed version control system',
41
'license': 'GNU GPL v2',
42
'download_url': 'https://launchpad.net/brz/+download',
43
'long_description': get_long_description(),
45
'Development Status :: 6 - Mature',
46
'Environment :: Console',
47
'Intended Audience :: Developers',
48
'Intended Audience :: System Administrators',
49
'License :: OSI Approved :: GNU General Public License (GPL)',
50
'Operating System :: Microsoft :: Windows',
51
'Operating System :: OS Independent',
52
'Operating System :: POSIX',
53
'Programming Language :: Python',
54
'Programming Language :: C',
55
'Topic :: Software Development :: Version Control',
60
# Technically, Breezy works without these two dependencies too. But there's
61
# no way to enable them by default and let users opt out.
74
# The list of packages is automatically generated later. Add other things
75
# that are part of BREEZY here.
79
# install files from selftest suite
80
'package_data': {'breezy': ['doc/api/*.txt',
81
'tests/test_patches_data/*',
82
'help_topics/en/*.txt',
83
'tests/ssl_certs/ca.crt',
84
'tests/ssl_certs/server_without_pass.key',
85
'tests/ssl_certs/server_with_pass.key',
86
'tests/ssl_certs/server.crt',
90
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
91
langfile = filepath[len("breezy/locale/"):]
92
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
93
I18N_FILES.append((targetpath, [filepath]))
95
def get_breezy_packages():
96
"""Recurse through the breezy directory, and extract the package names"""
99
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
100
for root, dirs, files in os.walk(base_path):
101
if '__init__.py' in files:
102
assert root.startswith(base_path)
103
# Get just the path below breezy
104
package_path = root[len(base_path):]
105
# Remove leading and trailing slashes
106
package_path = package_path.strip('\\/')
108
package_name = 'breezy'
112
package_path.replace('/', '.').replace('\\', '.'))
113
packages.append(package_name)
114
return sorted(packages)
117
BREEZY['packages'] = get_breezy_packages()
120
from distutils import log
37
121
from distutils.core import setup
122
from distutils.version import LooseVersion
38
123
from distutils.command.install_scripts import install_scripts
124
from distutils.command.install_data import install_data
39
125
from distutils.command.build import build
41
127
###############################
45
131
class my_install_scripts(install_scripts):
46
132
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
133
Create brz.bat for win32.
53
136
install_scripts.run(self) # standard action
55
138
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"
61
f = file(batch_path, "w")
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
140
scripts_dir = os.path.join(sys.prefix, 'Scripts')
141
script_path = self._quoted_path(os.path.join(scripts_dir,
143
python_exe = self._quoted_path(sys.executable)
144
args = self._win_batch_args()
145
batch_str = "@%s %s %s" % (python_exe, script_path, args)
146
batch_path = os.path.join(self.install_dir, "brz.bat")
147
with open(batch_path, "w") as f:
149
print(("Created: %s" % batch_path))
151
e = sys.exc_info()[1]
152
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
154
def _quoted_path(self, path):
156
return '"' + path + '"'
160
def _win_batch_args(self):
161
from breezy.win32utils import winver
162
if winver == 'Windows NT':
165
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
166
#/class my_install_scripts
69
169
class bzr_build(build):
70
170
"""Customized build distutils action.
174
sub_commands = build.sub_commands + [
175
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
181
from tools import generate_docs
182
generate_docs.main(argv=["brz", "man"])
79
185
########################
81
187
########################
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.
189
from breezy.bzr_distutils import build_mo
191
command_classes = {'install_scripts': my_install_scripts,
193
'build_mo': build_mo,
195
from distutils import log
196
from distutils.errors import CCompilerError, DistutilsPlatformError
197
from distutils.extension import Extension
200
from Cython.Distutils import build_ext
201
from Cython.Compiler.Version import version as cython_version
204
# try to build the extension from the prior generated source.
206
print("The python package 'Cython' is not available."
207
" If the .c files are available,")
208
print("they will be built,"
209
" but modifying the .pyx files will not rebuild them.")
211
from distutils.command.build_ext import build_ext
214
cython_version_info = LooseVersion(cython_version)
217
class build_ext_if_possible(build_ext):
219
user_options = build_ext.user_options + [
220
('allow-python-fallback', None,
221
"When an extension cannot be built, allow falling"
222
" back to the pure-python implementation.")
225
def initialize_options(self):
226
build_ext.initialize_options(self)
227
self.allow_python_fallback = False
232
except DistutilsPlatformError:
233
e = sys.exc_info()[1]
234
if not self.allow_python_fallback:
235
log.warn('\n Cannot build extensions.\n'
236
' Use "build_ext --allow-python-fallback" to use'
237
' slower python implementations instead.\n')
240
log.warn('\n Extensions cannot be built.\n'
241
' Using the slower Python implementations instead.\n')
243
def build_extension(self, ext):
245
build_ext.build_extension(self, ext)
246
except CCompilerError:
247
if not self.allow_python_fallback:
248
log.warn('\n Cannot build extension "%s".\n'
249
' Use "build_ext --allow-python-fallback" to use'
250
' slower python implementations instead.\n'
253
log.warn('\n Building of "%s" extension failed.\n'
254
' Using the slower Python implementation instead.'
258
# Override the build_ext if we have Cython available
259
command_classes['build_ext'] = build_ext_if_possible
260
unavailable_files = []
263
def add_cython_extension(module_name, libraries=None, extra_source=[]):
264
"""Add a cython module to build.
266
This will use Cython to auto-generate the .c file if it is available.
267
Otherwise it will fall back on the .c file. If the .c file is not
268
available, it will warn, and not add anything.
270
You can pass any extra options to Extension through kwargs. One example is
273
:param module_name: The python path to the module. This will be used to
274
determine the .pyx and .c files to use.
276
path = module_name.replace('.', '/')
277
cython_name = path + '.pyx'
280
if sys.platform == 'win32':
281
# cython uses the macro WIN32 to detect the platform, even though it
282
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
283
# give it the right value.
284
define_macros.append(('WIN32', None))
286
source = [cython_name]
288
if not os.path.isfile(c_name):
289
unavailable_files.append(c_name)
293
source.extend(extra_source)
294
include_dirs = ['breezy']
297
module_name, source, define_macros=define_macros,
298
libraries=libraries, include_dirs=include_dirs))
301
add_cython_extension('breezy._simple_set_pyx')
302
ext_modules.append(Extension('breezy._static_tuple_c',
303
['breezy/_static_tuple_c.c']))
304
add_cython_extension('breezy._annotator_pyx')
305
add_cython_extension('breezy._bencode_pyx')
306
add_cython_extension('breezy._chunks_to_lines_pyx')
307
add_cython_extension('breezy.bzr._groupcompress_pyx',
308
extra_source=['breezy/bzr/diff-delta.c'])
309
add_cython_extension('breezy.bzr._knit_load_data_pyx')
310
add_cython_extension('breezy._known_graph_pyx')
311
add_cython_extension('breezy._rio_pyx')
312
if sys.platform == 'win32':
313
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
314
libraries=['Ws2_32'])
315
add_cython_extension('breezy._walkdirs_win32')
317
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
318
add_cython_extension('breezy._readdir_pyx')
319
add_cython_extension('breezy.bzr._chk_map_pyx')
320
ext_modules.append(Extension('breezy._patiencediff_c',
321
['breezy/_patiencediff_c.c']))
322
add_cython_extension('breezy.bzr._btree_serializer_pyx')
325
if unavailable_files:
326
print('C extension(s) not found:')
327
print((' %s' % ('\n '.join(unavailable_files),)))
328
print('The python versions will be used instead.')
332
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
333
gui_targets, data_files):
334
packages.append('tbzrcommands')
336
# ModuleFinder can't handle runtime changes to __path__, but
337
# win32com uses them. Hook this in so win32com.shell is found.
340
import cPickle as pickle
341
for p in win32com.__path__[1:]:
342
modulefinder.AddPackagePath("win32com", p)
343
for extra in ["win32com.shell"]:
345
m = sys.modules[extra]
346
for p in m.__path__[1:]:
347
modulefinder.AddPackagePath(extra, p)
349
# TBZR points to the TBZR directory
350
tbzr_root = os.environ["TBZR"]
352
# Ensure tbreezy itself is on sys.path
353
sys.path.append(tbzr_root)
355
packages.append("tbreezy")
357
# collect up our icons.
359
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
360
icos = [] # list of (path_root, relative_ico_path)
361
# First always brz's icon and its in the root of the brz tree.
362
icos.append(('', 'brz.ico'))
363
for root, dirs, files in os.walk(ico_root):
364
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root) + 1:])
365
for f in files if f.endswith('.ico')])
366
# allocate an icon ID for each file and the full path to the ico
367
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
368
for rid, (ico_dir, ico_name) in enumerate(icos)]
369
# create a string resource with the mapping. Might as well save the
370
# runtime some effort and write a pickle.
371
# Runtime expects unicode objects with forward-slash seps.
372
fse = sys.getfilesystemencoding()
373
map_items = [(f.replace('\\', '/').decode(fse), rid)
374
for rid, (_, f) in enumerate(icos)]
375
ico_map = dict(map_items)
376
# Create a new resource type of 'ICON_MAP', and use ID=1
377
other_resources = [("ICON_MAP", 1, pickle.dumps(ico_map))]
379
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
380
win32ui crawler.Crawler""".split())
382
# tbzrcache executables - a "console" version for debugging and a
383
# GUI version that is generally used.
385
script=os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
386
icon_resources=icon_resources,
387
other_resources=other_resources,
389
console_targets.append(tbzrcache)
391
# Make a windows version which is the same except for the base name.
392
tbzrcachew = tbzrcache.copy()
393
tbzrcachew["dest_base"] = "tbzrcachew"
394
gui_targets.append(tbzrcachew)
396
# ditto for the tbzrcommand tool
398
script=os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
399
icon_resources=icon_resources,
400
other_resources=other_resources,
402
console_targets.append(tbzrcommand)
403
tbzrcommandw = tbzrcommand.copy()
404
tbzrcommandw["dest_base"] = "tbzrcommandw"
405
gui_targets.append(tbzrcommandw)
407
# A utility to see python output from both C++ and Python based shell
409
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
410
console_targets.append(tracer)
412
# The C++ implemented shell extensions.
413
dist_dir = os.path.join(tbzr_root, "shellext", "build")
414
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
415
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
418
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
419
# PyQt4 itself still escapes the plugin detection code for some reason...
420
includes.append('PyQt4.QtCore')
421
includes.append('PyQt4.QtGui')
422
includes.append('PyQt4.QtTest')
423
includes.append('sip') # extension module required for Qt.
424
packages.append('pygments') # colorizer for qbzr
425
packages.append('docutils') # html formatting
426
includes.append('win32event') # for qsubprocess stuff
427
# the qt binaries might not be on PATH...
428
# They seem to install to a place like C:\Python25\PyQt4\*
429
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
430
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
431
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
432
if os.path.isdir(pyqt_bin_dir):
433
path = os.environ.get("PATH", "")
434
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
435
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
436
# also add all imageformat plugins to distribution
437
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
438
base_dirs_to_check = []
439
if os.path.isdir(pyqt_dir):
440
base_dirs_to_check.append(pyqt_dir)
446
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
447
if pyqt4_base_dir != pyqt_dir:
448
base_dirs_to_check.append(pyqt4_base_dir)
449
if not base_dirs_to_check:
450
log.warn("Can't find PyQt4 installation -> not including imageformat"
454
for base_dir in base_dirs_to_check:
455
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
456
if os.path.isdir(plug_dir):
457
for fname in os.listdir(plug_dir):
458
# Include plugin dlls, but not debugging dlls
459
fullpath = os.path.join(plug_dir, fname)
460
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
461
files.append(fullpath)
463
data_files.append(('imageformats', files))
465
log.warn('PyQt4 was found, but we could not find any imageformat'
466
' plugins. Are you sure your configuration is correct?')
469
def get_svn_py2exe_info(includes, excludes, packages):
470
packages.append('subvertpy')
471
packages.append('sqlite3')
474
def get_git_py2exe_info(includes, excludes, packages):
475
packages.append('dulwich')
478
def get_fastimport_py2exe_info(includes, excludes, packages):
479
# This is the python-fastimport package, not to be confused with the
480
# brz-fastimport plugin.
481
packages.append('fastimport')
484
if 'bdist_wininst' in sys.argv:
487
for root, dirs, files in os.walk('doc'):
490
if (os.path.splitext(f)[1] in ('.html', '.css', '.png', '.pdf')
491
or f == 'quick-start-summary.svg'):
492
r.append(os.path.join(root, f))
496
target = os.path.join('Doc\\Breezy', relative)
498
target = 'Doc\\Breezy'
499
docs.append((target, r))
502
# python's distutils-based win32 installer
503
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
504
'ext_modules': ext_modules,
506
'data_files': find_docs(),
507
# for building cython extensions
508
'cmdclass': command_classes,
511
ARGS.update(META_INFO)
513
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
514
ARGS.update(PKG_DATA)
518
elif 'py2exe' in sys.argv:
522
# pick real brz version
526
for i in breezy.version_info[:4]:
531
version_number.append(str(i))
532
version_str = '.'.join(version_number)
534
# An override to install_data used only by py2exe builds, which arranges
535
# to byte-compile any .py files in data_files (eg, our plugins)
536
# Necessary as we can't rely on the user having the relevant permissions
537
# to the "Program Files" directory to generate them on the fly.
538
class install_data_with_bytecompile(install_data):
540
from distutils.util import byte_compile
542
install_data.run(self)
544
py2exe = self.distribution.get_command_obj('py2exe', False)
545
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
546
# time before living with docstring stripping
548
compile_names = [f for f in self.outfiles if f.endswith('.py')]
549
# Round mtime to nearest even second so that installing on a FAT
550
# filesystem bytecode internal and script timestamps will match
551
for f in compile_names:
552
mtime = os.stat(f).st_mtime
553
remainder = mtime % 2
556
os.utime(f, (mtime, mtime))
557
byte_compile(compile_names,
559
force=self.force, prefix=self.install_dir,
560
dry_run=self.dry_run)
561
self.outfiles.extend([f + 'o' for f in compile_names])
562
# end of class install_data_with_bytecompile
564
target = py2exe.build_exe.Target(
567
icon_resources=[(0, 'brz.ico')],
568
name=META_INFO['name'],
570
description=META_INFO['description'],
571
author=META_INFO['author'],
572
copyright="(c) Canonical Ltd, 2005-2010",
573
company_name="Canonical Ltd.",
574
comments=META_INFO['description'],
576
gui_target = copy.copy(target)
577
gui_target.dest_base = "bzrw"
579
packages = BREEZY['packages']
580
packages.remove('breezy')
581
packages = [i for i in packages if not i.startswith('breezy.plugins')]
583
for i in glob.glob('breezy\\*.py'):
584
module = i[:-3].replace('\\', '.')
585
if module.endswith('__init__'):
586
module = module[:-len('__init__')]
587
includes.append(module)
589
additional_packages = set()
590
if sys.version.startswith('2.7'):
591
additional_packages.add('xml.etree')
594
warnings.warn('Unknown Python version.\n'
595
'Please check setup.py script for compatibility.')
597
# Although we currently can't enforce it, we consider it an error for
598
# py2exe to report any files are "missing". Such modules we know aren't
599
# used should be listed here.
600
excludes = """Tkinter psyco ElementPath r_hmac
601
ImaginaryModule cElementTree elementtree.ElementTree
602
Crypto.PublicKey._fastmath
604
resource validate""".split()
607
# email package from std python library use lazy import,
608
# so we need to explicitly add all package
609
additional_packages.add('email')
610
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
611
# a result, packages like 'email.Parser' show as missing. Tell py2exe
614
for oldname in getattr(email, '_LOWERNAMES', []):
615
excludes.append("email." + oldname)
616
for oldname in getattr(email, '_MIMENAMES', []):
617
excludes.append("email.MIME" + oldname)
619
# text files for help topis
620
text_topics = glob.glob('breezy/help_topics/en/*.txt')
621
topics_files = [('lib/help_topics/en', text_topics)]
625
# XXX - should we consider having the concept of an 'official' build,
626
# which hard-codes the list of plugins, gets more upset if modules are
628
plugins = None # will be a set after plugin sniffing...
629
for root, dirs, files in os.walk('breezy/plugins'):
630
if root == 'breezy/plugins':
632
# We ship plugins as normal files on the file-system - however,
633
# the build process can cause *some* of these plugin files to end
634
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
635
# library.zip, and then saw import errors related to that as the
636
# rest of the svn plugin wasn't. So we tell py2exe to leave the
637
# plugins out of the .zip file
638
excludes.extend(["breezy.plugins." + d for d in dirs])
641
# Throw away files we don't want packaged. Note that plugins may
642
# have data files with all sorts of extensions so we need to
643
# be conservative here about what we ditch.
644
ext = os.path.splitext(i)[1]
645
if ext.endswith('~') or ext in [".pyc", ".swp"]:
647
if i == '__init__.py' and root == 'breezy/plugins':
649
x.append(os.path.join(root, i))
651
target_dir = root[len('breezy/'):] # install to 'plugins/...'
652
plugins_files.append((target_dir, x))
653
# find modules for built-in plugins
654
import tools.package_mf
655
mf = tools.package_mf.CustomModuleFinder()
656
mf.run_package('breezy/plugins')
657
packs, mods = mf.get_result()
658
additional_packages.update(packs)
659
includes.extend(mods)
661
console_targets = [target,
662
'tools/win32/bzr_postinstall.py',
664
gui_targets = [gui_target]
665
data_files = topics_files + plugins_files + I18N_FILES
667
if 'qbzr' in plugins:
668
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
671
get_svn_py2exe_info(includes, excludes, packages)
674
get_git_py2exe_info(includes, excludes, packages)
676
if 'fastimport' in plugins:
677
get_fastimport_py2exe_info(includes, excludes, packages)
679
if "TBZR" in os.environ:
680
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
681
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
682
# can be downloaded from (username=guest, blank password):
683
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
684
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
685
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
686
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
687
'TORTOISE_OVERLAYS_MSI_X64'):
688
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
690
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
692
"\nPlease set %s to the location of the relevant"
693
"\nTortoiseOverlays .msi installer file."
694
" The installers can be found at"
696
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
697
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
698
gui_targets, data_files)
700
# print this warning to stderr as output is redirected, so it is seen
701
# at build time. Also to stdout so it appears in the log
702
for f in (sys.stderr, sys.stdout):
703
f.write("Skipping TBZR binaries - "
704
"please set TBZR to a directory to enable\n")
706
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
708
dll_excludes.extend(["MSWSOCK.dll",
713
options_list = {"py2exe": {"packages": packages + list(additional_packages),
714
"includes": includes,
715
"excludes": excludes,
716
"dll_excludes": dll_excludes,
717
"dist_dir": "win32_bzr.exe",
719
"custom_boot_script":
720
"tools/win32/py2exe_boot_common.py",
724
# We want the libaray.zip to have optimize = 2, but the exe to have
725
# optimize = 1, so that .py files that get compilied at run time
726
# (e.g. user installed plugins) dont have their doc strings removed.
727
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
728
def build_executable(self, *args, **kwargs):
730
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
733
if __name__ == '__main__':
734
command_classes['install_data'] = install_data_with_bytecompile
735
command_classes['py2exe'] = py2exe_no_oo_exe
736
setup(options=options_list,
737
console=console_targets,
739
zipfile='lib/library.zip',
740
data_files=data_files,
741
cmdclass=command_classes,
745
# ad-hoc for easy_install
747
if 'bdist_egg' not in sys.argv:
748
# generate and install brz.1 only with plain install, not the
750
DATA_FILES = [('man/man1', ['brz.1', 'breezy/git/git-remote-bzr.1'])]
752
DATA_FILES = DATA_FILES + I18N_FILES
754
ARGS = {'scripts': ['brz',
755
# TODO(jelmer): Only install the git scripts if
757
'breezy/git/git-remote-bzr',
758
'breezy/git/bzr-receive-pack',
759
'breezy/git/bzr-upload-pack'],
760
'data_files': DATA_FILES,
761
'cmdclass': command_classes,
762
'ext_modules': ext_modules,
765
ARGS.update(META_INFO)
767
ARGS.update(PKG_DATA)
769
if __name__ == '__main__':