-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsetup.py
147 lines (127 loc) · 5.49 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Copyright 2016-2018 Dirk Thomas
# Licensed under the Apache License, Version 2.0
from contextlib import suppress
import os
import sys
from setuptools import setup
if sys.platform == 'win32':
print(
"The Python package 'colcon-argcomplete' doesn't support Windows",
file=sys.stderr)
sys.exit(1)
if 'BUILD_DEBIAN_PACKAGE' not in os.environ:
from pkg_resources import parse_version
from setuptools import __version__ as setuptools_version
minimum_version = '40.5.0'
if parse_version(setuptools_version) < parse_version(minimum_version):
print(
"The Python package 'colcon-argcomplete' requires at least "
'setuptools version {minimum_version}'.format_map(locals()),
file=sys.stderr)
sys.exit(1)
cmdclass = {}
try:
from stdeb.command.sdist_dsc import sdist_dsc
except ImportError:
pass
else:
class CustomSdistDebCommand(sdist_dsc):
"""Weird approach to apply the Debian patches during packaging."""
def run(self): # noqa: D102
from stdeb.command import sdist_dsc
build_dsc = sdist_dsc.build_dsc
def custom_build_dsc(*args, **kwargs):
nonlocal build_dsc
debinfo = self.get_debinfo()
repackaged_dirname = \
debinfo.source + '-' + debinfo.upstream_version
dst_directory = os.path.join(
self.dist_dir, repackaged_dirname, 'debian', 'patches')
os.makedirs(dst_directory, exist_ok=True)
# read patch
with open('debian/patches/setup.cfg.patch', 'r') as h:
lines = h.read().splitlines()
print(
"writing customized patch '%s'" %
os.path.join(dst_directory, 'setup.cfg.patch'))
# write patch with modified path
with open(
os.path.join(dst_directory, 'setup.cfg.patch'), 'w'
) as h:
for line in lines:
if line.startswith('--- ') or line.startswith('+++ '):
line = \
line[0:4] + repackaged_dirname + '/' + line[4:]
h.write(line + '\n')
with open(os.path.join(dst_directory, 'series'), 'w') as h:
h.write('setup.cfg.patch\n')
return build_dsc(*args, **kwargs)
sdist_dsc.build_dsc = custom_build_dsc
super().run()
cmdclass['sdist_dsc'] = CustomSdistDebCommand
if 'BUILD_DEBIAN_PACKAGE' in os.environ:
import distutils.command.install as distutils_install
import inspect
import shutil
from setuptools.command.install import install
src_base = 'completion'
data_files = (
('share/colcon_argcomplete/hook', [
'completion/colcon-argcomplete.bash',
'completion/colcon-argcomplete.zsh']),
)
dst_prefix = None
if os.path.exists('.pc/applied-patches'):
# assuming this is a deb_dist build
# use dst prefix for data files
dst_prefix = os.path.join(
os.getcwd(), 'debian/python3-colcon-argcomplete')
class CustomInstallCommand(install):
def run(self):
global data_files
# https://github.com/pypa/setuptools/blob/52aacd5b276fedd6849c3a648a0014f5da563e93/setuptools/command/install.py#L59-L67
# Explicit request for old-style install? Just do it
if self.old_and_unmanageable or self.single_version_externally_managed:
distutils_install.install.run(self)
elif not self._called_from_setup(inspect.currentframe()):
# Run in backward-compatibility mode to support bdist_* commands.
distutils_install.install.run(self)
else:
super().do_egg_install()
_foreach_data_file(
self, data_files,
'Copying {src} to {dst_dir}',
_copy_data_file)
def _foreach_data_file(command, data_files, msg, callback):
global dst_prefix
for dst_dir, srcs in data_files:
if command.prefix is not None:
dst_dir = os.path.join(command.prefix, dst_dir)
if dst_prefix:
dst_dir = os.path.join(dst_prefix) + dst_dir
for src in srcs:
dst = os.path.join(dst_dir, os.path.basename(src))
with suppress(OSError):
src = os.path.join(
os.path.dirname(os.path.realpath('setup.py')),
src)
print(msg.format_map(locals()))
if not command.dry_run:
callback(src, dst_dir, dst)
def _copy_data_file(src, dst_dir, dst):
_prepare_destination(src, dst_dir, dst)
shutil.copy2(src, dst_dir)
def _prepare_destination(src, dst_dir, dst):
assert os.path.isfile(src), \
"data file '{src}' not found".format_map(locals())
assert os.path.isabs(dst_dir), \
'Install command needs to be invoked with --prefix ' \
'or the data files destination must be absolute'
assert not os.path.isfile(dst_dir), \
'data file destination directory must not be a file'
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir, exist_ok=True)
with suppress(FileNotFoundError):
os.remove(dst)
cmdclass['install'] = CustomInstallCommand
setup(cmdclass=cmdclass)