32
24
def get_long_description():
33
25
dirname = os.path.dirname(__file__)
34
readme = os.path.join(dirname, 'README.rst')
35
with open(readme, 'r') as f:
26
readme = os.path.join(dirname, 'README')
27
f = open(readme, 'rb')
40
35
# META INFORMATION FOR SETUP
41
36
# 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',
39
'version': breezy.__version__,
40
'author': 'Canonical Ltd',
41
'author_email': 'bazaar@lists.canonical.com',
42
'maintainer': 'Breezy Developers',
43
'url': 'https://www.breezy-vcs.org/',
44
'description': 'Friendly distributed version control system',
45
'license': 'GNU GPL v2',
50
46
'download_url': 'https://launchpad.net/brz/+download',
51
47
'long_description': get_long_description(),
62
58
'Programming Language :: C',
63
59
'Topic :: Software Development :: Version Control',
68
# Technically, Breezy works without these two dependencies too. But there's
69
# no way to enable them by default and let users opt out.
70
'dulwich>=0.19.12;python_version>="3.5"',
71
'dulwich<0.20,>=0.19.12;python_version<"3.0"',
76
'launchpad': ['launchpadlib>=1.6.3'],
77
'workspace': ['pyinotify'],
81
'testtools<=2.4.0;python_version<"3.0"',
86
63
# The list of packages is automatically generated later. Add other things
87
# that are part of BREEZY here.
64
# that are part of BZRLIB here.
91
# install files from selftest suite
92
'package_data': {'breezy': ['doc/api/*.txt',
93
'tests/test_patches_data/*',
94
'help_topics/en/*.txt',
95
'tests/ssl_certs/ca.crt',
96
'tests/ssl_certs/server_without_pass.key',
97
'tests/ssl_certs/server_with_pass.key',
98
'tests/ssl_certs/server.crt',
67
PKG_DATA = {# install files from selftest suite
68
'package_data': {'breezy': ['doc/api/*.txt',
69
'tests/test_patches_data/*',
70
'help_topics/en/*.txt',
71
'tests/ssl_certs/ca.crt',
72
'tests/ssl_certs/server_without_pass.key',
73
'tests/ssl_certs/server_with_pass.key',
74
'tests/ssl_certs/server.crt',
102
78
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
103
79
langfile = filepath[len("breezy/locale/"):]
119
95
if not package_path:
120
96
package_name = 'breezy'
124
package_path.replace('/', '.').replace('\\', '.'))
98
package_name = ('breezy.' +
99
package_path.replace('/', '.').replace('\\', '.'))
125
100
packages.append(package_name)
126
101
return sorted(packages)
129
BREEZY['packages'] = get_breezy_packages()
132
from setuptools import setup
104
BZRLIB['packages'] = get_breezy_packages()
107
from distutils import log
108
from distutils.core import setup
133
109
from distutils.version import LooseVersion
134
110
from distutils.command.install_scripts import install_scripts
135
111
from distutils.command.install_data import install_data
152
128
script_path = self._quoted_path(os.path.join(scripts_dir,
154
130
python_exe = self._quoted_path(sys.executable)
155
batch_str = "@%s %s %%*" % (python_exe, script_path)
131
args = self._win_batch_args()
132
batch_str = "@%s %s %s" % (python_exe, script_path, args)
156
133
batch_path = os.path.join(self.install_dir, "brz.bat")
157
with open(batch_path, "w") as f:
134
f = file(batch_path, "w")
159
137
print(("Created: %s" % batch_path))
160
138
except Exception:
161
139
e = sys.exc_info()[1]
200
185
from distutils.extension import Extension
203
from Cython.Distutils import build_ext
204
from Cython.Compiler.Version import version as cython_version
189
from Cython.Distutils import build_ext
190
from Cython.Compiler.Version import version as pyrex_version
192
print("No Cython, trying Pyrex...")
193
from Pyrex.Distutils import build_ext
194
from Pyrex.Compiler.Version import version as pyrex_version
205
195
except ImportError:
207
197
# try to build the extension from the prior generated source.
209
print("The python package 'Cython' is not available."
199
print("The python package 'Pyrex' is not available."
210
200
" If the .c files are available,")
211
201
print("they will be built,"
212
202
" but modifying the .pyx files will not rebuild them.")
214
204
from distutils.command.build_ext import build_ext
216
minimum_cython_version = '0.29'
217
cython_version_info = LooseVersion(cython_version)
218
if cython_version_info < LooseVersion(minimum_cython_version):
219
print("Version of Cython is too old. "
220
"Current is %s, need at least %s."
221
% (cython_version, minimum_cython_version))
222
print("If the .c files are available, they will be built,"
223
" but modifying the .pyx files will not rebuild them.")
207
pyrex_version_info = LooseVersion(pyrex_version)
229
210
class build_ext_if_possible(build_ext):
270
# Override the build_ext if we have Cython available
251
# Override the build_ext if we have Pyrex available
271
252
command_classes['build_ext'] = build_ext_if_possible
272
253
unavailable_files = []
275
def add_cython_extension(module_name, libraries=None, extra_source=[]):
276
"""Add a cython module to build.
256
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
257
"""Add a pyrex module to build.
278
This will use Cython to auto-generate the .c file if it is available.
259
This will use Pyrex to auto-generate the .c file if it is available.
279
260
Otherwise it will fall back on the .c file. If the .c file is not
280
261
available, it will warn, and not add anything.
286
267
determine the .pyx and .c files to use.
288
269
path = module_name.replace('.', '/')
289
cython_name = path + '.pyx'
270
pyrex_name = path + '.pyx'
290
271
c_name = path + '.c'
291
272
define_macros = []
292
273
if sys.platform == 'win32':
293
# cython uses the macro WIN32 to detect the platform, even though it
274
# pyrex uses the macro WIN32 to detect the platform, even though it
294
275
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
295
276
# give it the right value.
296
277
define_macros.append(('WIN32', None))
298
source = [cython_name]
279
source = [pyrex_name]
300
281
if not os.path.isfile(c_name):
301
282
unavailable_files.append(c_name)
304
285
source = [c_name]
305
286
source.extend(extra_source)
306
include_dirs = ['breezy']
309
module_name, source, define_macros=define_macros,
310
libraries=libraries, include_dirs=include_dirs))
313
add_cython_extension('breezy._simple_set_pyx')
314
ext_modules.append(Extension('breezy._static_tuple_c',
315
['breezy/_static_tuple_c.c']))
316
add_cython_extension('breezy._annotator_pyx')
317
add_cython_extension('breezy._bencode_pyx')
318
add_cython_extension('breezy._chunks_to_lines_pyx')
319
add_cython_extension('breezy.bzr._groupcompress_pyx',
320
extra_source=['breezy/bzr/diff-delta.c'])
321
add_cython_extension('breezy.bzr._knit_load_data_pyx')
322
add_cython_extension('breezy._known_graph_pyx')
323
add_cython_extension('breezy._rio_pyx')
287
ext_modules.append(Extension(module_name, source,
288
define_macros=define_macros, libraries=libraries))
291
add_pyrex_extension('breezy._annotator_pyx')
292
add_pyrex_extension('breezy._bencode_pyx')
293
add_pyrex_extension('breezy._chunks_to_lines_pyx')
294
add_pyrex_extension('breezy.bzr._groupcompress_pyx',
295
extra_source=['breezy/bzr/diff-delta.c'])
296
add_pyrex_extension('breezy.bzr._knit_load_data_pyx')
297
add_pyrex_extension('breezy._known_graph_pyx')
298
add_pyrex_extension('breezy._rio_pyx')
324
299
if sys.platform == 'win32':
325
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
326
libraries=['Ws2_32'])
327
add_cython_extension('breezy._walkdirs_win32')
329
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
330
add_cython_extension('breezy._readdir_pyx')
331
add_cython_extension('breezy.bzr._chk_map_pyx')
332
add_cython_extension('breezy.bzr._btree_serializer_pyx')
300
add_pyrex_extension('breezy.bzr._dirstate_helpers_pyx',
301
libraries=['Ws2_32'])
302
add_pyrex_extension('breezy._walkdirs_win32')
304
if have_pyrex and pyrex_version_info == LooseVersion("0.9.4.1"):
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 "breezy.bzr._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('breezy.bzr._dirstate_helpers_pyx')
318
add_pyrex_extension('breezy._readdir_pyx')
319
add_pyrex_extension('breezy.bzr._chk_map_pyx')
320
ext_modules.append(Extension('breezy._patiencediff_c',
321
['breezy/_patiencediff_c.c']))
322
if have_pyrex and pyrex_version_info < LooseVersion("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('breezy._simple_set_pyx')
334
ext_modules.append(Extension('breezy._static_tuple_c',
335
['breezy/_static_tuple_c.c']))
336
add_pyrex_extension('breezy.bzr._btree_serializer_pyx')
335
339
if unavailable_files:
371
375
# First always brz's icon and its in the root of the brz tree.
372
376
icos.append(('', 'brz.ico'))
373
377
for root, dirs, files in os.walk(ico_root):
374
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root) + 1:])
378
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
375
379
for f in files if f.endswith('.ico')])
376
380
# allocate an icon ID for each file and the full path to the ico
377
381
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
392
396
# tbzrcache executables - a "console" version for debugging and a
393
397
# GUI version that is generally used.
394
398
tbzrcache = dict(
395
script=os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
396
icon_resources=icon_resources,
397
other_resources=other_resources,
399
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
400
icon_resources = icon_resources,
401
other_resources = other_resources,
399
403
console_targets.append(tbzrcache)
401
405
# Make a windows version which is the same except for the base name.
402
406
tbzrcachew = tbzrcache.copy()
403
tbzrcachew["dest_base"] = "tbzrcachew"
407
tbzrcachew["dest_base"]="tbzrcachew"
404
408
gui_targets.append(tbzrcachew)
406
410
# ditto for the tbzrcommand tool
407
411
tbzrcommand = dict(
408
script=os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
409
icon_resources=icon_resources,
410
other_resources=other_resources,
412
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
413
icon_resources = icon_resources,
414
other_resources = other_resources,
412
416
console_targets.append(tbzrcommand)
413
417
tbzrcommandw = tbzrcommand.copy()
414
tbzrcommandw["dest_base"] = "tbzrcommandw"
418
tbzrcommandw["dest_base"]="tbzrcommandw"
415
419
gui_targets.append(tbzrcommandw)
417
421
# A utility to see python output from both C++ and Python based shell
419
423
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
571
575
self.outfiles.extend([f + 'o' for f in compile_names])
572
576
# end of class install_data_with_bytecompile
574
target = py2exe.build_exe.Target(
577
icon_resources=[(0, 'brz.ico')],
578
name=META_INFO['name'],
580
description=META_INFO['description'],
581
author=META_INFO['author'],
582
copyright="(c) Canonical Ltd, 2005-2010",
583
company_name="Canonical Ltd.",
584
comments=META_INFO['description'],
578
target = py2exe.build_exe.Target(script = "brz",
580
icon_resources = [(0,'brz.ico')],
581
name = META_INFO['name'],
582
version = version_str,
583
description = META_INFO['description'],
584
author = META_INFO['author'],
585
copyright = "(c) Canonical Ltd, 2005-2010",
586
company_name = "Canonical Ltd.",
587
comments = META_INFO['description'],
586
589
gui_target = copy.copy(target)
587
590
gui_target.dest_base = "bzrw"
589
packages = BREEZY['packages']
592
packages = BZRLIB['packages']
590
593
packages.remove('breezy')
591
594
packages = [i for i in packages if not i.startswith('breezy.plugins')]
597
600
includes.append(module)
599
602
additional_packages = set()
603
if sys.version.startswith('2.4'):
604
# adding elementtree package
605
additional_packages.add('elementtree')
606
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
607
additional_packages.add('xml.etree')
610
warnings.warn('Unknown Python version.\n'
611
'Please check setup.py script for compatibility.')
601
613
# Although we currently can't enforce it, we consider it an error for
602
614
# py2exe to report any files are "missing". Such modules we know aren't
749
762
# ad-hoc for easy_install
751
if 'bdist_egg' not in sys.argv:
764
if not 'bdist_egg' in sys.argv:
752
765
# generate and install brz.1 only with plain install, not the
753
766
# easy_install one
754
DATA_FILES = [('man/man1', ['brz.1', 'breezy/git/git-remote-bzr.1'])]
767
DATA_FILES = [('man/man1', ['brz.1'])]
756
769
DATA_FILES = DATA_FILES + I18N_FILES
758
ARGS = {'scripts': ['brz',
759
# TODO(jelmer): Only install the git scripts if
761
'breezy/git/git-remote-bzr',
762
'breezy/git/bzr-receive-pack',
763
'breezy/git/bzr-upload-pack'],
771
ARGS = {'scripts': ['brz'],
764
772
'data_files': DATA_FILES,
765
773
'cmdclass': command_classes,
766
774
'ext_modules': ext_modules,
769
777
ARGS.update(META_INFO)
771
779
ARGS.update(PKG_DATA)
773
781
if __name__ == '__main__':