1
#! /usr/bin/env python3
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")
23
sys.stderr.write("[ERROR] Please install setuptools\n")
27
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
28
# './setup.py' or the equivalent with another path, should always be at the
29
# start of the path, so this should find the right one...
32
def get_long_description():
33
dirname = os.path.dirname(__file__)
34
readme = os.path.join(dirname, 'README.rst')
35
with open(readme, 'r') as f:
40
# META INFORMATION FOR SETUP
41
# see http://docs.python.org/dist/meta-data.html
44
'version': breezy.__version__,
45
'maintainer': 'Breezy Developers',
46
'maintainer_email': 'team@breezy-vcs.org',
47
'url': 'https://www.breezy-vcs.org/',
48
'description': 'Friendly distributed version control system',
49
'license': 'GNU GPL v2',
50
'download_url': 'https://launchpad.net/brz/+download',
51
'long_description': get_long_description(),
53
'Development Status :: 6 - Mature',
54
'Environment :: Console',
55
'Intended Audience :: Developers',
56
'Intended Audience :: System Administrators',
57
'License :: OSI Approved :: GNU General Public License (GPL)',
58
'Operating System :: Microsoft :: Windows',
59
'Operating System :: OS Independent',
60
'Operating System :: POSIX',
61
'Programming Language :: Python',
62
'Programming Language :: C',
63
'Topic :: Software Development :: Version Control',
69
# Technically, Breezy works without these two dependencies too. But there's
70
# no way to enable them by default and let users opt out.
77
'launchpad': ['launchpadlib>=1.6.3'],
84
# The list of packages is automatically generated later. Add other things
85
# that are part of BREEZY here.
89
# install files from selftest suite
90
'package_data': {'breezy': ['doc/api/*.txt',
91
'tests/test_patches_data/*',
92
'help_topics/en/*.txt',
93
'tests/ssl_certs/ca.crt',
94
'tests/ssl_certs/server_without_pass.key',
95
'tests/ssl_certs/server_with_pass.key',
96
'tests/ssl_certs/server.crt',
100
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
101
langfile = filepath[len("breezy/locale/"):]
102
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
103
I18N_FILES.append((targetpath, [filepath]))
105
def get_breezy_packages():
106
"""Recurse through the breezy directory, and extract the package names"""
109
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
110
for root, dirs, files in os.walk(base_path):
111
if '__init__.py' in files:
112
assert root.startswith(base_path)
113
# Get just the path below breezy
114
package_path = root[len(base_path):]
115
# Remove leading and trailing slashes
116
package_path = package_path.strip('\\/')
118
package_name = 'breezy'
122
package_path.replace('/', '.').replace('\\', '.'))
123
packages.append(package_name)
124
return sorted(packages)
127
BREEZY['packages'] = get_breezy_packages()
130
from setuptools import setup
131
from distutils.version import LooseVersion
132
from distutils.command.install_scripts import install_scripts
133
from distutils.command.install_data import install_data
134
from distutils.command.build import build
3
# This is an installation script for bzr. Run it with
4
# './setup.py install', or
5
# './setup.py --help' for more options
7
from distutils.core import setup
9
# more sophisticated setup script, based on pychecker setup.py
11
from distutils.command.build_scripts import build_scripts
136
14
###############################
137
15
# Overridden distutils actions
138
16
###############################
140
class my_install_scripts(install_scripts):
141
""" Customized install_scripts distutils action.
142
Create brz.bat for win32.
18
class my_build_scripts(build_scripts):
19
"""Customized build_scripts distutils action.
21
Create bzr.bat for win32.
145
install_scripts.run(self) # standard action
147
25
if sys.platform == "win32":
149
scripts_dir = os.path.join(sys.prefix, 'Scripts')
150
script_path = self._quoted_path(os.path.join(scripts_dir,
152
python_exe = self._quoted_path(sys.executable)
153
batch_str = "@%s %s %%*" % (python_exe, script_path)
154
batch_path = os.path.join(self.install_dir, "brz.bat")
155
with open(batch_path, "w") as f:
157
print(("Created: %s" % batch_path))
159
e = sys.exc_info()[1]
160
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
162
def _quoted_path(self, path):
164
return '"' + path + '"'
167
#/class my_install_scripts
170
class bzr_build(build):
171
"""Customized build distutils action.
175
sub_commands = build.sub_commands + [
176
('build_mo', lambda _: True),
182
from tools import generate_docs
183
generate_docs.main(argv=["brz", "man"])
26
bat_path = os.path.join(self.build_dir, "bzr.bat")
27
self.scripts.append(bat_path)
28
self.mkpath(self.build_dir)
29
scripts_dir = self.distribution.get_command_obj("install").\
31
self.execute(func=self._create_bat,
32
args=[bat_path, scripts_dir],
33
msg="Create %s" % bat_path)
34
build_scripts.run(self) # invoke "standard" action
36
def _create_bat(self, bat_path, scripts_dir):
37
""" Creates the batch file for bzr on win32.
40
script_path = os.path.join(scripts_dir, "bzr")
41
bat_str = "@%s %s %%*\n" % (sys.executable, script_path)
42
file(bat_path, "w").write(bat_str)
45
print "ERROR: Unable to create %s: %s" % (bat_path, e)
186
49
########################
188
51
########################
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
214
minimum_cython_version = '0.29'
215
cython_version_info = LooseVersion(cython_version)
216
if cython_version_info < LooseVersion(minimum_cython_version):
217
print("Version of Cython is too old. "
218
"Current is %s, need at least %s."
219
% (cython_version, minimum_cython_version))
220
print("If the .c files are available, they will be built,"
221
" but modifying the .pyx files will not rebuild them.")
227
class build_ext_if_possible(build_ext):
229
user_options = build_ext.user_options + [
230
('allow-python-fallback', None,
231
"When an extension cannot be built, allow falling"
232
" back to the pure-python implementation.")
235
def initialize_options(self):
236
build_ext.initialize_options(self)
237
self.allow_python_fallback = False
242
except DistutilsPlatformError:
243
e = sys.exc_info()[1]
244
if not self.allow_python_fallback:
245
log.warn('\n Cannot build extensions.\n'
246
' Use "build_ext --allow-python-fallback" to use'
247
' slower python implementations instead.\n')
250
log.warn('\n Extensions cannot be built.\n'
251
' Using the slower Python implementations instead.\n')
253
def build_extension(self, ext):
255
build_ext.build_extension(self, ext)
256
except CCompilerError:
257
if not self.allow_python_fallback:
258
log.warn('\n Cannot build extension "%s".\n'
259
' Use "build_ext --allow-python-fallback" to use'
260
' slower python implementations instead.\n'
263
log.warn('\n Building of "%s" extension failed.\n'
264
' Using the slower Python implementation instead.'
268
# Override the build_ext if we have Cython available
269
command_classes['build_ext'] = build_ext_if_possible
270
unavailable_files = []
273
def add_cython_extension(module_name, libraries=None, extra_source=[]):
274
"""Add a cython module to build.
276
This will use Cython to auto-generate the .c file if it is available.
277
Otherwise it will fall back on the .c file. If the .c file is not
278
available, it will warn, and not add anything.
280
You can pass any extra options to Extension through kwargs. One example is
283
:param module_name: The python path to the module. This will be used to
284
determine the .pyx and .c files to use.
286
path = module_name.replace('.', '/')
287
cython_name = path + '.pyx'
290
if sys.platform == 'win32':
291
# cython uses the macro WIN32 to detect the platform, even though it
292
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
293
# give it the right value.
294
define_macros.append(('WIN32', None))
296
source = [cython_name]
298
if not os.path.isfile(c_name):
299
unavailable_files.append(c_name)
303
source.extend(extra_source)
304
include_dirs = ['breezy']
307
module_name, source, define_macros=define_macros,
308
libraries=libraries, include_dirs=include_dirs))
311
add_cython_extension('breezy._simple_set_pyx')
312
ext_modules.append(Extension('breezy._static_tuple_c',
313
['breezy/_static_tuple_c.c']))
314
add_cython_extension('breezy._annotator_pyx')
315
add_cython_extension('breezy._bencode_pyx')
316
add_cython_extension('breezy._chunks_to_lines_pyx')
317
add_cython_extension('breezy.bzr._groupcompress_pyx',
318
extra_source=['breezy/bzr/diff-delta.c'])
319
add_cython_extension('breezy.bzr._knit_load_data_pyx')
320
add_cython_extension('breezy._known_graph_pyx')
321
add_cython_extension('breezy._rio_pyx')
322
if sys.platform == 'win32':
323
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
324
libraries=['Ws2_32'])
325
add_cython_extension('breezy._walkdirs_win32')
327
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
328
add_cython_extension('breezy._readdir_pyx')
329
add_cython_extension('breezy.bzr._chk_map_pyx')
330
add_cython_extension('breezy.bzr._btree_serializer_pyx')
333
if unavailable_files:
334
print('C extension(s) not found:')
335
print((' %s' % ('\n '.join(unavailable_files),)))
336
print('The python versions will be used instead.')
340
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
341
gui_targets, data_files):
342
packages.append('tbzrcommands')
344
# ModuleFinder can't handle runtime changes to __path__, but
345
# win32com uses them. Hook this in so win32com.shell is found.
348
import cPickle as pickle
349
for p in win32com.__path__[1:]:
350
modulefinder.AddPackagePath("win32com", p)
351
for extra in ["win32com.shell"]:
353
m = sys.modules[extra]
354
for p in m.__path__[1:]:
355
modulefinder.AddPackagePath(extra, p)
357
# TBZR points to the TBZR directory
358
tbzr_root = os.environ["TBZR"]
360
# Ensure tbreezy itself is on sys.path
361
sys.path.append(tbzr_root)
363
packages.append("tbreezy")
365
# collect up our icons.
367
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
368
icos = [] # list of (path_root, relative_ico_path)
369
# First always brz's icon and its in the root of the brz tree.
370
icos.append(('', 'brz.ico'))
371
for root, dirs, files in os.walk(ico_root):
372
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root) + 1:])
373
for f in files if f.endswith('.ico')])
374
# allocate an icon ID for each file and the full path to the ico
375
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
376
for rid, (ico_dir, ico_name) in enumerate(icos)]
377
# create a string resource with the mapping. Might as well save the
378
# runtime some effort and write a pickle.
379
# Runtime expects unicode objects with forward-slash seps.
380
fse = sys.getfilesystemencoding()
381
map_items = [(f.replace('\\', '/').decode(fse), rid)
382
for rid, (_, f) in enumerate(icos)]
383
ico_map = dict(map_items)
384
# Create a new resource type of 'ICON_MAP', and use ID=1
385
other_resources = [("ICON_MAP", 1, pickle.dumps(ico_map))]
387
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
388
win32ui crawler.Crawler""".split())
390
# tbzrcache executables - a "console" version for debugging and a
391
# GUI version that is generally used.
393
script=os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
394
icon_resources=icon_resources,
395
other_resources=other_resources,
397
console_targets.append(tbzrcache)
399
# Make a windows version which is the same except for the base name.
400
tbzrcachew = tbzrcache.copy()
401
tbzrcachew["dest_base"] = "tbzrcachew"
402
gui_targets.append(tbzrcachew)
404
# ditto for the tbzrcommand tool
406
script=os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
407
icon_resources=icon_resources,
408
other_resources=other_resources,
410
console_targets.append(tbzrcommand)
411
tbzrcommandw = tbzrcommand.copy()
412
tbzrcommandw["dest_base"] = "tbzrcommandw"
413
gui_targets.append(tbzrcommandw)
415
# A utility to see python output from both C++ and Python based shell
417
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
418
console_targets.append(tracer)
420
# The C++ implemented shell extensions.
421
dist_dir = os.path.join(tbzr_root, "shellext", "build")
422
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
423
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
426
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
427
# PyQt4 itself still escapes the plugin detection code for some reason...
428
includes.append('PyQt4.QtCore')
429
includes.append('PyQt4.QtGui')
430
includes.append('PyQt4.QtTest')
431
includes.append('sip') # extension module required for Qt.
432
packages.append('pygments') # colorizer for qbzr
433
packages.append('docutils') # html formatting
434
includes.append('win32event') # for qsubprocess stuff
435
# the qt binaries might not be on PATH...
436
# They seem to install to a place like C:\Python25\PyQt4\*
437
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
438
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
439
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
440
if os.path.isdir(pyqt_bin_dir):
441
path = os.environ.get("PATH", "")
442
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
443
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
444
# also add all imageformat plugins to distribution
445
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
446
base_dirs_to_check = []
447
if os.path.isdir(pyqt_dir):
448
base_dirs_to_check.append(pyqt_dir)
454
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
455
if pyqt4_base_dir != pyqt_dir:
456
base_dirs_to_check.append(pyqt4_base_dir)
457
if not base_dirs_to_check:
458
log.warn("Can't find PyQt4 installation -> not including imageformat"
462
for base_dir in base_dirs_to_check:
463
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
464
if os.path.isdir(plug_dir):
465
for fname in os.listdir(plug_dir):
466
# Include plugin dlls, but not debugging dlls
467
fullpath = os.path.join(plug_dir, fname)
468
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
469
files.append(fullpath)
471
data_files.append(('imageformats', files))
473
log.warn('PyQt4 was found, but we could not find any imageformat'
474
' plugins. Are you sure your configuration is correct?')
477
def get_svn_py2exe_info(includes, excludes, packages):
478
packages.append('subvertpy')
479
packages.append('sqlite3')
482
def get_git_py2exe_info(includes, excludes, packages):
483
packages.append('dulwich')
486
def get_fastimport_py2exe_info(includes, excludes, packages):
487
# This is the python-fastimport package, not to be confused with the
488
# brz-fastimport plugin.
489
packages.append('fastimport')
492
if 'bdist_wininst' in sys.argv:
495
for root, dirs, files in os.walk('doc'):
498
if (os.path.splitext(f)[1] in ('.html', '.css', '.png', '.pdf')
499
or f == 'quick-start-summary.svg'):
500
r.append(os.path.join(root, f))
504
target = os.path.join('Doc\\Breezy', relative)
506
target = 'Doc\\Breezy'
507
docs.append((target, r))
510
# python's distutils-based win32 installer
511
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
512
'ext_modules': ext_modules,
514
'data_files': find_docs(),
515
# for building cython extensions
516
'cmdclass': command_classes,
519
ARGS.update(META_INFO)
521
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
522
ARGS.update(PKG_DATA)
526
elif 'py2exe' in sys.argv:
530
# pick real brz version
534
for i in breezy.version_info[:4]:
539
version_number.append(str(i))
540
version_str = '.'.join(version_number)
542
# An override to install_data used only by py2exe builds, which arranges
543
# to byte-compile any .py files in data_files (eg, our plugins)
544
# Necessary as we can't rely on the user having the relevant permissions
545
# to the "Program Files" directory to generate them on the fly.
546
class install_data_with_bytecompile(install_data):
548
from distutils.util import byte_compile
550
install_data.run(self)
552
py2exe = self.distribution.get_command_obj('py2exe', False)
553
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
554
# time before living with docstring stripping
556
compile_names = [f for f in self.outfiles if f.endswith('.py')]
557
# Round mtime to nearest even second so that installing on a FAT
558
# filesystem bytecode internal and script timestamps will match
559
for f in compile_names:
560
mtime = os.stat(f).st_mtime
561
remainder = mtime % 2
564
os.utime(f, (mtime, mtime))
565
byte_compile(compile_names,
567
force=self.force, prefix=self.install_dir,
568
dry_run=self.dry_run)
569
self.outfiles.extend([f + 'o' for f in compile_names])
570
# end of class install_data_with_bytecompile
572
target = py2exe.build_exe.Target(
575
icon_resources=[(0, 'brz.ico')],
576
name=META_INFO['name'],
578
description=META_INFO['description'],
579
author=META_INFO['author'],
580
copyright="(c) Canonical Ltd, 2005-2010",
581
company_name="Canonical Ltd.",
582
comments=META_INFO['description'],
584
gui_target = copy.copy(target)
585
gui_target.dest_base = "bzrw"
587
packages = BREEZY['packages']
588
packages.remove('breezy')
589
packages = [i for i in packages if not i.startswith('breezy.plugins')]
591
for i in glob.glob('breezy\\*.py'):
592
module = i[:-3].replace('\\', '.')
593
if module.endswith('__init__'):
594
module = module[:-len('__init__')]
595
includes.append(module)
597
additional_packages = set()
598
if sys.version.startswith('2.7'):
599
additional_packages.add('xml.etree')
602
warnings.warn('Unknown Python version.\n'
603
'Please check setup.py script for compatibility.')
605
# Although we currently can't enforce it, we consider it an error for
606
# py2exe to report any files are "missing". Such modules we know aren't
607
# used should be listed here.
608
excludes = """Tkinter psyco ElementPath r_hmac
609
ImaginaryModule cElementTree elementtree.ElementTree
610
Crypto.PublicKey._fastmath
612
resource validate""".split()
615
# email package from std python library use lazy import,
616
# so we need to explicitly add all package
617
additional_packages.add('email')
618
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
619
# a result, packages like 'email.Parser' show as missing. Tell py2exe
622
for oldname in getattr(email, '_LOWERNAMES', []):
623
excludes.append("email." + oldname)
624
for oldname in getattr(email, '_MIMENAMES', []):
625
excludes.append("email.MIME" + oldname)
627
# text files for help topis
628
text_topics = glob.glob('breezy/help_topics/en/*.txt')
629
topics_files = [('lib/help_topics/en', text_topics)]
633
# XXX - should we consider having the concept of an 'official' build,
634
# which hard-codes the list of plugins, gets more upset if modules are
636
plugins = None # will be a set after plugin sniffing...
637
for root, dirs, files in os.walk('breezy/plugins'):
638
if root == 'breezy/plugins':
640
# We ship plugins as normal files on the file-system - however,
641
# the build process can cause *some* of these plugin files to end
642
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
643
# library.zip, and then saw import errors related to that as the
644
# rest of the svn plugin wasn't. So we tell py2exe to leave the
645
# plugins out of the .zip file
646
excludes.extend(["breezy.plugins." + d for d in dirs])
649
# Throw away files we don't want packaged. Note that plugins may
650
# have data files with all sorts of extensions so we need to
651
# be conservative here about what we ditch.
652
ext = os.path.splitext(i)[1]
653
if ext.endswith('~') or ext in [".pyc", ".swp"]:
655
if i == '__init__.py' and root == 'breezy/plugins':
657
x.append(os.path.join(root, i))
659
target_dir = root[len('breezy/'):] # install to 'plugins/...'
660
plugins_files.append((target_dir, x))
661
# find modules for built-in plugins
662
import tools.package_mf
663
mf = tools.package_mf.CustomModuleFinder()
664
mf.run_package('breezy/plugins')
665
packs, mods = mf.get_result()
666
additional_packages.update(packs)
667
includes.extend(mods)
669
console_targets = [target,
670
'tools/win32/bzr_postinstall.py',
672
gui_targets = [gui_target]
673
data_files = topics_files + plugins_files + I18N_FILES
675
if 'qbzr' in plugins:
676
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
679
get_svn_py2exe_info(includes, excludes, packages)
682
get_git_py2exe_info(includes, excludes, packages)
684
if 'fastimport' in plugins:
685
get_fastimport_py2exe_info(includes, excludes, packages)
687
if "TBZR" in os.environ:
688
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
689
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
690
# can be downloaded from (username=guest, blank password):
691
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
692
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
693
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
694
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
695
'TORTOISE_OVERLAYS_MSI_X64'):
696
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
698
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
700
"\nPlease set %s to the location of the relevant"
701
"\nTortoiseOverlays .msi installer file."
702
" The installers can be found at"
704
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
705
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
706
gui_targets, data_files)
708
# print this warning to stderr as output is redirected, so it is seen
709
# at build time. Also to stdout so it appears in the log
710
for f in (sys.stderr, sys.stdout):
711
f.write("Skipping TBZR binaries - "
712
"please set TBZR to a directory to enable\n")
714
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
716
dll_excludes.extend(["MSWSOCK.dll",
721
options_list = {"py2exe": {"packages": packages + list(additional_packages),
722
"includes": includes,
723
"excludes": excludes,
724
"dll_excludes": dll_excludes,
725
"dist_dir": "win32_bzr.exe",
727
"custom_boot_script":
728
"tools/win32/py2exe_boot_common.py",
732
# We want the libaray.zip to have optimize = 2, but the exe to have
733
# optimize = 1, so that .py files that get compilied at run time
734
# (e.g. user installed plugins) dont have their doc strings removed.
735
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
736
def build_executable(self, *args, **kwargs):
738
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
741
if __name__ == '__main__':
742
command_classes['install_data'] = install_data_with_bytecompile
743
command_classes['py2exe'] = py2exe_no_oo_exe
744
setup(options=options_list,
745
console=console_targets,
747
zipfile='lib/library.zip',
748
data_files=data_files,
749
cmdclass=command_classes,
753
# ad-hoc for easy_install
755
if 'bdist_egg' not in sys.argv:
756
# generate and install brz.1 only with plain install, not the
758
DATA_FILES = [('man/man1', ['brz.1', 'breezy/git/git-remote-bzr.1'])]
760
DATA_FILES = DATA_FILES + I18N_FILES
762
ARGS = {'scripts': ['brz',
763
# TODO(jelmer): Only install the git scripts if
765
'breezy/git/git-remote-bzr',
766
'breezy/git/bzr-receive-pack',
767
'breezy/git/bzr-upload-pack'],
768
'data_files': DATA_FILES,
769
'cmdclass': command_classes,
770
'ext_modules': ext_modules,
773
ARGS.update(META_INFO)
775
ARGS.update(PKG_DATA)
777
if __name__ == '__main__':
56
author_email='mbp@sourcefrog.net',
57
url='http://www.bazaar-ng.org/',
58
description='Friendly distributed version control system',
66
'bzrlib.util.elementtree',
67
'bzrlib.util.effbot.org',