1b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# -*- coding: ascii -*-
2b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
3b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Copyright 2007 - 2013
4b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Andr\xe9 Malo or his licensors, as applicable
5b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
6b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Licensed under the Apache License, Version 2.0 (the "License");
7b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# you may not use this file except in compliance with the License.
8b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# You may obtain a copy of the License at
9b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
10b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#     http://www.apache.org/licenses/LICENSE-2.0
11b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
12b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Unless required by applicable law or agreed to in writing, software
13b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# distributed under the License is distributed on an "AS IS" BASIS,
14b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# See the License for the specific language governing permissions and
16b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# limitations under the License.
17b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
18b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang===================
19b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Main setup runner
20b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang===================
21b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
22b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei WangThis module provides a wrapper around the distutils core setup.
23b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
24b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__author__ = "Andr\xe9 Malo"
25b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__docformat__ = "restructuredtext en"
26b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
27b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport configparser as _config_parser
28b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils import core as _core
29b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport os as _os
30b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport posixpath as _posixpath
31b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport sys as _sys
32b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
33b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom _setup import commands as _commands
34b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom _setup import data as _data
35b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom _setup import ext as _ext
36b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom _setup import util as _util
37b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom _setup import shell as _shell
38b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
39b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
40b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef check_python_version(impl, version_min, version_max):
41b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Check python version """
42b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if impl == 'python':
43b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        version_info = _sys.version_info
44b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    elif impl == 'pypy3':
45b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        version_info = getattr(_sys, 'pypy_version_info', None)
46b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if not version_info:
47b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            return
48b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    elif impl == 'jython':
49b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if not 'java' in _sys.platform.lower():
50b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            return
51b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        version_info = _sys.version_info
52b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    else:
53b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        raise AssertionError("impl not in ('python', 'pypy3', 'jython')")
54b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
55b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    pyversion = list(map(int, version_info[:3]))
56b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if version_min:
57b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        min_required = list(
58b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            map(int, '.'.join((version_min, '0.0.0')).split('.')[:3])
59b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        )
60b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if pyversion < min_required:
61b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            raise EnvironmentError("Need at least %s %s (vs. %s)" % (
62b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                impl, version_min, '.'.join(map(str, pyversion))
63b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ))
64b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if version_max:
65b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        max_required = list(map(int, version_max.split('.')))
66b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        max_required[-1] += 1
67b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if pyversion >= max_required:
68b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            raise EnvironmentError("Need at max %s %s (vs. %s)" % (
69b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                impl,
70b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                version_max,
71b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                '.'.join(map(str, pyversion))
72b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ))
73b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
74b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
75b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_description(docs):
76b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
77b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Determine the package description from DESCRIPTION
78b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
79b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :Parameters:
80b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang      `docs` : ``dict``
81b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Docs config section
82b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
83b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :Return: Tuple of summary, description and license
84b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang             (``('summary', 'description', 'license')``)
85b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang             (all may be ``None``)
86b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :Rtype: ``tuple``
87b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
88b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    summary = None
89b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    filename = docs.get('meta.summary', 'SUMMARY').strip()
90b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if filename and _os.path.isfile(filename):
91b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp = open(filename, encoding='utf-8')
92b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
93b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            try:
94b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                summary = fp.read().strip().splitlines()[0].rstrip()
95b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            except IndexError:
96b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                summary = ''
97b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        finally:
98b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            fp.close()
99b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
100b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    description = None
101b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    filename = docs.get('meta.description', 'DESCRIPTION').strip()
102b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if filename and _os.path.isfile(filename):
103b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp = open(filename, encoding='utf-8')
104b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
105b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            description = fp.read().rstrip()
106b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        finally:
107b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            fp.close()
108b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
109b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if summary is None and description:
110b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            from docutils import core
111b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            summary = core.publish_parts(
112b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                source=description,
113b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                source_path=filename,
114b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                writer_name='html',
115b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            )['title'].encode('utf-8')
116b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
117b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return summary, description
118b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
119b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
120b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_classifiers(docs):
121b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
122b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Determine classifiers from CLASSIFIERS
123b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
124b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :return: List of classifiers (``['classifier', ...]``)
125b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :rtype: ``list``
126b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
127b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    filename = docs.get('meta.classifiers', 'CLASSIFIERS').strip()
128b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if filename and _os.path.isfile(filename):
129b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp = open(filename, encoding='utf-8')
130b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
131b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            content = fp.read()
132b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        finally:
133b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            fp.close()
134b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        content = [item.strip() for item in content.splitlines()]
135b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return [item for item in content if item and not item.startswith('#')]
136b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return []
137b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
138b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
139b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_provides(docs):
140b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
141b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Determine provides from PROVIDES
142b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
143b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :return: List of provides (``['provides', ...]``)
144b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :rtype: ``list``
145b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
146b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    filename = docs.get('meta.provides', 'PROVIDES').strip()
147b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if filename and _os.path.isfile(filename):
148b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp = open(filename, encoding='utf-8')
149b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
150b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            content = fp.read()
151b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        finally:
152b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            fp.close()
153b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        content = [item.strip() for item in content.splitlines()]
154b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return [item for item in content if item and not item.startswith('#')]
155b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return []
156b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
157b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
158b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_license(docs):
159b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
160b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Determine license from LICENSE
161b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
162b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :return: License text
163b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :rtype: ``str``
164b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
165b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    filename = docs.get('meta.license', 'LICENSE').strip()
166b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if filename and _os.path.isfile(filename):
167b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp = open(filename, encoding='utf-8')
168b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
169b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            return fp.read().rstrip()
170b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        finally:
171b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            fp.close()
172b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return None
173b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
174b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
175b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_packages(manifest):
176b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Determine packages and subpackages """
177b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    packages = {}
178b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    collect = manifest.get('packages.collect', '').split()
179b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lib = manifest.get('packages.lib', '.')
180b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
181b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        sep = _os.path.sep
182b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except AttributeError:
183b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        sep = _os.path.join('1', '2')[1:-1]
184b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for root in collect:
185b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for dirpath, _, filenames in _shell.walk(_os.path.join(lib, root)):
186b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if dirpath.find('.svn') >= 0 or dirpath.find('.git') >= 0:
187b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                continue
188b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if '__init__.py' in filenames:
189b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                packages[
190b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    _os.path.normpath(dirpath).replace(sep, '.')
191b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                ] = None
192b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    packages = list(packages.keys())
193b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    packages.sort()
194b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return packages
195b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
196b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
197b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef find_data(name, docs):
198b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Determine data files """
199b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result = []
200b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if docs.get('extra', '').strip():
201b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_data.Documentation(docs['extra'].split(),
202b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            prefix='share/doc/%s' % name,
203b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ))
204b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if docs.get('examples.dir', '').strip():
205b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        tpl = ['recursive-include %s *' % docs['examples.dir']]
206b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if docs.get('examples.ignore', '').strip():
207b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            tpl.extend(["global-exclude %s" % item
208b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for item in docs['examples.ignore'].split()
209b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ])
210b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        strip = int(docs.get('examples.strip', '') or 0)
211b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_data.Documentation.from_templates(*tpl, **{
212b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'strip': strip,
213b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'prefix': 'share/doc/%s' % name,
214b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'preserve': 1,
215b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        }))
216b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if docs.get('userdoc.dir', '').strip():
217b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        tpl = ['recursive-include %s *' % docs['userdoc.dir']]
218b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if docs.get('userdoc.ignore', '').strip():
219b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            tpl.extend(["global-exclude %s" % item
220b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for item in docs['userdoc.ignore'].split()
221b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ])
222b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        strip = int(docs.get('userdoc.strip', '') or 0)
223b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_data.Documentation.from_templates(*tpl, **{
224b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'strip': strip,
225b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'prefix': 'share/doc/%s' % name,
226b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'preserve': 1,
227b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        }))
228b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if docs.get('apidoc.dir', '').strip():
229b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        tpl = ['recursive-include %s *' % docs['apidoc.dir']]
230b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if docs.get('apidoc.ignore', '').strip():
231b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            tpl.extend(["global-exclude %s" % item
232b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for item in docs['apidoc.ignore'].split()
233b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ])
234b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        strip = int(docs.get('apidoc.strip', '') or 0)
235b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_data.Documentation.from_templates(*tpl, **{
236b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'strip': strip,
237b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'prefix': 'share/doc/%s' % name,
238b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'preserve': 1,
239b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        }))
240b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if docs.get('man', '').strip():
241b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.extend(_data.Manpages.dispatch(docs['man'].split()))
242b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return result
243b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
244b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
245b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef make_manifest(manifest, config, docs, kwargs):
246b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Create file list to pack up """
247b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # pylint: disable = R0912
248b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    kwargs = kwargs.copy()
249b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    kwargs['script_args'] = ['install']
250b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    kwargs['packages'] = list(kwargs.get('packages') or ()) + [
251b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        '_setup', '_setup.py2', '_setup.py3',
252b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    ] + list(manifest.get('packages.extra', '').split() or ())
253b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _core._setup_stop_after = "commandline"  # noqa pylint: disable = protected-access
254b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
255b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        dist = _core.setup(**kwargs)
256b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    finally:
257b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _core._setup_stop_after = None  # pylint: disable = protected-access
258b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
259b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result = ['MANIFEST', 'PKG-INFO', 'setup.py'] + list(config)
260b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # xx: work with default values?
261b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for key in ('classifiers', 'description', 'summary', 'provides',
262b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                'license'):
263b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        filename = docs.get('meta.' + key, '').strip()
264b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if filename and _os.path.isfile(filename):
265b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.append(filename)
266b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
267b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd = dist.get_command_obj("build_py")
268b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd.ensure_finalized()
269b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # from pprint import pprint; pprint(("build_py", cmd.get_source_files()))
270b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for item in cmd.get_source_files():
271b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_posixpath.sep.join(
272b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            _os.path.normpath(item).split(_os.path.sep)
273b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ))
274b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
275b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd = dist.get_command_obj("build_ext")
276b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd.ensure_finalized()
277b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # from pprint import pprint; pprint(("build_ext", cmd.get_source_files()))
278b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for item in cmd.get_source_files():
279b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(_posixpath.sep.join(
280b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            _os.path.normpath(item).split(_os.path.sep)
281b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ))
282b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for ext in cmd.extensions:
283b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if ext.depends:
284b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.extend([_posixpath.sep.join(
285b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                _os.path.normpath(item).split(_os.path.sep)
286b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ) for item in ext.depends])
287b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
288b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd = dist.get_command_obj("build_clib")
289b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd.ensure_finalized()
290b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if cmd.libraries:
291b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        # import pprint; pprint.pprint(("build_clib", cmd.get_source_files()))
292b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for item in cmd.get_source_files():
293b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.append(_posixpath.sep.join(
294b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                _os.path.normpath(item).split(_os.path.sep)
295b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ))
296b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for lib in cmd.libraries:
297b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if lib[1].get('depends'):
298b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                result.extend([_posixpath.sep.join(
299b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    _os.path.normpath(item).split(_os.path.sep)
300b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                ) for item in lib[1]['depends']])
301b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
302b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd = dist.get_command_obj("build_scripts")
303b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd.ensure_finalized()
304b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # import pprint; pprint.pprint(("build_scripts", cmd.get_source_files()))
305b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if cmd.get_source_files():
306b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for item in cmd.get_source_files():
307b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.append(_posixpath.sep.join(
308b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                _os.path.normpath(item).split(_os.path.sep)
309b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ))
310b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
311b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd = dist.get_command_obj("install_data")
312b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cmd.ensure_finalized()
313b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # from pprint import pprint; pprint(("install_data", cmd.get_inputs()))
314b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
315b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        strings = str
316b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except NameError:
317b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        strings = (str, str)
318b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
319b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for item in cmd.get_inputs():
320b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if isinstance(item, strings):
321b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.append(item)
322b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        else:
323b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            result.extend(item[1])
324b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
325b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for item in manifest.get('dist', '').split():
326b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result.append(item)
327b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if _os.path.isdir(item):
328b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for filename in _shell.files(item):
329b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                result.append(filename)
330b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
331b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result = list(dict([(item, None) for item in result]).keys())
332b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result.sort()
333b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return result
334b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
335b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
336b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef run(config=('package.cfg',), ext=None, script_args=None, manifest_only=0):
337b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Main runner """
338b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # pylint: disable = too-many-locals
339b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if ext is None:
340b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ext = []
341b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
342b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    cfg = _util.SafeConfigParser()
343b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if (3, 0, 0) <= _sys.version_info < (3, 2, 0):
344b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        cfg.read(config)
345b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    else:
346b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        cfg.read(config, encoding='utf-8')
347b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    pkg = dict(cfg.items('package'))
348b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    python_min = pkg.get('python.min') or None
349b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    python_max = pkg.get('python.max') or None
350b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    check_python_version('python', python_min, python_max)
351b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    pypy_min = pkg.get('pypy3.min') or None
352b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    pypy_max = pkg.get('pypy3.max') or None
353b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    check_python_version('pypy3', pypy_min, pypy_max)
354b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    jython_min = pkg.get('jython.min') or None
355b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    jython_max = pkg.get('jython.max') or None
356b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    check_python_version('jython', jython_min, jython_max)
357b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
358b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    manifest = dict(cfg.items('manifest'))
359b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
360b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        docs = dict(cfg.items('docs'))
361b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except _config_parser.NoSectionError:
362b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        docs = {}
363b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
364b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    summary, description = find_description(docs)
365b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    scripts = manifest.get('scripts', '').strip() or None
366b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if scripts:
367b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        scripts = scripts.split()
368b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    modules = manifest.get('modules', '').strip() or None
369b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if modules:
370b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        modules = modules.split()
371b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    keywords = docs.get('meta.keywords', '').strip() or None
372b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if keywords:
373b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        keywords = keywords.split()
374b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    revision = pkg.get('version.revision', '').strip()
375b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if revision:
376b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        revision = int(revision)
377b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    else:
378b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        revision = 0
379b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
380b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    kwargs = {
381b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'name': pkg['name'],
382b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'version': "%s%s" % (
383b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            pkg['version.number'],
384b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ["", ".dev%d" % (revision,)][_util.humanbool(
385b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                'version.dev', pkg.get('version.dev', 'false')
386b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            )],
387b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ),
388b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'provides': find_provides(docs),
389b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'description': summary,
390b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'long_description': description,
391b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'classifiers': find_classifiers(docs),
392b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'keywords': keywords,
393b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'author': pkg['author.name'],
394b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'author_email': pkg['author.email'],
395b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'maintainer': pkg.get('maintainer.name'),
396b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'maintainer_email': pkg.get('maintainer.email'),
397b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'url': pkg.get('url.homepage'),
398b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'download_url': pkg.get('url.download'),
399b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'license': find_license(docs),
400b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'package_dir': {'': manifest.get('packages.lib', '.')},
401b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'packages': find_packages(manifest),
402b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'py_modules': modules,
403b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'ext_modules': ext,
404b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'scripts': scripts,
405b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'script_args': script_args,
406b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'data_files': find_data(pkg['name'], docs),
407b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'cmdclass': {
408b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'build'       : _commands.Build,
409b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'build_ext'   : _commands.BuildExt,
410b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'install'     : _commands.Install,
411b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'install_data': _commands.InstallData,
412b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'install_lib' : _commands.InstallLib,
413b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        }
414b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    }
415b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for key in ('provides',):
416b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if key not in _core.setup_keywords:
417b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            del kwargs[key]
418b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
419b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if manifest_only:
420b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return make_manifest(manifest, config, docs, kwargs)
421b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
422b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # monkey-patch crappy manifest writer away.
423b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    from distutils.command import sdist
424b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    sdist.sdist.get_file_list = sdist.sdist.read_manifest
425b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
426b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return _core.setup(**kwargs)
427