import os
import os.path
import sys
import glob
try:
import setuptools
except ModuleNotFoundError as e:
sys.stderr.write("[ERROR] Please install setuptools (%s)\n" % e)
sys.exit(1)
try:
from setuptools_rust import Binding, RustExtension, Strip
except ModuleNotFoundError as e:
sys.stderr.write("[ERROR] Please install setuptools_rust (%s)\n" % e)
sys.exit(1)
import breezy
I18N_FILES = []
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
langfile = filepath[len("breezy/locale/"):]
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
I18N_FILES.append((targetpath, [filepath]))
from setuptools import setup
try:
from packaging.version import Version
except ImportError:
from distutils.version import LooseVersion as Version
from distutils.command.install import install
from distutils.command.install_data import install_data
from distutils.command.install_scripts import install_scripts
from distutils.command.build import build
from distutils.command.build_scripts import build_scripts
class brz_build_scripts(build_scripts):
def run(self):
build_scripts.run(self)
self.run_command('build_ext')
build_ext = self.get_finalized_command("build_ext")
for ext in self.distribution.rust_extensions:
if ext.binding == Binding.Exec:
os.replace(
os.path.join(build_ext.build_lib, ext.name),
os.path.join(self.build_dir, ext.name))
class brz_install(install):
def finalize_options(self):
install.finalize_options(self)
self.single_version_externally_managed = True
class bzr_build(build):
sub_commands = build.sub_commands + [
('build_mo', lambda _: True),
]
def run(self):
build.run(self)
from tools import generate_docs
generate_docs.main(argv=["brz", "man"])
from breezy.bzr_distutils import build_mo
command_classes = {
'build': bzr_build,
'build_mo': build_mo,
'build_scripts': brz_build_scripts,
'install': brz_install,
}
from distutils import log
from distutils.errors import CCompilerError, DistutilsPlatformError
from distutils.extension import Extension
ext_modules = []
try:
from Cython.Distutils import build_ext
from Cython.Compiler.Version import version as cython_version
except ModuleNotFoundError:
have_cython = False
print("")
print("The python package 'Cython' is not available."
" If the .c files are available,")
print("they will be built,"
" but modifying the .pyx files will not rebuild them.")
print("")
from distutils.command.build_ext import build_ext
else:
minimum_cython_version = '0.29'
cython_version_info = Version(cython_version)
if cython_version_info < Version(minimum_cython_version):
print("Version of Cython is too old. "
"Current is %s, need at least %s."
% (cython_version, minimum_cython_version))
print("If the .c files are available, they will be built,"
" but modifying the .pyx files will not rebuild them.")
have_cython = False
else:
have_cython = True
class build_ext_if_possible(build_ext):
user_options = build_ext.user_options + [
('allow-python-fallback', None,
"When an extension cannot be built, allow falling"
" back to the pure-python implementation.")
]
def initialize_options(self):
super(build_ext_if_possible, self).initialize_options()
self.ext_map = {}
self.allow_python_fallback = False
def run(self):
try:
super(build_ext_if_possible, self).run()
except DistutilsPlatformError:
e = sys.exc_info()[1]
if not self.allow_python_fallback:
log.warn('\n Cannot build extensions.\n'
' Use "build_ext --allow-python-fallback" to use'
' slower python implementations instead.\n')
raise
log.warn(str(e))
log.warn('\n Extensions cannot be built.\n'
' Using the slower Python implementations instead.\n')
def build_extension(self, ext):
try:
super(build_ext_if_possible, self).build_extension(ext)
except CCompilerError:
if not self.allow_python_fallback:
log.warn('\n Cannot build extension "%s".\n'
' Use "build_ext --allow-python-fallback" to use'
' slower python implementations instead.\n'
% (ext.name,))
raise
log.warn('\n Building of "%s" extension failed.\n'
' Using the slower Python implementation instead.'
% (ext.name,))
command_classes['build_ext'] = build_ext_if_possible
unavailable_files = []
def add_cython_extension(module_name, libraries=None, extra_source=[]):
path = module_name.replace('.', '/')
cython_name = path + '.pyx'
c_name = path + '.c'
define_macros = []
if sys.platform == 'win32':
define_macros.append(('WIN32', None))
if have_cython:
source = [cython_name]
else:
if not os.path.isfile(c_name):
unavailable_files.append(c_name)
return
else:
source = [c_name]
source.extend(extra_source)
include_dirs = ['breezy']
ext_modules.append(
Extension(
module_name, source, define_macros=define_macros,
libraries=libraries, include_dirs=include_dirs))
add_cython_extension('breezy.bzr._simple_set_pyx')
ext_modules.append(Extension('breezy.bzr._static_tuple_c',
['breezy/bzr/_static_tuple_c.c']))
add_cython_extension('breezy._annotator_pyx')
add_cython_extension('breezy._chunks_to_lines_pyx')
add_cython_extension('breezy.bzr._groupcompress_pyx',
extra_source=['breezy/bzr/diff-delta.c'])
add_cython_extension('breezy.bzr._knit_load_data_pyx')
add_cython_extension('breezy._known_graph_pyx')
add_cython_extension('breezy.bzr._rio_pyx')
if sys.platform == 'win32':
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
libraries=['Ws2_32'])
add_cython_extension('breezy._walkdirs_win32')
else:
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
add_cython_extension('breezy._readdir_pyx')
add_cython_extension('breezy.bzr._chk_map_pyx')
add_cython_extension('breezy.bzr._btree_serializer_pyx')
if unavailable_files:
print('C extension(s) not found:')
print((' %s' % ('\n '.join(unavailable_files),)))
print('The python versions will be used instead.')
print("")
DATA_FILES = []
if 'bdist_egg' not in sys.argv:
DATA_FILES = [('man/man1', ['brz.1', 'breezy/git/git-remote-bzr.1'])]
DATA_FILES = DATA_FILES + I18N_FILES
import site
site.ENABLE_USER_SITE = "--user" in sys.argv
setup(
scripts=[ 'breezy/git/git-remote-bzr',
'breezy/git/bzr-receive-pack',
'breezy/git/bzr-upload-pack'],
data_files=DATA_FILES,
cmdclass=command_classes,
ext_modules=ext_modules,
rust_extensions=[
RustExtension("brz", binding=Binding.Exec, strip=Strip.All),
RustExtension("breezy.bzr._rio_rs", "lib-rio/Cargo.toml", binding=Binding.PyO3),
],
package_data={'breezy': ['doc/api/*.txt',
'tests/test_patches_data/*',
'help_topics/en/*.txt',
'tests/ssl_certs/ca.crt',
'tests/ssl_certs/server_without_pass.key',
'tests/ssl_certs/server_with_pass.key',
'tests/ssl_certs/server.crt',
]})