From 75a96dc9e647a454899ebdb9c5f26ef961a34b97 Mon Sep 17 00:00:00 2001 From: Matthew Balvanz Date: Tue, 4 Apr 2017 23:14:11 -0500 Subject: [PATCH] Package the Ruby Mock Service and Verifier - Build process now downloads and prepares the Ruby applications like the NPM based Pact - Resulting *.tar.gz now includes portable Ruby versions of Mock Service and Verifier - The platform appropriate version is unpacked when a user installs pact-python --- .gitignore | 1 + .travis.yml | 5 ++- MANIFEST.in | 2 + Makefile | 16 ++++++- scripts/build.sh | 111 +++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 66 ++++++++++++++++++++++++++++ 6 files changed, 198 insertions(+), 3 deletions(-) create mode 100755 scripts/build.sh diff --git a/.gitignore b/.gitignore index 1885062cb..9c62da2ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # pact-python specific ignores e2e/pacts +pact/bin # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/.travis.yml b/.travis.yml index 7edb7edab..98f6faa81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,7 @@ sudo: false install: pip install -r requirements_dev.txt -script: make test +script: + - flake8 + - pydocstyle pact + - tox --develop diff --git a/MANIFEST.in b/MANIFEST.in index e6b40904f..fc86ec227 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,6 @@ include LICENSE +include *.gz include *.txt include *.md prune *test +prune e2e/* diff --git a/Makefile b/Makefile index 066557038..1b64f26ff 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ endef help: @echo "" + @echo " clean to clear build and distribution directories" @echo " deps to install the required files for development" @echo " package to create a distribution package in /dist/" @echo " release to perform a release build, including deps, test, and package targets" @@ -21,6 +22,13 @@ help: release: deps test package +.PHONY: clean +clean: + rm -rf build + rm -rf dist + rm -rf pact/bin + + .PHONY: deps deps: pip install -r requirements_dev.txt @@ -42,13 +50,17 @@ e2e: docker-compose down' .PHONY: package -package: +package: pact/bin python setup.py sdist +pact/bin: + scripts/build.sh + + export VERSION_CHECK .PHONY: test -test: deps +test: deps pact/bin @echo "Checking version consistency..." python -c "$$VERSION_CHECK" diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 000000000..30552541f --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +set -e + + +build() { + echo "Building..." + pushd $(pwd) + mkdir -p build + cd build + if [ ! -d "${PROJECT_NAME}-${GEM_VERSION}" ]; then + wget https://github.com/${REPOSITORY}/archive/v${GEM_VERSION}.zip -O temp.zip + unzip temp.zip + rm temp.zip + fi + + cd ${PROJECT_NAME}-${GEM_VERSION} + + bundle + bundle exec rake package + popd +} + + +package() { + echo "Packaging $STANDALONE_PACKAGE_NAME.$EXTENSION for pypi as $PYPI_PACKAGE_NAME.$EXTENSION" + pushd $(pwd) + mkdir -p pact/bin + + cd build + cp ${PROJECT_NAME}-${GEM_VERSION}/pkg/${PROJECT_NAME//_/-}-* . + rm -rf $STANDALONE_PACKAGE_NAME + + if [ $EXTENSION = "zip" ]; then + unzip $STANDALONE_PACKAGE_NAME.$EXTENSION + else + tar -xzf $STANDALONE_PACKAGE_NAME.$EXTENSION + fi + + mv $STANDALONE_PACKAGE_NAME $PYPI_PACKAGE_NAME + cd $PYPI_PACKAGE_NAME + + tar -czf ../../pact/bin/${PYPI_PACKAGE_NAME}.tar.gz * + popd +} + + +echo "Packaging the Mock Service for distribution." +export GEM_VERSION=0.12.1 +export RELEASE_VERSION=1 +export PACKAGE_VERSION=${GEM_VERSION}-${RELEASE_VERSION} + +export PROJECT_NAME='pact-mock_service' +export REPOSITORY='bethesque/pact-mock_service' +build + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME//_/-}-${PACKAGE_VERSION}-win32" +export PYPI_PACKAGE_NAME="${PROJECT_NAME//_/-}-win32" +export SUFFIX='win32' +export EXTENSION='zip' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME//_/-}-${PACKAGE_VERSION}-osx" +export PYPI_PACKAGE_NAME="${PROJECT_NAME//_/-}-darwin" +export SUFFIX='osx' +export EXTENSION='tar.gz' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME//_/-}-${PACKAGE_VERSION}-linux-x86" +export PYPI_PACKAGE_NAME="${PROJECT_NAME//_/-}-ia32" +export SUFFIX='linux-x86' +export EXTENSION='tar.gz' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME//_/-}-${PACKAGE_VERSION}-linux-x86_64" +export PYPI_PACKAGE_NAME="${PROJECT_NAME//_/-}-linux-x64" +export SUFFIX='linux-x86_64' +export EXTENSION='tar.gz' +package + +echo "Packaging the Verifier for distribution." +export GEM_VERSION=0.0.13 +export RELEASE_VERSION=1 +export PACKAGE_VERSION=${GEM_VERSION}-${RELEASE_VERSION} +export PROJECT_NAME='pact-provider-verifier' +export REPOSITORY='pact-foundation/pact-provider-verifier' +build + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME}-${PACKAGE_VERSION}-win32" +export PYPI_PACKAGE_NAME="${PROJECT_NAME}-win32" +export SUFFIX='win32' +export EXTENSION='zip' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME}-${PACKAGE_VERSION}-osx" +export PYPI_PACKAGE_NAME="${PROJECT_NAME}-darwin" +export SUFFIX='osx' +export EXTENSION='tar.gz' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME}-${PACKAGE_VERSION}-linux-x86" +export PYPI_PACKAGE_NAME="${PROJECT_NAME}-linux-ia32" +export SUFFIX='linux-x86' +export EXTENSION='tar.gz' +package + +export STANDALONE_PACKAGE_NAME="${PROJECT_NAME}-${PACKAGE_VERSION}-linux-x86_64" +export PYPI_PACKAGE_NAME="${PROJECT_NAME}-linux-x64" +export SUFFIX='linux-x86_64' +export EXTENSION='tar.gz' +package diff --git a/setup.py b/setup.py index bfbc3b835..db2287bde 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,70 @@ """pact-python PyPI Package.""" import os +import platform +import sys +import tarfile + from setuptools import find_packages, setup +from setuptools.command.install import install + + +class PactPythonInstallCommand(install): + """ + Custom installer for pact-python. + + Installs the Python package and unpacks the platform appropriate version + of Python mock service. + """ + def run(self): + install.run(self) + bin_path = os.path.join(self.install_lib, 'pact', 'bin') + self.mock_service(bin_path) + self.verifier(bin_path) + + def mock_service(self, bin_path): + """Install the Ruby mock service for this platform.""" + is_64 = sys.maxsize > 2 ** 32 + target_platform = platform.platform().lower() + if 'darwin' in target_platform: + platform_tar = 'pact-mock-service-darwin.tar.gz' + elif 'linux' in target_platform and is_64: + platform_tar = 'pact-mock-service-linux-x64.tar.gz' + elif 'linux' in target_platform: + platform_tar = 'pact-mock-service-ia32.tar.gz' + elif 'windows' in target_platform: + platform_tar = 'pact-mock-service-win32.tar.gz' + else: + msg = ('Unfortunately, {} is not a supported platform. Only Linux,' + ' Windows, and OSX are currently supported.').format( + platform.platform()) + raise Exception(msg) + + self.announce(u'Extracting {} to {}'.format(platform_tar, bin_path)) + with tarfile.open(os.path.join(bin_path, platform_tar)) as f: + f.extractall(os.path.join(bin_path, 'mock-service')) + + def verifier(self, bin_path): + """Install the Ruby Pact Verifier for this platform.""" + is_64 = sys.maxsize > 2 ** 32 + target_platform = platform.platform().lower() + if 'darwin' in target_platform: + platform_tar = 'pact-provider-verifier-darwin.tar.gz' + elif 'linux' in target_platform and is_64: + platform_tar = 'pact-provider-verifier-linux-x64.tar.gz' + elif 'linux' in target_platform: + platform_tar = 'pact-provider-verifier-linux-ia32.tar.gz' + elif 'windows' in target_platform: + platform_tar = 'pact-provider-verifier-win32.tar.gz' + else: + msg = ('Unfortunately, {} is not a supported platform. Only Linux,' + ' Windows, and OSX are currently supported.').format( + platform.platform()) + raise Exception(msg) + + self.announce(u'Extracting {} to {}'.format(platform_tar, bin_path)) + with tarfile.open(os.path.join(bin_path, platform_tar)) as f: + f.extractall(os.path.join(bin_path, 'verifier')) def get_version(): @@ -21,6 +84,7 @@ def read(filename): dependencies = [ dep.strip() for dep in read('requirements.txt').split('\n') if dep.strip()] setup_args = dict( + cmdclass={'install': PactPythonInstallCommand}, name='pact-python', version=get_version(), description=('Tools for creating and verifying consumer driven contracts' @@ -31,6 +95,8 @@ def read(filename): url='https://github.com/pact-foundation/pact-python', install_requires=dependencies, packages=find_packages(exclude=['*.test', '*.test.*', 'test.*', 'test']), + package_data={'pact': ['bin/*']}, + package_dir={'pact': 'pact'}, license=read('LICENSE'))