summaryrefslogtreecommitdiffstats
path: root/packaging
diff options
context:
space:
mode:
Diffstat (limited to 'packaging')
-rw-r--r--packaging/arch/README.md8
-rw-r--r--packaging/debian/Dockerfile20
-rw-r--r--packaging/debian/README.md39
-rw-r--r--packaging/debian/ansible-base.dirs4
-rw-r--r--packaging/debian/ansible-base.install15
-rw-r--r--packaging/debian/ansible-test.install2
-rw-r--r--packaging/debian/changelog5
-rw-r--r--packaging/debian/compat1
-rw-r--r--packaging/debian/control29
-rw-r--r--packaging/debian/copyright26
-rw-r--r--packaging/debian/docs1
-rw-r--r--packaging/debian/pycompat1
-rwxr-xr-xpackaging/debian/rules17
-rw-r--r--packaging/gentoo/README.md3
-rw-r--r--packaging/macports/.gitignore2
-rw-r--r--packaging/macports/README.md39
-rw-r--r--packaging/macports/sysutils/ansible/Portfile67
-rw-r--r--packaging/release/Makefile61
-rw-r--r--packaging/release/tests/__init__.py0
-rw-r--r--packaging/release/tests/version_helper_test.py47
-rw-r--r--packaging/release/versionhelper/__init__.py0
-rw-r--r--packaging/release/versionhelper/version_helper.py195
-rwxr-xr-xpackaging/sdist/check-link-behavior.py51
23 files changed, 633 insertions, 0 deletions
diff --git a/packaging/arch/README.md b/packaging/arch/README.md
new file mode 100644
index 00000000..994daca7
--- /dev/null
+++ b/packaging/arch/README.md
@@ -0,0 +1,8 @@
+Arch Packaging Files
+--------------------
+
+You can find the source files for [ansible-git][1] in the [Arch User Repository][2] and for the stable version [ansible][3] you can do so in \[community\].
+
+ [1]: https://aur.archlinux.org/packages/ansible-git/
+ [2]: https://wiki.archlinux.org/index.php/Arch_User_Repository
+ [3]: https://www.archlinux.org/packages/community/any/ansible/
diff --git a/packaging/debian/Dockerfile b/packaging/debian/Dockerfile
new file mode 100644
index 00000000..de831d09
--- /dev/null
+++ b/packaging/debian/Dockerfile
@@ -0,0 +1,20 @@
+FROM ubuntu:xenial
+
+RUN apt-get update && apt-get install -y \
+ python-docutils \
+ cdbs \
+ debootstrap \
+ devscripts \
+ make \
+ pbuilder \
+ python-jinja2 \
+ python-setuptools \
+ python-yaml \
+ && \
+ apt-get clean
+
+VOLUME /ansible
+WORKDIR /ansible
+
+ENTRYPOINT ["/bin/bash", "-c"]
+CMD ["make deb"]
diff --git a/packaging/debian/README.md b/packaging/debian/README.md
new file mode 100644
index 00000000..7eaa4721
--- /dev/null
+++ b/packaging/debian/README.md
@@ -0,0 +1,39 @@
+Ansible Debian Package
+======================
+
+To create an Ansible DEB package:
+
+__Note__: You must run this target as root or set `PBUILDER_BIN='sudo pbuilder'`
+
+```
+apt-get install python-docutils cdbs debootstrap devscripts make pbuilder python-setuptools
+git clone https://github.com/ansible/ansible.git
+cd ansible
+DEB_DIST='xenial trusty precise' make deb
+```
+
+Building in Docker:
+
+```
+git clone https://github.com/ansible/ansible.git
+cd ansible
+docker build -t ansible-deb-builder -f packaging/debian/Dockerfile .
+docker run --privileged -e DEB_DIST='trusty' -v $(pwd):/ansible ansible-deb-builder
+```
+
+The debian package file will be placed in the `deb-build` directory. This can then be added to an APT repository or installed with `dpkg -i <package-file>`.
+
+Note that `dpkg -i` does not resolve dependencies.
+
+To install the Ansible DEB package and resolve dependencies:
+
+```
+dpkg -i <package-file>
+apt-get -fy install
+```
+
+Or, if you are running Debian Stretch (or later) or Ubuntu Xenial (or later):
+
+```
+apt install /path/to/<package-file>
+```
diff --git a/packaging/debian/ansible-base.dirs b/packaging/debian/ansible-base.dirs
new file mode 100644
index 00000000..fba15a43
--- /dev/null
+++ b/packaging/debian/ansible-base.dirs
@@ -0,0 +1,4 @@
+etc/ansible
+etc/ansible/roles
+usr/lib/python3/dist-packages/ansible
+usr/share/ansible
diff --git a/packaging/debian/ansible-base.install b/packaging/debian/ansible-base.install
new file mode 100644
index 00000000..d2dac7c1
--- /dev/null
+++ b/packaging/debian/ansible-base.install
@@ -0,0 +1,15 @@
+examples/hosts etc/ansible
+docs/man/man1/*.1 usr/share/man/man1
+debian/tmp/usr/bin/ansible-galaxy usr/bin
+debian/tmp/usr/bin/ansible-vault usr/bin
+debian/tmp/usr/bin/ansible-doc usr/bin
+debian/tmp/usr/bin/ansible-console usr/bin
+debian/tmp/usr/bin/ansible-connection usr/bin
+debian/tmp/usr/bin/ansible-inventory usr/bin
+debian/tmp/usr/bin/ansible-config usr/bin
+debian/tmp/usr/bin/ansible-pull usr/bin
+debian/tmp/usr/bin/ansible-playbook usr/bin
+debian/tmp/usr/bin/ansible usr/bin
+examples/ansible.cfg etc/ansible
+debian/tmp/usr/lib/python3/dist-packages/ansible usr/lib/python3/dist-packages
+debian/tmp/usr/lib/python3/dist-packages/ansible_*.egg-info
diff --git a/packaging/debian/ansible-test.install b/packaging/debian/ansible-test.install
new file mode 100644
index 00000000..92528905
--- /dev/null
+++ b/packaging/debian/ansible-test.install
@@ -0,0 +1,2 @@
+debian/tmp/usr/bin/ansible-test usr/bin
+debian/tmp/usr/lib/python3/dist-packages/ansible_test usr/lib/python3/dist-packages
diff --git a/packaging/debian/changelog b/packaging/debian/changelog
new file mode 100644
index 00000000..0eb840ce
--- /dev/null
+++ b/packaging/debian/changelog
@@ -0,0 +1,5 @@
+ansible-base (%VERSION%-%RELEASE%~%DIST%) %DIST%; urgency=low
+
+ * %VERSION% release
+
+ -- Ansible, Inc. <info@ansible.com> %DATE%
diff --git a/packaging/debian/compat b/packaging/debian/compat
new file mode 100644
index 00000000..7ed6ff82
--- /dev/null
+++ b/packaging/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/packaging/debian/control b/packaging/debian/control
new file mode 100644
index 00000000..71380057
--- /dev/null
+++ b/packaging/debian/control
@@ -0,0 +1,29 @@
+Source: ansible-base
+Section: admin
+Priority: optional
+Standards-Version: 3.9.3
+Maintainer: Ansible, Inc. <info@ansible.com>
+Build-Depends: cdbs, debhelper (>= 5.0.0), python3-docutils, python3, dh-python | python-support, python3-setuptools, lsb-release, python3-straight.plugin, python3-packaging, python3-jinja2
+Homepage: https://github.com/ansible/ansible/
+
+Package: ansible-base
+Architecture: all
+Depends: python3-jinja2, python3-yaml, python3-paramiko, python3-cryptography, sshpass, ${misc:Depends}, ${python:Depends}
+Description: Ansible IT Automation
+ Ansible is a radically simple model-driven configuration management,
+ multi-node deployment, and remote task execution system. Ansible works
+ over SSH and does not require any software or daemons to be installed
+ on remote nodes. Extension modules can be written in any language and
+ are transferred to managed machines automatically.
+
+Package: ansible-test
+Architecture: all
+Depends: ansible-base (= ${binary:Version}), python3-venv, ${misc:Depends}
+Description: Ansible IT Automation
+ Ansible is a radically simple model-driven configuration management,
+ multi-node deployment, and remote task execution system. Ansible works
+ over SSH and does not require any software or daemons to be installed
+ on remote nodes. Extension modules can be written in any language and
+ are transferred to managed machines automatically.
+ This package installs the ansible-test command for testing modules and
+ plugins developed for ansible.
diff --git a/packaging/debian/copyright b/packaging/debian/copyright
new file mode 100644
index 00000000..4a17425f
--- /dev/null
+++ b/packaging/debian/copyright
@@ -0,0 +1,26 @@
+This package was debianized by Henry Graham (hzgraham) <Henry.Graham@mail.wvu.edu> on
+Tue, 17 Apr 2012 12:19:47 -0400.
+
+It was downloaded from https://github.com/ansible/ansible.git
+
+Copyright: Henry Graham (hzgraham) <Henry.Graham@mail.wvu.edu>
+
+License:
+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
diff --git a/packaging/debian/docs b/packaging/debian/docs
new file mode 100644
index 00000000..a1320b1b
--- /dev/null
+++ b/packaging/debian/docs
@@ -0,0 +1 @@
+README.rst
diff --git a/packaging/debian/pycompat b/packaging/debian/pycompat
new file mode 100644
index 00000000..0cfbf088
--- /dev/null
+++ b/packaging/debian/pycompat
@@ -0,0 +1 @@
+2
diff --git a/packaging/debian/rules b/packaging/debian/rules
new file mode 100755
index 00000000..cd1e9534
--- /dev/null
+++ b/packaging/debian/rules
@@ -0,0 +1,17 @@
+#!/usr/bin/make -f
+# -- makefile --
+
+DEB_PYTHON3_MODULE_PACKAGES=ansible-base ansible_test
+#DEB_PYTHON_INSTALL_ARGS_ALL="--install-purelib=/usr/lib/python2.7/site-packages/"
+DEB_PYTHON_DISTUTILS_INSTALLDIR_SKEL = /usr/lib/python3/dist-packages/
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/python-distutils.mk
+
+# dist-packages for the modern distro, site-packages for the older (e.g: Ubuntu 14.04)
+ifeq ($(shell lsb_release -cs), precise)
+ export ANSIBLE_CRYPTO_BACKEND = pycrypto
+endif
+ifeq ($(shell lsb_release -cs), trusty)
+ export ANSIBLE_CRYPTO_BACKEND = pycrypto
+endif
diff --git a/packaging/gentoo/README.md b/packaging/gentoo/README.md
new file mode 100644
index 00000000..991692c9
--- /dev/null
+++ b/packaging/gentoo/README.md
@@ -0,0 +1,3 @@
+Gentoo ebuilds are available in the main tree:
+
+emerge ansible
diff --git a/packaging/macports/.gitignore b/packaging/macports/.gitignore
new file mode 100644
index 00000000..2af97a6f
--- /dev/null
+++ b/packaging/macports/.gitignore
@@ -0,0 +1,2 @@
+PortIndex
+PortIndex.quick
diff --git a/packaging/macports/README.md b/packaging/macports/README.md
new file mode 100644
index 00000000..7984a96c
--- /dev/null
+++ b/packaging/macports/README.md
@@ -0,0 +1,39 @@
+This portfile installs ansible from the git repository, it will install the
+latest and greatest version of ansible. This portfile does not install the
+required dependencies to run in accelerated mode.
+
+## Installing the stable version of ansible via macports
+
+If you wish to run a stable version of ansible please do the following
+
+First update your macports repo to the latest versions
+
+ $ sudo port sync
+
+Then install ansible
+
+ $ sudo port install ansible
+
+## Installing the devel version of ansible via macports
+
+To use this Portfile to install the development version of ansible one should
+follow the instructions at
+<http://guide.macports.org/#development.local-repositories>
+
+The basic idea is to add the _ansible/packaging/macports_ directory to your
+_/opt/local/etc/macports/sources.conf_ file. You should have something similar
+to this at the end of the file
+
+ file:///Users/jtang/develop/ansible/packaging/macports
+ rsync://rsync.macports.org/release/tarballs/ports.tar [default]
+
+In the _ansible/packaging/macports_ directory, do this
+
+ $ portindex
+
+Once the index is created the _Portfile_ will override the one in the upstream
+macports repository.
+
+Installing newer development versions should involve an uninstall, clean,
+install process or else the Portfile will need its version number/epoch
+bumped.
diff --git a/packaging/macports/sysutils/ansible/Portfile b/packaging/macports/sysutils/ansible/Portfile
new file mode 100644
index 00000000..9a386d77
--- /dev/null
+++ b/packaging/macports/sysutils/ansible/Portfile
@@ -0,0 +1,67 @@
+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
+# $Id: Portfile 102428 2013-02-02 18:34:49Z blair@macports.org $
+
+PortSystem 1.0
+PortGroup python 1.0
+
+name ansible
+version devel
+categories sysutils
+supported_archs noarch
+
+maintainers nomaintainer
+
+homepage https://ansible.com/
+description Ansible IT Automation
+long_description \
+ Ansible is a radically simple model-driven configuration \
+ management, multi-node deployment, and orchestration \
+ engine. Ansible works over SSH and does not require any software \
+ or daemons to be installed on remote nodes. Extension modules can \
+ be written in any language and are transferred to managed machines \
+ automatically.
+
+license GPL-3+
+
+platforms darwin
+
+fetch.type git
+git.url https://github.com/ansible/ansible.git
+git.branch ${version}
+
+python.default_version 27
+depends_lib-append port:py${python.version}-jinja2 \
+ port:py${python.version}-paramiko \
+ port:py${python.version}-yaml
+
+patch {
+ fs-traverse f ${worksrcpath} {
+ if {[file isfile ${f}]} {
+ reinplace -locale C "s#/etc/ansible#${prefix}/etc/ansible#g" ${f}
+ reinplace -locale C "s#/usr/share/ansible#${prefix}/share/ansible#g" ${f}
+ }
+ }
+}
+
+post-destroot {
+ # documentation and examples
+ xinstall -m 644 -W ${worksrcpath} README.rst CHANGELOG.md CONTRIBUTING.md COPYING \
+ ${destroot}${prefix}/share/doc/${name}
+
+ xinstall -m 755 -d ${destroot}${prefix}/share/doc/examples
+ xinstall -m 755 ${worksrcpath}/examples/ansible.cfg ${destroot}${prefix}/share/doc/${name}/examples
+ xinstall -m 755 ${worksrcpath}/examples/hosts ${destroot}${prefix}/share/doc/${name}/examples
+
+ file copy ${worksrcpath}/examples/playbooks ${destroot}${prefix}/share/doc/${name}/examples/
+
+ # man pages
+ xinstall -d 644 ${destroot}${prefix}/share/man/man1
+ eval xinstall -m 755 [glob ${worksrcpath}/docs/man/man1/*.1] ${destroot}${prefix}/share/man/man1
+
+ # install sample config and hosts file
+ xinstall -m 755 -d ${destroot}${prefix}/etc/ansible
+ xinstall -m 755 ${worksrcpath}/examples/ansible.cfg ${destroot}${prefix}/etc/ansible/ansible.cfg
+ xinstall -m 755 ${worksrcpath}/examples/hosts ${destroot}${prefix}/etc/ansible/hosts
+}
+
+python.link_binaries_suffix
diff --git a/packaging/release/Makefile b/packaging/release/Makefile
new file mode 100644
index 00000000..d1ff8f88
--- /dev/null
+++ b/packaging/release/Makefile
@@ -0,0 +1,61 @@
+version ?= $(shell python versionhelper/version_helper.py --raw)
+
+.PHONY: all
+all:
+ @echo "USAGE:"
+ @echo
+ @echo "make release version={version} # current version is '${version}'"
+ @echo "make publish"
+ @echo
+ @echo "NOTE: Make sure to source hacking/env-setup before running these targets."
+
+.PHONY: release
+release: version summary changelog commit-release
+ git show -p
+ git status
+ @echo
+ @echo 'Run `git push` if you are satisfied with the changes.'
+
+.PHONY: version
+version:
+ sed -i.bak "s/^__version__ = .*$$/__version__ = '${version}'/" ../../lib/ansible/release.py
+ rm ../../lib/ansible/release.py.bak
+
+.PHONY: summary
+summary:
+ @printf '%s\n%s\n%s\n' \
+ 'release_summary: |' \
+ ' | Release Date: $(shell date '+%Y-%m-%d')' \
+ ' | `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__' > \
+ ../../changelogs/fragments/v${version}_summary.yaml
+
+.PHONY: changelog
+changelog:
+ antsibull-changelog release -vv --use-ansible-doc && antsibull-changelog generate -vv --use-ansible-doc
+ ansible-test sanity changelogs/
+
+.PHONY: commit-release
+commit-release:
+ git add ../../changelogs/ ../../lib/ansible/release.py
+ git commit -m "New release v${version}"
+
+.PHONY: publish
+publish: tag postversion commit-postversion
+ git show -p
+ git status
+ @echo
+ @echo 'Run `git push --follow-tags` if you are satisfied with the changes.'
+
+.PHONY: tag
+tag:
+ git tag -a v${version} -m "New release v${version}"
+
+.PHONY: postversion
+postversion:
+ sed -i.bak "s/^__version__ = .*$$/__version__ = '${version}.post0'/" ../../lib/ansible/release.py
+ rm ../../lib/ansible/release.py.bak
+
+.PHONY: commit-postversion
+commit-postversion:
+ git add ../../lib/ansible/release.py
+ git commit -m "Update Ansible release version to v${version}."
diff --git a/packaging/release/tests/__init__.py b/packaging/release/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/packaging/release/tests/__init__.py
diff --git a/packaging/release/tests/version_helper_test.py b/packaging/release/tests/version_helper_test.py
new file mode 100644
index 00000000..ff14bd4d
--- /dev/null
+++ b/packaging/release/tests/version_helper_test.py
@@ -0,0 +1,47 @@
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import pytest
+
+from packaging.version import InvalidVersion
+from versionhelper.version_helper import AnsibleVersionMunger
+
+
+@pytest.mark.parametrize('version,revision,codename,output_propname,expected', [
+ ('2.5.0.dev1', None, None, 'raw', '2.5.0.dev1'),
+ ('2.5.0a0.post0', None, None, 'raw', '2.5.0a0.post0'),
+ ('2.5.0', None, None, 'raw', '2.5.0'),
+ ('2.5.0.dev1', None, None, 'major_version', '2.5'),
+ ('2.5.0', None, None, 'major_version', '2.5'),
+ ('2.5.0.dev1', None, None, 'base_version', '2.5.0'),
+ ('2.5.0', None, None, 'base_version', '2.5.0'),
+ ('2.5.0.dev1', None, None, 'deb_version', '2.5.0~dev1'),
+ ('2.5.0b1', None, None, 'deb_version', '2.5.0~b1'),
+ ('2.5.0b1.dev1', None, None, 'deb_version', '2.5.0~b1~dev1'),
+ ('2.5.0b1.post0', None, None, 'deb_version', '2.5.0~b1~post0'),
+ ('2.5.0', None, None, 'deb_version', '2.5.0'),
+ ('2.5.0.dev1', None, None, 'deb_release', '1'),
+ ('2.5.0b1', 2, None, 'deb_release', '2'),
+ ('2.5.0.dev1', None, None, 'rpm_release', '0.1.dev1'),
+ ('2.5.0a1', None, None, 'rpm_release', '0.101.a1'),
+ ('2.5.0a1.post0', None, None, 'rpm_release', '0.101.a1.post0'),
+ ('2.5.0b1', None, None, 'rpm_release', '0.201.b1'),
+ ('2.5.0rc1', None, None, 'rpm_release', '0.1001.rc1'),
+ ('2.5.0rc1', '0.99', None, 'rpm_release', '0.99.rc1'),
+ ('2.5.0.rc.1', None, None, 'rpm_release', '0.1001.rc.1'),
+ ('2.5.0.rc1.dev1', None, None, 'rpm_release', '0.1001.rc1.dev1'),
+ ('2.5.0', None, None, 'rpm_release', '1'),
+ ('2.5.0', 2, None, 'rpm_release', '2'),
+ ('2.5.0', None, None, 'codename', 'UNKNOWN'),
+ ('2.5.0', None, 'LedZeppelinSongHere', 'codename', 'LedZeppelinSongHere'),
+ ('2.5.0x1', None, None, None, InvalidVersion)
+])
+def test_output_values(version, revision, codename, output_propname, expected):
+ try:
+ v = AnsibleVersionMunger(version, revision, codename)
+ assert getattr(v, output_propname) == expected
+ except Exception as ex:
+ if isinstance(expected, type):
+ assert isinstance(ex, expected)
+ else:
+ raise
diff --git a/packaging/release/versionhelper/__init__.py b/packaging/release/versionhelper/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/packaging/release/versionhelper/__init__.py
diff --git a/packaging/release/versionhelper/version_helper.py b/packaging/release/versionhelper/version_helper.py
new file mode 100644
index 00000000..163494b6
--- /dev/null
+++ b/packaging/release/versionhelper/version_helper.py
@@ -0,0 +1,195 @@
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import argparse
+import os
+import re
+import sys
+
+from packaging.version import Version, VERSION_PATTERN
+
+
+class AnsibleVersionMunger(object):
+ tag_offsets = dict(
+ dev=0,
+ a=100,
+ b=200,
+ rc=1000
+ )
+
+ # TODO: allow overrides here for packaging bump etc
+ def __init__(self, raw_version, revision=None, codename=None):
+ self._raw_version = raw_version
+ self._revision = revision
+ self._parsed_version = Version(raw_version)
+ self._codename = codename
+ self._parsed_regex_match = re.match(VERSION_PATTERN, raw_version, re.VERBOSE | re.IGNORECASE)
+
+ @property
+ def deb_version(self):
+ v = self._parsed_version
+
+ match = self._parsed_regex_match
+
+ # treat dev/post as prerelease for now; treat dev/post as equivalent and disallow together
+ if v.is_prerelease or match.group('dev') or match.group('post'):
+ if match.group('dev') and match.group('post'):
+ raise Exception("dev and post may not currently be used together")
+ if match.group('pre'):
+ tag_value = match.group('pre')
+ tag_type = match.group('pre_l')
+ if match.group('dev'):
+ tag_value += ('~%s' % match.group('dev').strip('.'))
+ if match.group('post'):
+ tag_value += ('~%s' % match.group('post').strip('.'))
+ elif match.group('dev'):
+ tag_type = "dev"
+ tag_value = match.group('dev').strip('.')
+ elif match.group('post'):
+ tag_type = "dev"
+ tag_value = match.group('post').strip('.')
+ else:
+ raise Exception("unknown prerelease type for version {0}".format(self._raw_version))
+ else:
+ tag_type = None
+ tag_value = ''
+
+ # not a pre/post/dev release, just return base version
+ if not tag_type:
+ return '{base_version}'.format(base_version=self.base_version)
+
+ # it is a pre/dev release, include the tag value with a ~
+ return '{base_version}~{tag_value}'.format(base_version=self.base_version, tag_value=tag_value)
+
+ @property
+ def deb_release(self):
+ return '1' if self._revision is None else str(self._revision)
+
+ @property
+ def rpm_release(self):
+ v = self._parsed_version
+ match = self._parsed_regex_match
+
+ # treat presence of dev/post as prerelease for now; treat dev/post the same and disallow together
+ if v.is_prerelease or match.group('dev') or match.group('post'):
+ if match.group('dev') and match.group('post'):
+ raise Exception("dev and post may not currently be used together")
+ if match.group('pre'):
+ tag_value = match.group('pre')
+ tag_type = match.group('pre_l')
+ tag_ver = match.group('pre_n')
+ if match.group('dev'):
+ tag_value += match.group('dev')
+ if match.group('post'):
+ tag_value += match.group('post')
+ elif match.group('dev'):
+ tag_type = "dev"
+ tag_value = match.group('dev')
+ tag_ver = match.group('dev_n')
+ elif match.group('post'):
+ tag_type = "dev"
+ tag_value = match.group('post')
+ tag_ver = match.group('post_n')
+ else:
+ raise Exception("unknown prerelease type for version {0}".format(self._raw_version))
+ else:
+ tag_type = None
+ tag_value = ''
+ tag_ver = 0
+
+ # not a pre/post/dev release, just append revision (default 1)
+ if not tag_type:
+ if self._revision is None:
+ self._revision = 1
+ return '{revision}'.format(revision=self._revision)
+
+ # cleanse tag value in case it starts with .
+ tag_value = tag_value.strip('.')
+
+ # coerce to int and None == 0
+ tag_ver = int(tag_ver if tag_ver else 0)
+
+ if self._revision is None:
+ tag_offset = self.tag_offsets.get(tag_type)
+ if tag_offset is None:
+ raise Exception('no tag offset defined for tag {0}'.format(tag_type))
+ pkgrel = '0.{0}'.format(tag_offset + tag_ver)
+ else:
+ pkgrel = self._revision
+
+ return '{pkgrel}.{tag_value}'.format(pkgrel=pkgrel, tag_value=tag_value)
+
+ @property
+ def raw(self):
+ return self._raw_version
+
+ # return the x.y.z version without any other modifiers present
+ @property
+ def base_version(self):
+ return self._parsed_version.base_version
+
+ # return the x.y version without any other modifiers present
+ @property
+ def major_version(self):
+ return re.match(r'^(\d+.\d+)', self._raw_version).group(1)
+
+ @property
+ def codename(self):
+ return self._codename if self._codename else "UNKNOWN"
+
+
+def main():
+ parser = argparse.ArgumentParser(description='Extract/transform Ansible versions to various packaging formats')
+
+ group = parser.add_mutually_exclusive_group(required=True)
+ group.add_argument('--raw', action='store_true')
+ group.add_argument('--majorversion', action='store_true')
+ group.add_argument('--baseversion', action='store_true')
+ group.add_argument('--debversion', action='store_true')
+ group.add_argument('--debrelease', action='store_true')
+ group.add_argument('--rpmrelease', action='store_true')
+ group.add_argument('--codename', action='store_true')
+ group.add_argument('--all', action='store_true')
+
+ parser.add_argument('--revision', action='store', default='auto')
+
+ args = parser.parse_args()
+
+ mydir = os.path.dirname(__file__)
+ release_loc = os.path.normpath(mydir + '/../../../lib')
+
+ sys.path.insert(0, release_loc)
+
+ from ansible import release
+
+ rev = None
+ if args.revision != 'auto':
+ rev = args.revision
+
+ v_raw = release.__version__
+ codename = release.__codename__
+ v = AnsibleVersionMunger(v_raw, revision=rev, codename=codename)
+
+ if args.raw:
+ print(v.raw)
+ elif args.baseversion:
+ print(v.base_version)
+ elif args.majorversion:
+ print(v.major_version)
+ elif args.debversion:
+ print(v.deb_version)
+ elif args.debrelease:
+ print(v.deb_release)
+ elif args.rpmrelease:
+ print(v.rpm_release)
+ elif args.codename:
+ print(v.codename)
+ elif args.all:
+ props = [name for (name, impl) in vars(AnsibleVersionMunger).items() if isinstance(impl, property)]
+
+ for propname in props:
+ print('{0}: {1}'.format(propname, getattr(v, propname)))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/packaging/sdist/check-link-behavior.py b/packaging/sdist/check-link-behavior.py
new file mode 100755
index 00000000..34e05023
--- /dev/null
+++ b/packaging/sdist/check-link-behavior.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+"""Checks for link behavior required for sdist to retain symlinks."""
+
+from __future__ import (absolute_import, division, print_function)
+
+__metaclass__ = type
+
+import os
+import platform
+import shutil
+import sys
+import tempfile
+
+
+def main():
+ """Main program entry point."""
+ temp_dir = tempfile.mkdtemp()
+
+ target_path = os.path.join(temp_dir, 'file.txt')
+ symlink_path = os.path.join(temp_dir, 'symlink.txt')
+ hardlink_path = os.path.join(temp_dir, 'hardlink.txt')
+
+ try:
+ with open(target_path, 'w'):
+ pass
+
+ os.symlink(target_path, symlink_path)
+ os.link(symlink_path, hardlink_path)
+
+ if not os.path.islink(symlink_path):
+ abort('Symbolic link not created.')
+
+ if not os.path.islink(hardlink_path):
+ # known issue on MacOS (Darwin)
+ abort('Hard link of symbolic link created as a regular file.')
+ finally:
+ shutil.rmtree(temp_dir)
+
+
+def abort(reason):
+ """
+ :type reason: str
+ """
+ sys.exit('ERROR: %s\n'
+ 'This will prevent symbolic links from being preserved in the resulting tarball.\n'
+ 'Aborting creation of sdist on platform: %s'
+ % (reason, platform.system()))
+
+
+if __name__ == '__main__':
+ main()