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
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")
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
7
107
from distutils.core import setup
9
# more sophisticated setup script, based on pychecker setup.py
11
from distutils.command.build_scripts import build_scripts
108
from distutils.command.install_scripts import install_scripts
109
from distutils.command.install_data import install_data
110
from distutils.command.build import build
14
112
###############################
15
113
# Overridden distutils actions
16
114
###############################
18
class my_build_scripts(build_scripts):
19
"""Customized build_scripts distutils action.
116
class my_install_scripts(install_scripts):
117
""" Customized install_scripts distutils action.
21
118
Create bzr.bat for win32.
121
install_scripts.run(self) # standard action
25
123
if sys.platform == "win32":
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)
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")
132
f = file(batch_path, "w")
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
155
class bzr_build(build):
156
"""Customized build distutils action.
160
sub_commands = build.sub_commands + [
161
('build_mo', lambda _: True),
167
from tools import generate_docs
168
generate_docs.main(argv=["bzr", "man"])
49
171
########################
51
173
########################
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',
175
from bzrlib.bzr_distutils 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
205
pyrex_version_info = tuple(map(int, pyrex_version.rstrip("+").split('.')))
208
class build_ext_if_possible(build_ext):
210
user_options = build_ext.user_options + [
211
('allow-python-fallback', None,
212
"When an extension cannot be built, allow falling"
213
" back to the pure-python implementation.")
216
def initialize_options(self):
217
build_ext.initialize_options(self)
218
self.allow_python_fallback = False
223
except DistutilsPlatformError:
224
e = sys.exc_info()[1]
225
if not self.allow_python_fallback:
226
log.warn('\n Cannot build extensions.\n'
227
' Use "build_ext --allow-python-fallback" to use'
228
' slower python implementations instead.\n')
231
log.warn('\n Extensions cannot be built.\n'
232
' Using the slower Python implementations instead.\n')
234
def build_extension(self, ext):
236
build_ext.build_extension(self, ext)
237
except CCompilerError:
238
if not self.allow_python_fallback:
239
log.warn('\n Cannot build extension "%s".\n'
240
' Use "build_ext --allow-python-fallback" to use'
241
' slower python implementations instead.\n'
244
log.warn('\n Building of "%s" extension failed.\n'
245
' Using the slower Python implementation instead.'
249
# Override the build_ext if we have Pyrex available
250
command_classes['build_ext'] = build_ext_if_possible
251
unavailable_files = []
254
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
255
"""Add a pyrex module to build.
257
This will use Pyrex to auto-generate the .c file if it is available.
258
Otherwise it will fall back on the .c file. If the .c file is not
259
available, it will warn, and not add anything.
261
You can pass any extra options to Extension through kwargs. One example is
264
:param module_name: The python path to the module. This will be used to
265
determine the .pyx and .c files to use.
267
path = module_name.replace('.', '/')
268
pyrex_name = path + '.pyx'
271
if sys.platform == 'win32':
272
# pyrex uses the macro WIN32 to detect the platform, even though it
273
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
274
# give it the right value.
275
define_macros.append(('WIN32', None))
277
source = [pyrex_name]
279
if not os.path.isfile(c_name):
280
unavailable_files.append(c_name)
284
source.extend(extra_source)
285
ext_modules.append(Extension(module_name, source,
286
define_macros=define_macros, libraries=libraries))
289
add_pyrex_extension('bzrlib._annotator_pyx')
290
add_pyrex_extension('bzrlib._bencode_pyx')
291
add_pyrex_extension('bzrlib._chunks_to_lines_pyx')
292
add_pyrex_extension('bzrlib._groupcompress_pyx',
293
extra_source=['bzrlib/diff-delta.c'])
294
add_pyrex_extension('bzrlib._knit_load_data_pyx')
295
add_pyrex_extension('bzrlib._known_graph_pyx')
296
add_pyrex_extension('bzrlib._rio_pyx')
297
if sys.platform == 'win32':
298
add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
299
libraries=['Ws2_32'])
300
add_pyrex_extension('bzrlib._walkdirs_win32')
302
if have_pyrex and pyrex_version_info[:3] == (0,9,4):
303
# Pyrex 0.9.4.1 fails to compile this extension correctly
304
# The code it generates re-uses a "local" pointer and
305
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
306
# which is NULL safe with PY_DECREF which is not.)
307
# <https://bugs.launchpad.net/bzr/+bug/449372>
308
# <https://bugs.launchpad.net/bzr/+bug/276868>
309
print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
310
print('your version of pyrex "%s". Please upgrade your pyrex'
312
print('install. For now, the non-compiled (python) version will')
313
print('be used instead.')
315
add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
316
add_pyrex_extension('bzrlib._readdir_pyx')
317
add_pyrex_extension('bzrlib._chk_map_pyx')
318
ext_modules.append(Extension('bzrlib._patiencediff_c',
319
['bzrlib/_patiencediff_c.c']))
320
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
322
print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
324
print('and static_tuple extensions.')
325
print('Please upgrade to at least Pyrex 0.9.6.3')
327
# TODO: Should this be a fatal error?
329
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
331
add_pyrex_extension('bzrlib._simple_set_pyx')
332
ext_modules.append(Extension('bzrlib._static_tuple_c',
333
['bzrlib/_static_tuple_c.c']))
334
add_pyrex_extension('bzrlib._btree_serializer_pyx')
337
if unavailable_files:
338
print('C extension(s) not found:')
339
print(' %s' % ('\n '.join(unavailable_files),))
340
print('The python versions will be used instead.')
344
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
345
gui_targets, data_files):
346
packages.append('tbzrcommands')
348
# ModuleFinder can't handle runtime changes to __path__, but
349
# win32com uses them. Hook this in so win32com.shell is found.
352
import cPickle as pickle
353
for p in win32com.__path__[1:]:
354
modulefinder.AddPackagePath("win32com", p)
355
for extra in ["win32com.shell"]:
357
m = sys.modules[extra]
358
for p in m.__path__[1:]:
359
modulefinder.AddPackagePath(extra, p)
361
# TBZR points to the TBZR directory
362
tbzr_root = os.environ["TBZR"]
364
# Ensure tbzrlib itself is on sys.path
365
sys.path.append(tbzr_root)
367
packages.append("tbzrlib")
369
# collect up our icons.
371
ico_root = os.path.join(tbzr_root, 'tbzrlib', 'resources')
372
icos = [] # list of (path_root, relative_ico_path)
373
# First always bzr's icon and its in the root of the bzr tree.
374
icos.append(('', 'bzr.ico'))
375
for root, dirs, files in os.walk(ico_root):
376
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
377
for f in files if f.endswith('.ico')])
378
# allocate an icon ID for each file and the full path to the ico
379
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
380
for rid, (ico_dir, ico_name) in enumerate(icos)]
381
# create a string resource with the mapping. Might as well save the
382
# runtime some effort and write a pickle.
383
# Runtime expects unicode objects with forward-slash seps.
384
fse = sys.getfilesystemencoding()
385
map_items = [(f.replace('\\', '/').decode(fse), rid)
386
for rid, (_, f) in enumerate(icos)]
387
ico_map = dict(map_items)
388
# Create a new resource type of 'ICON_MAP', and use ID=1
389
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
391
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
392
win32ui crawler.Crawler""".split())
394
# tbzrcache executables - a "console" version for debugging and a
395
# GUI version that is generally used.
397
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
398
icon_resources = icon_resources,
399
other_resources = other_resources,
401
console_targets.append(tbzrcache)
403
# Make a windows version which is the same except for the base name.
404
tbzrcachew = tbzrcache.copy()
405
tbzrcachew["dest_base"]="tbzrcachew"
406
gui_targets.append(tbzrcachew)
408
# ditto for the tbzrcommand tool
410
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
411
icon_resources = icon_resources,
412
other_resources = other_resources,
414
console_targets.append(tbzrcommand)
415
tbzrcommandw = tbzrcommand.copy()
416
tbzrcommandw["dest_base"]="tbzrcommandw"
417
gui_targets.append(tbzrcommandw)
419
# A utility to see python output from both C++ and Python based shell
421
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
422
console_targets.append(tracer)
424
# The C++ implemented shell extensions.
425
dist_dir = os.path.join(tbzr_root, "shellext", "build")
426
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
427
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
430
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
431
# PyQt4 itself still escapes the plugin detection code for some reason...
432
includes.append('PyQt4.QtCore')
433
includes.append('PyQt4.QtGui')
434
includes.append('sip') # extension module required for Qt.
435
packages.append('pygments') # colorizer for qbzr
436
packages.append('docutils') # html formatting
437
includes.append('win32event') # for qsubprocess stuff
438
# the qt binaries might not be on PATH...
439
# They seem to install to a place like C:\Python25\PyQt4\*
440
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
441
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
442
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
443
if os.path.isdir(pyqt_bin_dir):
444
path = os.environ.get("PATH", "")
445
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
446
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
447
# also add all imageformat plugins to distribution
448
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
449
base_dirs_to_check = []
450
if os.path.isdir(pyqt_dir):
451
base_dirs_to_check.append(pyqt_dir)
457
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
458
if pyqt4_base_dir != pyqt_dir:
459
base_dirs_to_check.append(pyqt4_base_dir)
460
if not base_dirs_to_check:
461
log.warn("Can't find PyQt4 installation -> not including imageformat"
465
for base_dir in base_dirs_to_check:
466
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
467
if os.path.isdir(plug_dir):
468
for fname in os.listdir(plug_dir):
469
# Include plugin dlls, but not debugging dlls
470
fullpath = os.path.join(plug_dir, fname)
471
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
472
files.append(fullpath)
474
data_files.append(('imageformats', files))
476
log.warn('PyQt4 was found, but we could not find any imageformat'
477
' plugins. Are you sure your configuration is correct?')
480
def get_svn_py2exe_info(includes, excludes, packages):
481
packages.append('subvertpy')
482
packages.append('sqlite3')
485
def get_fastimport_py2exe_info(includes, excludes, packages):
486
# This is the python-fastimport package, not to be confused with the
487
# bzr-fastimport plugin.
488
packages.append('fastimport')
491
if 'bdist_wininst' in sys.argv:
494
for root, dirs, files in os.walk('doc'):
497
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
498
or f == 'quick-start-summary.svg'):
499
r.append(os.path.join(root, f))
503
target = os.path.join('Doc\\Bazaar', relative)
505
target = 'Doc\\Bazaar'
506
docs.append((target, r))
509
# python's distutils-based win32 installer
510
ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
511
'ext_modules': ext_modules,
513
'data_files': find_docs(),
514
# for building pyrex extensions
515
'cmdclass': command_classes,
518
ARGS.update(META_INFO)
520
PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
521
ARGS.update(PKG_DATA)
525
elif 'py2exe' in sys.argv:
529
# pick real bzr version
533
for i in bzrlib.version_info[:4]:
538
version_number.append(str(i))
539
version_str = '.'.join(version_number)
541
# An override to install_data used only by py2exe builds, which arranges
542
# to byte-compile any .py files in data_files (eg, our plugins)
543
# Necessary as we can't rely on the user having the relevant permissions
544
# to the "Program Files" directory to generate them on the fly.
545
class install_data_with_bytecompile(install_data):
547
from distutils.util import byte_compile
549
install_data.run(self)
551
py2exe = self.distribution.get_command_obj('py2exe', False)
552
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
553
# time before living with docstring stripping
555
compile_names = [f for f in self.outfiles if f.endswith('.py')]
556
# Round mtime to nearest even second so that installing on a FAT
557
# filesystem bytecode internal and script timestamps will match
558
for f in compile_names:
559
mtime = os.stat(f).st_mtime
560
remainder = mtime % 2
563
os.utime(f, (mtime, mtime))
564
byte_compile(compile_names,
566
force=self.force, prefix=self.install_dir,
567
dry_run=self.dry_run)
568
self.outfiles.extend([f + 'o' for f in compile_names])
569
# end of class install_data_with_bytecompile
571
target = py2exe.build_exe.Target(script = "bzr",
573
icon_resources = [(0,'bzr.ico')],
574
name = META_INFO['name'],
575
version = version_str,
576
description = META_INFO['description'],
577
author = META_INFO['author'],
578
copyright = "(c) Canonical Ltd, 2005-2010",
579
company_name = "Canonical Ltd.",
580
comments = META_INFO['description'],
582
gui_target = copy.copy(target)
583
gui_target.dest_base = "bzrw"
585
packages = BZRLIB['packages']
586
packages.remove('bzrlib')
587
packages = [i for i in packages if not i.startswith('bzrlib.plugins')]
589
for i in glob.glob('bzrlib\\*.py'):
590
module = i[:-3].replace('\\', '.')
591
if module.endswith('__init__'):
592
module = module[:-len('__init__')]
593
includes.append(module)
595
additional_packages = set()
596
if sys.version.startswith('2.4'):
597
# adding elementtree package
598
additional_packages.add('elementtree')
599
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
600
additional_packages.add('xml.etree')
603
warnings.warn('Unknown Python version.\n'
604
'Please check setup.py script for compatibility.')
606
# Although we currently can't enforce it, we consider it an error for
607
# py2exe to report any files are "missing". Such modules we know aren't
608
# used should be listed here.
609
excludes = """Tkinter psyco ElementPath r_hmac
610
ImaginaryModule cElementTree elementtree.ElementTree
611
Crypto.PublicKey._fastmath
612
medusa medusa.filesys medusa.ftp_server
614
resource validate""".split()
617
# email package from std python library use lazy import,
618
# so we need to explicitly add all package
619
additional_packages.add('email')
620
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
621
# a result, packages like 'email.Parser' show as missing. Tell py2exe
624
for oldname in getattr(email, '_LOWERNAMES', []):
625
excludes.append("email." + oldname)
626
for oldname in getattr(email, '_MIMENAMES', []):
627
excludes.append("email.MIME" + oldname)
629
# text files for help topis
630
text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
631
topics_files = [('lib/help_topics/en', text_topics)]
635
# XXX - should we consider having the concept of an 'official' build,
636
# which hard-codes the list of plugins, gets more upset if modules are
638
plugins = None # will be a set after plugin sniffing...
639
for root, dirs, files in os.walk('bzrlib/plugins'):
640
if root == 'bzrlib/plugins':
642
# We ship plugins as normal files on the file-system - however,
643
# the build process can cause *some* of these plugin files to end
644
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
645
# library.zip, and then saw import errors related to that as the
646
# rest of the svn plugin wasn't. So we tell py2exe to leave the
647
# plugins out of the .zip file
648
excludes.extend(["bzrlib.plugins." + d for d in dirs])
651
# Throw away files we don't want packaged. Note that plugins may
652
# have data files with all sorts of extensions so we need to
653
# be conservative here about what we ditch.
654
ext = os.path.splitext(i)[1]
655
if ext.endswith('~') or ext in [".pyc", ".swp"]:
657
if i == '__init__.py' and root == 'bzrlib/plugins':
659
x.append(os.path.join(root, i))
661
target_dir = root[len('bzrlib/'):] # install to 'plugins/...'
662
plugins_files.append((target_dir, x))
663
# find modules for built-in plugins
664
import tools.package_mf
665
mf = tools.package_mf.CustomModuleFinder()
666
mf.run_package('bzrlib/plugins')
667
packs, mods = mf.get_result()
668
additional_packages.update(packs)
669
includes.extend(mods)
671
console_targets = [target,
672
'tools/win32/bzr_postinstall.py',
674
gui_targets = [gui_target]
675
data_files = topics_files + plugins_files + I18N_FILES
677
if 'qbzr' in plugins:
678
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
681
get_svn_py2exe_info(includes, excludes, packages)
683
if 'fastimport' in plugins:
684
get_fastimport_py2exe_info(includes, excludes, packages)
686
if "TBZR" in os.environ:
687
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
688
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
689
# can be downloaded from (username=guest, blank password):
690
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
691
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
692
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
693
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
694
'TORTOISE_OVERLAYS_MSI_X64'):
695
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
697
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
699
"\nPlease set %s to the location of the relevant"
700
"\nTortoiseOverlays .msi installer file."
701
" The installers can be found at"
703
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
704
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
705
gui_targets, data_files)
707
# print this warning to stderr as output is redirected, so it is seen
708
# at build time. Also to stdout so it appears in the log
709
for f in (sys.stderr, sys.stdout):
710
f.write("Skipping TBZR binaries - "
711
"please set TBZR to a directory to enable\n")
713
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
715
dll_excludes.extend(["MSWSOCK.dll",
720
options_list = {"py2exe": {"packages": packages + list(additional_packages),
721
"includes": includes,
722
"excludes": excludes,
723
"dll_excludes": dll_excludes,
724
"dist_dir": "win32_bzr.exe",
726
"custom_boot_script":
727
"tools/win32/py2exe_boot_common.py",
731
# We want the libaray.zip to have optimize = 2, but the exe to have
732
# optimize = 1, so that .py files that get compilied at run time
733
# (e.g. user installed plugins) dont have their doc strings removed.
734
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
735
def build_executable(self, *args, **kwargs):
737
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
740
if __name__ == '__main__':
741
command_classes['install_data'] = install_data_with_bytecompile
742
command_classes['py2exe'] = py2exe_no_oo_exe
743
setup(options=options_list,
744
console=console_targets,
746
zipfile='lib/library.zip',
747
data_files=data_files,
748
cmdclass=command_classes,
752
# ad-hoc for easy_install
754
if not 'bdist_egg' in sys.argv:
755
# generate and install bzr.1 only with plain install, not the
757
DATA_FILES = [('man/man1', ['bzr.1'])]
759
DATA_FILES = DATA_FILES + I18N_FILES
761
ARGS = {'scripts': ['bzr'],
762
'data_files': DATA_FILES,
763
'cmdclass': command_classes,
764
'ext_modules': ext_modules,
767
ARGS.update(META_INFO)
769
ARGS.update(PKG_DATA)
771
if __name__ == '__main__':