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.
68
'launchpad': ['launchpadlib>=1.6.3'],
75
# The list of packages is automatically generated later. Add other things
76
# that are part of BREEZY here.
80
# install files from selftest suite
81
'package_data': {'breezy': ['doc/api/*.txt',
82
'tests/test_patches_data/*',
83
'help_topics/en/*.txt',
84
'tests/ssl_certs/ca.crt',
85
'tests/ssl_certs/server_without_pass.key',
86
'tests/ssl_certs/server_with_pass.key',
87
'tests/ssl_certs/server.crt',
91
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
92
langfile = filepath[len("breezy/locale/"):]
93
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
94
I18N_FILES.append((targetpath, [filepath]))
96
def get_breezy_packages():
97
"""Recurse through the breezy directory, and extract the package names"""
100
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
101
for root, dirs, files in os.walk(base_path):
102
if '__init__.py' in files:
103
assert root.startswith(base_path)
104
# Get just the path below breezy
105
package_path = root[len(base_path):]
106
# Remove leading and trailing slashes
107
package_path = package_path.strip('\\/')
109
package_name = 'breezy'
113
package_path.replace('/', '.').replace('\\', '.'))
114
packages.append(package_name)
115
return sorted(packages)
118
BREEZY['packages'] = get_breezy_packages()
121
from distutils import log
37
122
from distutils.core import setup
123
from distutils.version import LooseVersion
38
124
from distutils.command.install_scripts import install_scripts
125
from distutils.command.install_data import install_data
39
126
from distutils.command.build import build
41
128
###############################
45
132
class my_install_scripts(install_scripts):
46
133
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
134
Create brz.bat for win32.
53
137
install_scripts.run(self) # standard action
55
139
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)
141
scripts_dir = os.path.join(sys.prefix, 'Scripts')
142
script_path = self._quoted_path(os.path.join(scripts_dir,
144
python_exe = self._quoted_path(sys.executable)
145
args = self._win_batch_args()
146
batch_str = "@%s %s %s" % (python_exe, script_path, args)
147
batch_path = os.path.join(self.install_dir, "brz.bat")
148
with open(batch_path, "w") as f:
150
print(("Created: %s" % batch_path))
152
e = sys.exc_info()[1]
153
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
155
def _quoted_path(self, path):
157
return '"' + path + '"'
161
def _win_batch_args(self):
162
from breezy.win32utils import winver
163
if winver == 'Windows NT':
166
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
167
#/class my_install_scripts
69
170
class bzr_build(build):
70
171
"""Customized build distutils action.
175
sub_commands = build.sub_commands + [
176
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
182
from tools import generate_docs
183
generate_docs.main(argv=["brz", "man"])
79
186
########################
81
188
########################
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.
190
from breezy.bzr_distutils import build_mo
192
command_classes = {'install_scripts': my_install_scripts,
194
'build_mo': build_mo,
196
from distutils import log
197
from distutils.errors import CCompilerError, DistutilsPlatformError
198
from distutils.extension import Extension
201
from Cython.Distutils import build_ext
202
from Cython.Compiler.Version import version as cython_version
205
# try to build the extension from the prior generated source.
207
print("The python package 'Cython' is not available."
208
" If the .c files are available,")
209
print("they will be built,"
210
" but modifying the .pyx files will not rebuild them.")
212
from distutils.command.build_ext import build_ext
215
cython_version_info = LooseVersion(cython_version)
218
class build_ext_if_possible(build_ext):
220
user_options = build_ext.user_options + [
221
('allow-python-fallback', None,
222
"When an extension cannot be built, allow falling"
223
" back to the pure-python implementation.")
226
def initialize_options(self):
227
build_ext.initialize_options(self)
228
self.allow_python_fallback = False
233
except DistutilsPlatformError:
234
e = sys.exc_info()[1]
235
if not self.allow_python_fallback:
236
log.warn('\n Cannot build extensions.\n'
237
' Use "build_ext --allow-python-fallback" to use'
238
' slower python implementations instead.\n')
241
log.warn('\n Extensions cannot be built.\n'
242
' Using the slower Python implementations instead.\n')
244
def build_extension(self, ext):
246
build_ext.build_extension(self, ext)
247
except CCompilerError:
248
if not self.allow_python_fallback:
249
log.warn('\n Cannot build extension "%s".\n'
250
' Use "build_ext --allow-python-fallback" to use'
251
' slower python implementations instead.\n'
254
log.warn('\n Building of "%s" extension failed.\n'
255
' Using the slower Python implementation instead.'
259
# Override the build_ext if we have Cython available
260
command_classes['build_ext'] = build_ext_if_possible
261
unavailable_files = []
264
def add_cython_extension(module_name, libraries=None, extra_source=[]):
265
"""Add a cython module to build.
267
This will use Cython to auto-generate the .c file if it is available.
268
Otherwise it will fall back on the .c file. If the .c file is not
269
available, it will warn, and not add anything.
271
You can pass any extra options to Extension through kwargs. One example is
274
:param module_name: The python path to the module. This will be used to
275
determine the .pyx and .c files to use.
277
path = module_name.replace('.', '/')
278
cython_name = path + '.pyx'
281
if sys.platform == 'win32':
282
# cython uses the macro WIN32 to detect the platform, even though it
283
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
284
# give it the right value.
285
define_macros.append(('WIN32', None))
287
source = [cython_name]
289
if not os.path.isfile(c_name):
290
unavailable_files.append(c_name)
294
source.extend(extra_source)
295
include_dirs = ['breezy']
298
module_name, source, define_macros=define_macros,
299
libraries=libraries, include_dirs=include_dirs))
302
add_cython_extension('breezy._simple_set_pyx')
303
ext_modules.append(Extension('breezy._static_tuple_c',
304
['breezy/_static_tuple_c.c']))
305
add_cython_extension('breezy._annotator_pyx')
306
add_cython_extension('breezy._bencode_pyx')
307
add_cython_extension('breezy._chunks_to_lines_pyx')
308
add_cython_extension('breezy.bzr._groupcompress_pyx',
309
extra_source=['breezy/bzr/diff-delta.c'])
310
add_cython_extension('breezy.bzr._knit_load_data_pyx')
311
add_cython_extension('breezy._known_graph_pyx')
312
add_cython_extension('breezy._rio_pyx')
313
if sys.platform == 'win32':
314
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
315
libraries=['Ws2_32'])
316
add_cython_extension('breezy._walkdirs_win32')
318
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
319
add_cython_extension('breezy._readdir_pyx')
320
add_cython_extension('breezy.bzr._chk_map_pyx')
321
ext_modules.append(Extension('breezy._patiencediff_c',
322
['breezy/_patiencediff_c.c']))
323
add_cython_extension('breezy.bzr._btree_serializer_pyx')
326
if unavailable_files:
327
print('C extension(s) not found:')
328
print((' %s' % ('\n '.join(unavailable_files),)))
329
print('The python versions will be used instead.')
333
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
334
gui_targets, data_files):
335
packages.append('tbzrcommands')
337
# ModuleFinder can't handle runtime changes to __path__, but
338
# win32com uses them. Hook this in so win32com.shell is found.
341
import cPickle as pickle
342
for p in win32com.__path__[1:]:
343
modulefinder.AddPackagePath("win32com", p)
344
for extra in ["win32com.shell"]:
346
m = sys.modules[extra]
347
for p in m.__path__[1:]:
348
modulefinder.AddPackagePath(extra, p)
350
# TBZR points to the TBZR directory
351
tbzr_root = os.environ["TBZR"]
353
# Ensure tbreezy itself is on sys.path
354
sys.path.append(tbzr_root)
356
packages.append("tbreezy")
358
# collect up our icons.
360
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
361
icos = [] # list of (path_root, relative_ico_path)
362
# First always brz's icon and its in the root of the brz tree.
363
icos.append(('', 'brz.ico'))
364
for root, dirs, files in os.walk(ico_root):
365
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root) + 1:])
366
for f in files if f.endswith('.ico')])
367
# allocate an icon ID for each file and the full path to the ico
368
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
369
for rid, (ico_dir, ico_name) in enumerate(icos)]
370
# create a string resource with the mapping. Might as well save the
371
# runtime some effort and write a pickle.
372
# Runtime expects unicode objects with forward-slash seps.
373
fse = sys.getfilesystemencoding()
374
map_items = [(f.replace('\\', '/').decode(fse), rid)
375
for rid, (_, f) in enumerate(icos)]
376
ico_map = dict(map_items)
377
# Create a new resource type of 'ICON_MAP', and use ID=1
378
other_resources = [("ICON_MAP", 1, pickle.dumps(ico_map))]
380
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
381
win32ui crawler.Crawler""".split())
383
# tbzrcache executables - a "console" version for debugging and a
384
# GUI version that is generally used.
386
script=os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
387
icon_resources=icon_resources,
388
other_resources=other_resources,
390
console_targets.append(tbzrcache)
392
# Make a windows version which is the same except for the base name.
393
tbzrcachew = tbzrcache.copy()
394
tbzrcachew["dest_base"] = "tbzrcachew"
395
gui_targets.append(tbzrcachew)
397
# ditto for the tbzrcommand tool
399
script=os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
400
icon_resources=icon_resources,
401
other_resources=other_resources,
403
console_targets.append(tbzrcommand)
404
tbzrcommandw = tbzrcommand.copy()
405
tbzrcommandw["dest_base"] = "tbzrcommandw"
406
gui_targets.append(tbzrcommandw)
408
# A utility to see python output from both C++ and Python based shell
410
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
411
console_targets.append(tracer)
413
# The C++ implemented shell extensions.
414
dist_dir = os.path.join(tbzr_root, "shellext", "build")
415
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
416
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
419
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
420
# PyQt4 itself still escapes the plugin detection code for some reason...
421
includes.append('PyQt4.QtCore')
422
includes.append('PyQt4.QtGui')
423
includes.append('PyQt4.QtTest')
424
includes.append('sip') # extension module required for Qt.
425
packages.append('pygments') # colorizer for qbzr
426
packages.append('docutils') # html formatting
427
includes.append('win32event') # for qsubprocess stuff
428
# the qt binaries might not be on PATH...
429
# They seem to install to a place like C:\Python25\PyQt4\*
430
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
431
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
432
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
433
if os.path.isdir(pyqt_bin_dir):
434
path = os.environ.get("PATH", "")
435
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
436
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
437
# also add all imageformat plugins to distribution
438
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
439
base_dirs_to_check = []
440
if os.path.isdir(pyqt_dir):
441
base_dirs_to_check.append(pyqt_dir)
447
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
448
if pyqt4_base_dir != pyqt_dir:
449
base_dirs_to_check.append(pyqt4_base_dir)
450
if not base_dirs_to_check:
451
log.warn("Can't find PyQt4 installation -> not including imageformat"
455
for base_dir in base_dirs_to_check:
456
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
457
if os.path.isdir(plug_dir):
458
for fname in os.listdir(plug_dir):
459
# Include plugin dlls, but not debugging dlls
460
fullpath = os.path.join(plug_dir, fname)
461
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
462
files.append(fullpath)
464
data_files.append(('imageformats', files))
466
log.warn('PyQt4 was found, but we could not find any imageformat'
467
' plugins. Are you sure your configuration is correct?')
470
def get_svn_py2exe_info(includes, excludes, packages):
471
packages.append('subvertpy')
472
packages.append('sqlite3')
475
def get_git_py2exe_info(includes, excludes, packages):
476
packages.append('dulwich')
479
def get_fastimport_py2exe_info(includes, excludes, packages):
480
# This is the python-fastimport package, not to be confused with the
481
# brz-fastimport plugin.
482
packages.append('fastimport')
485
if 'bdist_wininst' in sys.argv:
488
for root, dirs, files in os.walk('doc'):
491
if (os.path.splitext(f)[1] in ('.html', '.css', '.png', '.pdf')
492
or f == 'quick-start-summary.svg'):
493
r.append(os.path.join(root, f))
497
target = os.path.join('Doc\\Breezy', relative)
499
target = 'Doc\\Breezy'
500
docs.append((target, r))
503
# python's distutils-based win32 installer
504
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
505
'ext_modules': ext_modules,
507
'data_files': find_docs(),
508
# for building cython extensions
509
'cmdclass': command_classes,
512
ARGS.update(META_INFO)
514
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
515
ARGS.update(PKG_DATA)
519
elif 'py2exe' in sys.argv:
523
# pick real brz version
527
for i in breezy.version_info[:4]:
532
version_number.append(str(i))
533
version_str = '.'.join(version_number)
535
# An override to install_data used only by py2exe builds, which arranges
536
# to byte-compile any .py files in data_files (eg, our plugins)
537
# Necessary as we can't rely on the user having the relevant permissions
538
# to the "Program Files" directory to generate them on the fly.
539
class install_data_with_bytecompile(install_data):
541
from distutils.util import byte_compile
543
install_data.run(self)
545
py2exe = self.distribution.get_command_obj('py2exe', False)
546
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
547
# time before living with docstring stripping
549
compile_names = [f for f in self.outfiles if f.endswith('.py')]
550
# Round mtime to nearest even second so that installing on a FAT
551
# filesystem bytecode internal and script timestamps will match
552
for f in compile_names:
553
mtime = os.stat(f).st_mtime
554
remainder = mtime % 2
557
os.utime(f, (mtime, mtime))
558
byte_compile(compile_names,
560
force=self.force, prefix=self.install_dir,
561
dry_run=self.dry_run)
562
self.outfiles.extend([f + 'o' for f in compile_names])
563
# end of class install_data_with_bytecompile
565
target = py2exe.build_exe.Target(
568
icon_resources=[(0, 'brz.ico')],
569
name=META_INFO['name'],
571
description=META_INFO['description'],
572
author=META_INFO['author'],
573
copyright="(c) Canonical Ltd, 2005-2010",
574
company_name="Canonical Ltd.",
575
comments=META_INFO['description'],
577
gui_target = copy.copy(target)
578
gui_target.dest_base = "bzrw"
580
packages = BREEZY['packages']
581
packages.remove('breezy')
582
packages = [i for i in packages if not i.startswith('breezy.plugins')]
584
for i in glob.glob('breezy\\*.py'):
585
module = i[:-3].replace('\\', '.')
586
if module.endswith('__init__'):
587
module = module[:-len('__init__')]
588
includes.append(module)
590
additional_packages = set()
591
if sys.version.startswith('2.7'):
592
additional_packages.add('xml.etree')
595
warnings.warn('Unknown Python version.\n'
596
'Please check setup.py script for compatibility.')
598
# Although we currently can't enforce it, we consider it an error for
599
# py2exe to report any files are "missing". Such modules we know aren't
600
# used should be listed here.
601
excludes = """Tkinter psyco ElementPath r_hmac
602
ImaginaryModule cElementTree elementtree.ElementTree
603
Crypto.PublicKey._fastmath
605
resource validate""".split()
608
# email package from std python library use lazy import,
609
# so we need to explicitly add all package
610
additional_packages.add('email')
611
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
612
# a result, packages like 'email.Parser' show as missing. Tell py2exe
615
for oldname in getattr(email, '_LOWERNAMES', []):
616
excludes.append("email." + oldname)
617
for oldname in getattr(email, '_MIMENAMES', []):
618
excludes.append("email.MIME" + oldname)
620
# text files for help topis
621
text_topics = glob.glob('breezy/help_topics/en/*.txt')
622
topics_files = [('lib/help_topics/en', text_topics)]
626
# XXX - should we consider having the concept of an 'official' build,
627
# which hard-codes the list of plugins, gets more upset if modules are
629
plugins = None # will be a set after plugin sniffing...
630
for root, dirs, files in os.walk('breezy/plugins'):
631
if root == 'breezy/plugins':
633
# We ship plugins as normal files on the file-system - however,
634
# the build process can cause *some* of these plugin files to end
635
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
636
# library.zip, and then saw import errors related to that as the
637
# rest of the svn plugin wasn't. So we tell py2exe to leave the
638
# plugins out of the .zip file
639
excludes.extend(["breezy.plugins." + d for d in dirs])
642
# Throw away files we don't want packaged. Note that plugins may
643
# have data files with all sorts of extensions so we need to
644
# be conservative here about what we ditch.
645
ext = os.path.splitext(i)[1]
646
if ext.endswith('~') or ext in [".pyc", ".swp"]:
648
if i == '__init__.py' and root == 'breezy/plugins':
650
x.append(os.path.join(root, i))
652
target_dir = root[len('breezy/'):] # install to 'plugins/...'
653
plugins_files.append((target_dir, x))
654
# find modules for built-in plugins
655
import tools.package_mf
656
mf = tools.package_mf.CustomModuleFinder()
657
mf.run_package('breezy/plugins')
658
packs, mods = mf.get_result()
659
additional_packages.update(packs)
660
includes.extend(mods)
662
console_targets = [target,
663
'tools/win32/bzr_postinstall.py',
665
gui_targets = [gui_target]
666
data_files = topics_files + plugins_files + I18N_FILES
668
if 'qbzr' in plugins:
669
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
672
get_svn_py2exe_info(includes, excludes, packages)
675
get_git_py2exe_info(includes, excludes, packages)
677
if 'fastimport' in plugins:
678
get_fastimport_py2exe_info(includes, excludes, packages)
680
if "TBZR" in os.environ:
681
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
682
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
683
# can be downloaded from (username=guest, blank password):
684
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
685
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
686
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
687
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
688
'TORTOISE_OVERLAYS_MSI_X64'):
689
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
691
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
693
"\nPlease set %s to the location of the relevant"
694
"\nTortoiseOverlays .msi installer file."
695
" The installers can be found at"
697
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
698
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
699
gui_targets, data_files)
701
# print this warning to stderr as output is redirected, so it is seen
702
# at build time. Also to stdout so it appears in the log
703
for f in (sys.stderr, sys.stdout):
704
f.write("Skipping TBZR binaries - "
705
"please set TBZR to a directory to enable\n")
707
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
709
dll_excludes.extend(["MSWSOCK.dll",
714
options_list = {"py2exe": {"packages": packages + list(additional_packages),
715
"includes": includes,
716
"excludes": excludes,
717
"dll_excludes": dll_excludes,
718
"dist_dir": "win32_bzr.exe",
720
"custom_boot_script":
721
"tools/win32/py2exe_boot_common.py",
725
# We want the libaray.zip to have optimize = 2, but the exe to have
726
# optimize = 1, so that .py files that get compilied at run time
727
# (e.g. user installed plugins) dont have their doc strings removed.
728
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
729
def build_executable(self, *args, **kwargs):
731
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
734
if __name__ == '__main__':
735
command_classes['install_data'] = install_data_with_bytecompile
736
command_classes['py2exe'] = py2exe_no_oo_exe
737
setup(options=options_list,
738
console=console_targets,
740
zipfile='lib/library.zip',
741
data_files=data_files,
742
cmdclass=command_classes,
746
# ad-hoc for easy_install
748
if 'bdist_egg' not in sys.argv:
749
# generate and install brz.1 only with plain install, not the
751
DATA_FILES = [('man/man1', ['brz.1', 'breezy/git/git-remote-bzr.1'])]
753
DATA_FILES = DATA_FILES + I18N_FILES
755
ARGS = {'scripts': ['brz',
756
# TODO(jelmer): Only install the git scripts if
758
'breezy/git/git-remote-bzr',
759
'breezy/git/bzr-receive-pack',
760
'breezy/git/bzr-upload-pack'],
761
'data_files': DATA_FILES,
762
'cmdclass': command_classes,
763
'ext_modules': ext_modules,
766
ARGS.update(META_INFO)
768
ARGS.update(PKG_DATA)
770
if __name__ == '__main__':