1
1
#! /usr/bin/env python
3
"""Installation script for bzr.
5
'./setup.py install', or
6
'./setup.py --help' for more options
15
if sys.version_info < (2, 6):
16
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.6+\n")
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
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': bzrlib.__version__,
40
'author': 'Canonical Ltd',
41
'author_email': 'bazaar@lists.canonical.com',
42
'url': 'http://bazaar.canonical.com/',
43
'description': 'Friendly distributed version control system',
44
'license': 'GNU GPL v2',
45
'download_url': 'https://launchpad.net/bzr/+download',
46
'long_description': get_long_description(),
48
'Development Status :: 6 - Mature',
49
'Environment :: Console',
50
'Intended Audience :: Developers',
51
'Intended Audience :: System Administrators',
52
'License :: OSI Approved :: GNU General Public License (GPL)',
53
'Operating System :: Microsoft :: Windows',
54
'Operating System :: OS Independent',
55
'Operating System :: POSIX',
56
'Programming Language :: Python',
57
'Programming Language :: C',
58
'Topic :: Software Development :: Version Control',
62
# The list of packages is automatically generated later. Add other things
63
# that are part of BZRLIB here.
66
PKG_DATA = {# install files from selftest suite
67
'package_data': {'bzrlib': ['doc/api/*.txt',
68
'tests/test_patches_data/*',
69
'help_topics/en/*.txt',
70
'tests/ssl_certs/ca.crt',
71
'tests/ssl_certs/server_without_pass.key',
72
'tests/ssl_certs/server_with_pass.key',
73
'tests/ssl_certs/server.crt',
77
for filepath in glob.glob("bzrlib/locale/*/LC_MESSAGES/*.mo"):
78
langfile = filepath[len("bzrlib/locale/"):]
79
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
80
I18N_FILES.append((targetpath, [filepath]))
82
def get_bzrlib_packages():
83
"""Recurse through the bzrlib directory, and extract the package names"""
86
base_path = os.path.dirname(os.path.abspath(bzrlib.__file__))
87
for root, dirs, files in os.walk(base_path):
88
if '__init__.py' in files:
89
assert root.startswith(base_path)
90
# Get just the path below bzrlib
91
package_path = root[len(base_path):]
92
# Remove leading and trailing slashes
93
package_path = package_path.strip('\\/')
95
package_name = 'bzrlib'
97
package_name = ('bzrlib.' +
98
package_path.replace('/', '.').replace('\\', '.'))
99
packages.append(package_name)
100
return sorted(packages)
103
BZRLIB['packages'] = get_bzrlib_packages()
106
from distutils import log
33
if hasattr(os, "unsetenv"):
107
37
from distutils.core import setup
108
38
from distutils.command.install_scripts import install_scripts
109
from distutils.command.install_data import install_data
110
39
from distutils.command.build import build
112
41
###############################
118
47
Create bzr.bat for win32.
121
53
install_scripts.run(self) # standard action
123
55
if sys.platform == "win32":
125
scripts_dir = os.path.join(sys.prefix, 'Scripts')
126
script_path = self._quoted_path(os.path.join(scripts_dir,
128
python_exe = self._quoted_path(sys.executable)
129
args = self._win_batch_args()
130
batch_str = "@%s %s %s" % (python_exe, script_path, args)
131
batch_path = os.path.join(self.install_dir, "bzr.bat")
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
61
f = file(batch_path, "w")
133
62
f.write(batch_str)
135
print("Created: %s" % batch_path)
137
e = sys.exc_info()[1]
138
print("ERROR: Unable to create %s: %s" % (batch_path, e))
140
def _quoted_path(self, path):
142
return '"' + path + '"'
146
def _win_batch_args(self):
147
from bzrlib.win32utils import winver
148
if winver == 'Windows NT':
151
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
152
#/class my_install_scripts
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
155
69
class bzr_build(build):
156
70
"""Customized build distutils action.
160
sub_commands = build.sub_commands + [
161
('build_mo', lambda _: True),
167
from tools import generate_docs
168
77
generate_docs.main(argv=["bzr", "man"])
171
79
########################
173
81
########################
175
from tools.build_mo import build_mo
177
command_classes = {'install_scripts': my_install_scripts,
179
'build_mo': build_mo,
181
from distutils import log
182
from distutils.errors import CCompilerError, DistutilsPlatformError
183
from distutils.extension import Extension
187
from Cython.Distutils import build_ext
188
from Cython.Compiler.Version import version as pyrex_version
190
print("No Cython, trying Pyrex...")
191
from Pyrex.Distutils import build_ext
192
from Pyrex.Compiler.Version import version as pyrex_version
195
# try to build the extension from the prior generated source.
197
print("The python package 'Pyrex' is not available."
198
" If the .c files are available,")
199
print("they will be built,"
200
" but modifying the .pyx files will not rebuild them.")
202
from distutils.command.build_ext import build_ext
206
_version = re.match("^[0-9.]+", pyrex_version).group(0)
207
pyrex_version_info = tuple(map(int, _version.split('.')))
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 Pyrex available
252
command_classes['build_ext'] = build_ext_if_possible
253
unavailable_files = []
256
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
257
"""Add a pyrex module to build.
259
This will use Pyrex 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
pyrex_name = path + '.pyx'
273
if sys.platform == 'win32':
274
# pyrex 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 = [pyrex_name]
281
if not os.path.isfile(c_name):
282
unavailable_files.append(c_name)
286
source.extend(extra_source)
287
ext_modules.append(Extension(module_name, source,
288
define_macros=define_macros, libraries=libraries))
291
add_pyrex_extension('bzrlib._annotator_pyx')
292
add_pyrex_extension('bzrlib._bencode_pyx')
293
add_pyrex_extension('bzrlib._chunks_to_lines_pyx')
294
add_pyrex_extension('bzrlib._groupcompress_pyx',
295
extra_source=['bzrlib/diff-delta.c'])
296
add_pyrex_extension('bzrlib._knit_load_data_pyx')
297
add_pyrex_extension('bzrlib._known_graph_pyx')
298
add_pyrex_extension('bzrlib._rio_pyx')
299
if sys.platform == 'win32':
300
add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
301
libraries=['Ws2_32'])
302
add_pyrex_extension('bzrlib._walkdirs_win32')
304
if have_pyrex and pyrex_version_info[:3] == (0,9,4):
305
# Pyrex 0.9.4.1 fails to compile this extension correctly
306
# The code it generates re-uses a "local" pointer and
307
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
308
# which is NULL safe with PY_DECREF which is not.)
309
# <https://bugs.launchpad.net/bzr/+bug/449372>
310
# <https://bugs.launchpad.net/bzr/+bug/276868>
311
print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
312
print('your version of pyrex "%s". Please upgrade your pyrex'
314
print('install. For now, the non-compiled (python) version will')
315
print('be used instead.')
317
add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
318
add_pyrex_extension('bzrlib._readdir_pyx')
319
add_pyrex_extension('bzrlib._chk_map_pyx')
320
ext_modules.append(Extension('bzrlib._patiencediff_c',
321
['bzrlib/_patiencediff_c.c']))
322
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
324
print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
326
print('and static_tuple extensions.')
327
print('Please upgrade to at least Pyrex 0.9.6.3')
329
# TODO: Should this be a fatal error?
331
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
333
add_pyrex_extension('bzrlib._simple_set_pyx')
334
ext_modules.append(Extension('bzrlib._static_tuple_c',
335
['bzrlib/_static_tuple_c.c']))
336
add_pyrex_extension('bzrlib._btree_serializer_pyx')
339
if unavailable_files:
340
print('C extension(s) not found:')
341
print(' %s' % ('\n '.join(unavailable_files),))
342
print('The python versions will be used instead.')
346
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
347
gui_targets, data_files):
348
packages.append('tbzrcommands')
350
# ModuleFinder can't handle runtime changes to __path__, but
351
# win32com uses them. Hook this in so win32com.shell is found.
354
import cPickle as pickle
355
for p in win32com.__path__[1:]:
356
modulefinder.AddPackagePath("win32com", p)
357
for extra in ["win32com.shell"]:
359
m = sys.modules[extra]
360
for p in m.__path__[1:]:
361
modulefinder.AddPackagePath(extra, p)
363
# TBZR points to the TBZR directory
364
tbzr_root = os.environ["TBZR"]
366
# Ensure tbzrlib itself is on sys.path
367
sys.path.append(tbzr_root)
369
packages.append("tbzrlib")
371
# collect up our icons.
373
ico_root = os.path.join(tbzr_root, 'tbzrlib', 'resources')
374
icos = [] # list of (path_root, relative_ico_path)
375
# First always bzr's icon and its in the root of the bzr tree.
376
icos.append(('', 'bzr.ico'))
377
for root, dirs, files in os.walk(ico_root):
378
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
379
for f in files if f.endswith('.ico')])
380
# allocate an icon ID for each file and the full path to the ico
381
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
382
for rid, (ico_dir, ico_name) in enumerate(icos)]
383
# create a string resource with the mapping. Might as well save the
384
# runtime some effort and write a pickle.
385
# Runtime expects unicode objects with forward-slash seps.
386
fse = sys.getfilesystemencoding()
387
map_items = [(f.replace('\\', '/').decode(fse), rid)
388
for rid, (_, f) in enumerate(icos)]
389
ico_map = dict(map_items)
390
# Create a new resource type of 'ICON_MAP', and use ID=1
391
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
393
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
394
win32ui crawler.Crawler""".split())
396
# tbzrcache executables - a "console" version for debugging and a
397
# GUI version that is generally used.
399
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
400
icon_resources = icon_resources,
401
other_resources = other_resources,
403
console_targets.append(tbzrcache)
405
# Make a windows version which is the same except for the base name.
406
tbzrcachew = tbzrcache.copy()
407
tbzrcachew["dest_base"]="tbzrcachew"
408
gui_targets.append(tbzrcachew)
410
# ditto for the tbzrcommand tool
412
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
413
icon_resources = icon_resources,
414
other_resources = other_resources,
416
console_targets.append(tbzrcommand)
417
tbzrcommandw = tbzrcommand.copy()
418
tbzrcommandw["dest_base"]="tbzrcommandw"
419
gui_targets.append(tbzrcommandw)
421
# A utility to see python output from both C++ and Python based shell
423
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
424
console_targets.append(tracer)
426
# The C++ implemented shell extensions.
427
dist_dir = os.path.join(tbzr_root, "shellext", "build")
428
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
429
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
432
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
433
# PyQt4 itself still escapes the plugin detection code for some reason...
434
includes.append('PyQt4.QtCore')
435
includes.append('PyQt4.QtGui')
436
includes.append('sip') # extension module required for Qt.
437
packages.append('pygments') # colorizer for qbzr
438
packages.append('docutils') # html formatting
439
includes.append('win32event') # for qsubprocess stuff
440
# the qt binaries might not be on PATH...
441
# They seem to install to a place like C:\Python25\PyQt4\*
442
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
443
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
444
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
445
if os.path.isdir(pyqt_bin_dir):
446
path = os.environ.get("PATH", "")
447
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
448
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
449
# also add all imageformat plugins to distribution
450
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
451
base_dirs_to_check = []
452
if os.path.isdir(pyqt_dir):
453
base_dirs_to_check.append(pyqt_dir)
459
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
460
if pyqt4_base_dir != pyqt_dir:
461
base_dirs_to_check.append(pyqt4_base_dir)
462
if not base_dirs_to_check:
463
log.warn("Can't find PyQt4 installation -> not including imageformat"
467
for base_dir in base_dirs_to_check:
468
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
469
if os.path.isdir(plug_dir):
470
for fname in os.listdir(plug_dir):
471
# Include plugin dlls, but not debugging dlls
472
fullpath = os.path.join(plug_dir, fname)
473
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
474
files.append(fullpath)
476
data_files.append(('imageformats', files))
478
log.warn('PyQt4 was found, but we could not find any imageformat'
479
' plugins. Are you sure your configuration is correct?')
482
def get_svn_py2exe_info(includes, excludes, packages):
483
packages.append('subvertpy')
484
packages.append('sqlite3')
487
def get_fastimport_py2exe_info(includes, excludes, packages):
488
# This is the python-fastimport package, not to be confused with the
489
# bzr-fastimport plugin.
490
packages.append('fastimport')
493
if 'bdist_wininst' in sys.argv:
496
for root, dirs, files in os.walk('doc'):
499
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
500
or f == 'quick-start-summary.svg'):
501
r.append(os.path.join(root, f))
505
target = os.path.join('Doc\\Bazaar', relative)
507
target = 'Doc\\Bazaar'
508
docs.append((target, r))
511
# python's distutils-based win32 installer
512
ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
513
'ext_modules': ext_modules,
515
'data_files': find_docs(),
516
# for building pyrex extensions
517
'cmdclass': command_classes,
520
ARGS.update(META_INFO)
522
PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
523
ARGS.update(PKG_DATA)
527
elif 'py2exe' in sys.argv:
531
# pick real bzr version
535
for i in bzrlib.version_info[:4]:
540
version_number.append(str(i))
541
version_str = '.'.join(version_number)
543
# An override to install_data used only by py2exe builds, which arranges
544
# to byte-compile any .py files in data_files (eg, our plugins)
545
# Necessary as we can't rely on the user having the relevant permissions
546
# to the "Program Files" directory to generate them on the fly.
547
class install_data_with_bytecompile(install_data):
549
from distutils.util import byte_compile
551
install_data.run(self)
553
py2exe = self.distribution.get_command_obj('py2exe', False)
554
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
555
# time before living with docstring stripping
557
compile_names = [f for f in self.outfiles if f.endswith('.py')]
558
# Round mtime to nearest even second so that installing on a FAT
559
# filesystem bytecode internal and script timestamps will match
560
for f in compile_names:
561
mtime = os.stat(f).st_mtime
562
remainder = mtime % 2
565
os.utime(f, (mtime, mtime))
566
byte_compile(compile_names,
568
force=self.force, prefix=self.install_dir,
569
dry_run=self.dry_run)
570
self.outfiles.extend([f + 'o' for f in compile_names])
571
# end of class install_data_with_bytecompile
573
target = py2exe.build_exe.Target(script = "bzr",
575
icon_resources = [(0,'bzr.ico')],
576
name = META_INFO['name'],
577
version = version_str,
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 = BZRLIB['packages']
588
packages.remove('bzrlib')
589
packages = [i for i in packages if not i.startswith('bzrlib.plugins')]
591
for i in glob.glob('bzrlib\\*.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.4'):
599
# adding elementtree package
600
additional_packages.add('elementtree')
601
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
602
additional_packages.add('xml.etree')
605
warnings.warn('Unknown Python version.\n'
606
'Please check setup.py script for compatibility.')
608
# Although we currently can't enforce it, we consider it an error for
609
# py2exe to report any files are "missing". Such modules we know aren't
610
# used should be listed here.
611
excludes = """Tkinter psyco ElementPath r_hmac
612
ImaginaryModule cElementTree elementtree.ElementTree
613
Crypto.PublicKey._fastmath
614
medusa medusa.filesys medusa.ftp_server
616
resource validate""".split()
619
# email package from std python library use lazy import,
620
# so we need to explicitly add all package
621
additional_packages.add('email')
622
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
623
# a result, packages like 'email.Parser' show as missing. Tell py2exe
626
for oldname in getattr(email, '_LOWERNAMES', []):
627
excludes.append("email." + oldname)
628
for oldname in getattr(email, '_MIMENAMES', []):
629
excludes.append("email.MIME" + oldname)
631
# text files for help topis
632
text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
633
topics_files = [('lib/help_topics/en', text_topics)]
637
# XXX - should we consider having the concept of an 'official' build,
638
# which hard-codes the list of plugins, gets more upset if modules are
640
plugins = None # will be a set after plugin sniffing...
641
for root, dirs, files in os.walk('bzrlib/plugins'):
642
if root == 'bzrlib/plugins':
644
# We ship plugins as normal files on the file-system - however,
645
# the build process can cause *some* of these plugin files to end
646
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
647
# library.zip, and then saw import errors related to that as the
648
# rest of the svn plugin wasn't. So we tell py2exe to leave the
649
# plugins out of the .zip file
650
excludes.extend(["bzrlib.plugins." + d for d in dirs])
653
# Throw away files we don't want packaged. Note that plugins may
654
# have data files with all sorts of extensions so we need to
655
# be conservative here about what we ditch.
656
ext = os.path.splitext(i)[1]
657
if ext.endswith('~') or ext in [".pyc", ".swp"]:
659
if i == '__init__.py' and root == 'bzrlib/plugins':
661
x.append(os.path.join(root, i))
663
target_dir = root[len('bzrlib/'):] # install to 'plugins/...'
664
plugins_files.append((target_dir, x))
665
# find modules for built-in plugins
666
import tools.package_mf
667
mf = tools.package_mf.CustomModuleFinder()
668
mf.run_package('bzrlib/plugins')
669
packs, mods = mf.get_result()
670
additional_packages.update(packs)
671
includes.extend(mods)
673
console_targets = [target,
674
'tools/win32/bzr_postinstall.py',
676
gui_targets = [gui_target]
677
data_files = topics_files + plugins_files + I18N_FILES
679
if 'qbzr' in plugins:
680
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
683
get_svn_py2exe_info(includes, excludes, packages)
685
if 'fastimport' in plugins:
686
get_fastimport_py2exe_info(includes, excludes, packages)
688
if "TBZR" in os.environ:
689
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
690
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
691
# can be downloaded from (username=guest, blank password):
692
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
693
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
694
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
695
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
696
'TORTOISE_OVERLAYS_MSI_X64'):
697
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
699
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
701
"\nPlease set %s to the location of the relevant"
702
"\nTortoiseOverlays .msi installer file."
703
" The installers can be found at"
705
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
706
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
707
gui_targets, data_files)
709
# print this warning to stderr as output is redirected, so it is seen
710
# at build time. Also to stdout so it appears in the log
711
for f in (sys.stderr, sys.stdout):
712
f.write("Skipping TBZR binaries - "
713
"please set TBZR to a directory to enable\n")
715
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
717
dll_excludes.extend(["MSWSOCK.dll",
722
options_list = {"py2exe": {"packages": packages + list(additional_packages),
723
"includes": includes,
724
"excludes": excludes,
725
"dll_excludes": dll_excludes,
726
"dist_dir": "win32_bzr.exe",
728
"custom_boot_script":
729
"tools/win32/py2exe_boot_common.py",
733
# We want the libaray.zip to have optimize = 2, but the exe to have
734
# optimize = 1, so that .py files that get compilied at run time
735
# (e.g. user installed plugins) dont have their doc strings removed.
736
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
737
def build_executable(self, *args, **kwargs):
739
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
742
if __name__ == '__main__':
743
command_classes['install_data'] = install_data_with_bytecompile
744
command_classes['py2exe'] = py2exe_no_oo_exe
745
setup(options=options_list,
746
console=console_targets,
748
zipfile='lib/library.zip',
749
data_files=data_files,
750
cmdclass=command_classes,
754
# ad-hoc for easy_install
756
if not 'bdist_egg' in sys.argv:
757
# generate and install bzr.1 only with plain install, not the
759
DATA_FILES = [('man/man1', ['bzr.1'])]
761
DATA_FILES = DATA_FILES + I18N_FILES
763
ARGS = {'scripts': ['bzr'],
764
'data_files': DATA_FILES,
765
'cmdclass': command_classes,
766
'ext_modules': ext_modules,
769
ARGS.update(META_INFO)
771
ARGS.update(PKG_DATA)
773
if __name__ == '__main__':
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',
101
'bzrlib.transport.http',
104
'bzrlib.util.elementtree',
105
'bzrlib.util.effbot.org',
106
'bzrlib.util.configobj',
109
cmdclass={'install_scripts': my_install_scripts, 'build': bzr_build},
110
data_files=[('man/man1', ['bzr.1'])],
111
# todo: install the txt files from bzrlib.doc.api.