eff757ee |
import json |
3f245498 |
import os |
57a7d770 |
import os.path |
e4cd8993 |
import re |
3f245498 |
import sys |
eff757ee |
from collections import defaultdict
from distutils.command.build_scripts import build_scripts as BuildScripts
from distutils.command.sdist import sdist as SDist |
3f245498 |
|
e6220748 |
try: |
a0fecd61 |
from setuptools import setup, find_packages |
eff757ee |
from setuptools.command.build_py import build_py as BuildPy
from setuptools.command.install_lib import install_lib as InstallLib
from setuptools.command.install_scripts import install_scripts as InstallScripts |
e6220748 |
except ImportError: |
9095e97c |
print("Ansible now needs setuptools in order to build. Install it using" |
4efec414 |
" your package manager (usually python-setuptools) or via pip (pip"
" install setuptools).") |
8e66a6c8 |
sys.exit(1) |
2c873a44 |
|
eff757ee |
sys.path.insert(0, os.path.abspath('lib'))
from ansible.release import __version__, __author__
SYMLINK_CACHE = 'SYMLINK_CACHE.json'
def _find_symlinks(topdir, extension=''):
"""Find symlinks that should be maintained
Maintained symlinks exist in the bin dir or are modules which have
aliases. Our heuristic is that they are a link in a certain path which
point to a file in the same directory.
"""
symlinks = defaultdict(list)
for base_path, dirs, files in os.walk(topdir):
for filename in files:
filepath = os.path.join(base_path, filename)
if os.path.islink(filepath) and filename.endswith(extension):
target = os.readlink(filepath)
if os.path.dirname(target) == '':
link = filepath[len(topdir):]
if link.startswith('/'):
link = link[1:]
symlinks[os.path.basename(target)].append(link)
return symlinks
def _cache_symlinks(symlink_data):
with open(SYMLINK_CACHE, 'w') as f:
f.write(json.dumps(symlink_data))
def _maintain_symlinks(symlink_type, base_path):
"""Switch a real file into a symlink"""
try:
# 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()) |
e132918b |
except (IOError, OSError) as e:
# IOError on py2, OSError on py3. Both have errno |
eff757ee |
if e.errno == 2:
# SYMLINKS_CACHE doesn't exist. Fallback to trying to create the
# cache now. Will work if we're running directly from a git
# checkout or from an sdist created earlier.
symlink_data = {'script': _find_symlinks('bin'),
'library': _find_symlinks('lib', '.py'),
}
# Sanity check that something we know should be a symlink was
# found. We'll take that to mean that the current directory
# structure properly reflects symlinks in the git repo
if 'ansible-playbook' in symlink_data['script']['ansible']:
_cache_symlinks(symlink_data)
else:
raise
else:
raise
symlinks = symlink_data[symlink_type]
for source in symlinks:
for dest in symlinks[source]:
dest_path = os.path.join(base_path, dest)
if not os.path.islink(dest_path):
try:
os.unlink(dest_path)
except OSError as e:
if e.errno == 2:
# File does not exist which is all we wanted
pass
os.symlink(source, dest_path)
class BuildPyCommand(BuildPy):
def run(self):
BuildPy.run(self)
_maintain_symlinks('library', self.build_lib)
class BuildScriptsCommand(BuildScripts):
def run(self):
BuildScripts.run(self)
_maintain_symlinks('script', self.build_dir)
class InstallLibCommand(InstallLib):
def run(self):
InstallLib.run(self)
_maintain_symlinks('library', self.install_dir)
class InstallScriptsCommand(InstallScripts):
def run(self):
InstallScripts.run(self)
_maintain_symlinks('script', self.install_dir)
class SDistCommand(SDist):
def run(self):
# have to generate the cache of symlinks for release as sdist is the
# only command that has access to symlinks from the git repo
symlinks = {'script': _find_symlinks('bin'),
'library': _find_symlinks('lib', '.py'),
}
_cache_symlinks(symlinks)
SDist.run(self)
|
d7b7cbac |
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" |
4efec414 |
"That indicates this copy of the source code is incomplete.") |
d7b7cbac |
sys.exit(2)
|
9bbd48ad |
# 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: |
e238ae99 |
if crypto_backend.strip() == 'pycrypto':
# Attempt to set version requirements
crypto_backend = 'pycrypto >= 2.6'
|
9bbd48ad |
install_requirements = [r for r in install_requirements if not (r.lower().startswith('pycrypto') or r.lower().startswith('cryptography'))]
install_requirements.append(crypto_backend)
|
e4cd8993 |
# 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()
|
9bbd48ad |
|
87aa59af |
setup( |
eff757ee |
# Use the distutils SDist so that symlinks are not expanded
# Use a custom Build for the same reason
cmdclass={
'build_py': BuildPyCommand,
'build_scripts': BuildScriptsCommand,
'install_lib': InstallLibCommand,
'install_scripts': InstallScriptsCommand,
'sdist': SDistCommand,
}, |
87aa59af |
name='ansible',
version=__version__,
description='Radically simple IT automation',
author=__author__,
author_email='info@ansible.com', |
3700bcb6 |
url='https://ansible.com/', |
5d28d762 |
license='GPLv3+', |
87aa59af |
# 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. |
d7b7cbac |
install_requires=install_requirements, |
4efec414 |
package_dir={'': 'lib'}, |
87aa59af |
packages=find_packages('lib'),
package_data={
'': [ |
dae8857d |
'module_utils/powershell/*.psm1',
'module_utils/powershell/*/*.psm1', |
87aa59af |
'modules/windows/*.ps1', |
dae8857d |
'modules/windows/*/*.ps1', |
87aa59af |
'galaxy/data/*/*.*', |
6f2cd64c |
'galaxy/data/*/*/.*', |
87aa59af |
'galaxy/data/*/*/*.*', |
74842adc |
'galaxy/data/*/tests/inventory', |
f9213694 |
'config/base.yml', |
87aa59af |
],
},
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: Information Technology',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Natural Language :: English',
'Operating System :: POSIX',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Topic :: System :: Installation/Setup',
'Topic :: System :: Systems Administration',
'Topic :: Utilities',
],
scripts=[
'bin/ansible',
'bin/ansible-playbook',
'bin/ansible-pull',
'bin/ansible-doc',
'bin/ansible-galaxy',
'bin/ansible-console',
'bin/ansible-connection',
'bin/ansible-vault',
],
data_files=[], |
e4cd8993 |
extras_require=extra_requirements |
2c873a44 |
) |