Skip to content

Commit

Permalink
Refactor setup.py helper code
Browse files Browse the repository at this point in the history
  • Loading branch information
webknjaz committed Apr 12, 2018
1 parent 922e703 commit 8912b43
Showing 1 changed file with 81 additions and 35 deletions.
116 changes: 81 additions & 35 deletions setup.py
@@ -1,4 +1,6 @@

from __future__ import print_function

import json
import os
import os.path
Expand All @@ -16,7 +18,7 @@
except ImportError:
print("Ansible now needs setuptools in order to build. Install it using"
" your package manager (usually python-setuptools) or via pip (pip"
" install setuptools).")
" install setuptools).", file=sys.stderr)
sys.exit(1)

sys.path.insert(0, os.path.abspath('lib'))
Expand Down Expand Up @@ -49,7 +51,7 @@ def _find_symlinks(topdir, extension=''):

def _cache_symlinks(symlink_data):
with open(SYMLINK_CACHE, 'w') as f:
f.write(json.dumps(symlink_data))
json.dump(symlink_data, f)


def _maintain_symlinks(symlink_type, base_path):
Expand All @@ -58,7 +60,7 @@ def _maintain_symlinks(symlink_type, base_path):
# Try the cache first because going from git checkout to sdist is the
# only time we know that we're going to cache correctly
with open(SYMLINK_CACHE, 'r') as f:
symlink_data = json.loads(f.read())
symlink_data = json.load(f)
except (IOError, OSError) as e:
# IOError on py2, OSError on py3. Both have errno
if e.errno == 2:
Expand Down Expand Up @@ -129,41 +131,87 @@ def run(self):
SDist.run(self)


with open('requirements.txt') as requirements_file:
install_requirements = requirements_file.read().splitlines()
if not install_requirements:
print("Unable to read requirements from the requirements.txt file"
"That indicates this copy of the source code is incomplete.")
sys.exit(2)

# pycrypto or cryptography. We choose a default but allow the user to
# override it. This translates into pip install of the sdist deciding what
# package to install and also the runtime dependencies that pkg_resources
# knows about
crypto_backend = os.environ.get('ANSIBLE_CRYPTO_BACKEND', None)
if crypto_backend:
if crypto_backend.strip() == 'pycrypto':
def read_file(file_name):
"""Read file and return its contents."""
with open(file_name, 'r') as f:
return f.read()


def read_requirements(file_name):
"""Read requirements file as a list."""
reqs = read_file(file_name).splitlines()
if not reqs:
raise RuntimeError(
"Unable to read requirements from the %s file"
"That indicates this copy of the source code is incomplete."
% file_name
)
return reqs


PYCRYPTO_DIST = 'pycrypto'


def get_crypto_req():
"""Detect custom crypto from ANSIBLE_CRYPTO_BACKEND env var.
pycrypto or cryptography. We choose a default but allow the user to
override it. This translates into pip install of the sdist deciding what
package to install and also the runtime dependencies that pkg_resources
knows about.
"""
crypto_backend = os.environ.get('ANSIBLE_CRYPTO_BACKEND', '').strip()

if crypto_backend == PYCRYPTO_DIST:
# Attempt to set version requirements
crypto_backend = 'pycrypto >= 2.6'
return '%s >= 2.6' % PYCRYPTO_DIST

return crypto_backend or None


def substitute_crypto_to_req(req):
"""Replace crypto requirements if customized."""
crypto_backend = get_crypto_req()

if crypto_backend is None:
return req

def is_not_crypto(r):
CRYPTO_LIBS = PYCRYPTO_DIST, 'cryptography'
return not any(r.lower().startswith(c) for c in CRYPTO_LIBS)

return [r for r in req if is_not_crypto(r)] + [crypto_backend]


install_requirements = [r for r in install_requirements if not (r.lower().startswith('pycrypto') or r.lower().startswith('cryptography'))]
install_requirements.append(crypto_backend)
def read_extras():
"""Specify any extra requirements for installation."""
extras = dict()
extra_requirements_dir = 'packaging/requirements'
for extra_requirements_filename in os.listdir(extra_requirements_dir):
filename_match = re.search(r'^requirements-(\w*).txt$', extra_requirements_filename)
if not filename_match:
continue
extra_req_file_path = os.path.join(extra_requirements_dir, extra_requirements_filename)
try:
extras[filename_match.group(1)] = read_file(extra_req_file_path).splitlines()
except RuntimeError:
pass
return extras

# specify any extra requirements for installation
extra_requirements = dict()
extra_requirements_dir = 'packaging/requirements'
for extra_requirements_filename in os.listdir(extra_requirements_dir):
filename_match = re.search(r'^requirements-(\w*).txt$', extra_requirements_filename)
if filename_match:
with open(os.path.join(extra_requirements_dir, extra_requirements_filename)) as extra_requirements_file:
extra_requirements[filename_match.group(1)] = extra_requirements_file.read().splitlines()

# Retrieve the long description from the README
with open('README.rst', 'r') as readme_file:
longdesc = readme_file.read()
def get_dynamic_setup_params():
"""Add dynamically calculated setup params to static ones."""
return {
# Retrieve the long description from the README
'long_description': read_file('README.rst'),
'install_requires': substitute_crypto_to_req(
read_requirements('requirements.txt'),
),
'extras_require': read_extras(),
}


setup_params = dict(
static_setup_params = dict(
# Use the distutils SDist so that symlinks are not expanded
# Use a custom Build for the same reason
cmdclass={
Expand All @@ -176,7 +224,6 @@ def run(self):
name='ansible',
version=__version__,
description='Radically simple IT automation',
long_description=longdesc,
author=__author__,
author_email='info@ansible.com',
url='https://ansible.com/',
Expand All @@ -189,7 +236,6 @@ def run(self):
license='GPLv3+',
# Ansible will also make use of a system copy of python-six and
# python-selectors2 if installed but use a Bundled copy if it's not.
install_requires=install_requirements,
python_requires='>=2.6,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
package_dir={'': 'lib'},
packages=find_packages('lib'),
Expand Down Expand Up @@ -237,14 +283,14 @@ def run(self):
'bin/ansible-inventory',
],
data_files=[],
extras_require=extra_requirements,
# Installing as zip files would break due to references to __file__
zip_safe=False
)


def main():
"""Invoke installation process using setuptools."""
setup_params = dict(static_setup_params, **get_dynamic_setup_params())
setup(**setup_params)


Expand Down

0 comments on commit 8912b43

Please sign in to comment.