This is an automated email from the ASF dual-hosted git repository. rskraba pushed a commit to branch branch-1.9 in repository https://gitbox.apache.org/repos/asf/avro.git
commit 6216bba7ae58badd0c6fc835cff312af357981ae Author: Michael A. Smith <[email protected]> AuthorDate: Fri May 31 13:43:42 2019 -0400 AVRO-2391 Refactor Py3 Setup (#514) The main purpose of this change is to simplify and modernize the setup code without really changing its behavior. The main change is that I moved most of the setup code into the declarative setup.cfg, where I hope it is somewhat clearer. I also fleshed out the setup.py commands so that the build.sh and setup.py have parity -- that is, the build.sh is entirely implemented using setup.py. --- lang/py3/{build.sh => MANIFEST.in} | 57 ++-------- lang/py3/build.sh | 56 +++------- lang/py3/setup.cfg | 65 ++++++++++++ lang/py3/setup.py | 209 +++++++++++++++---------------------- 4 files changed, 172 insertions(+), 215 deletions(-) diff --git a/lang/py3/build.sh b/lang/py3/MANIFEST.in old mode 100755 new mode 100644 similarity index 51% copy from lang/py3/build.sh copy to lang/py3/MANIFEST.in index d28f8cb..acdbd3b --- a/lang/py3/build.sh +++ b/lang/py3/MANIFEST.in @@ -1,5 +1,3 @@ -#!/bin/bash - # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. @@ -7,7 +5,7 @@ # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -15,51 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e # exit on error - -function usage { - echo "Usage: $0 {test|dist|clean}" - exit 1 -} - -if [ $# -eq 0 ] -then - usage -fi - -if [ -f VERSION.txt ] -then - VERSION=`cat VERSION.txt` -else - VERSION=`cat ../../share/VERSION.txt` -fi - -for target in "$@" -do - -function do_clean(){ - python3 setup.py clean - rm -rvf dist avro_python3.egg-info avro/*.avsc avro/VERSION.txt avro/__pycache__/ avro/tests/interop.avsc avro/tests/__pycache__/ -} - -case "$target" in - test) - python3 setup.py test - ;; - - dist) - python3 setup.py sdist - cp -r dist ../../dist/py3 - ;; - - clean) - do_clean - ;; - - *) - usage -esac - -done - -exit 0 +include avro/HandshakeRequest.avsc +include avro/HandshakeResponse.avsc +include avro/VERSION.txt +include avro/LICENSE +include avro/NOTICE diff --git a/lang/py3/build.sh b/lang/py3/build.sh index d28f8cb..1bb27ad 100755 --- a/lang/py3/build.sh +++ b/lang/py3/build.sh @@ -17,49 +17,23 @@ set -e # exit on error -function usage { +usage() { echo "Usage: $0 {test|dist|clean}" - exit 1 } -if [ $# -eq 0 ] -then - usage -fi - -if [ -f VERSION.txt ] -then - VERSION=`cat VERSION.txt` -else - VERSION=`cat ../../share/VERSION.txt` -fi - -for target in "$@" -do - -function do_clean(){ - python3 setup.py clean - rm -rvf dist avro_python3.egg-info avro/*.avsc avro/VERSION.txt avro/__pycache__/ avro/tests/interop.avsc avro/tests/__pycache__/ -} - -case "$target" in - test) - python3 setup.py test - ;; - - dist) - python3 setup.py sdist - cp -r dist ../../dist/py3 - ;; - - clean) - do_clean - ;; - - *) +main() { + local target + if (( $# == 0 )); then usage -esac - -done + return 1 + fi + for target; do + case "$target" in + clean|dist|test) : ;; + *) usage; return 1 ;; + esac + done + python3 setup.py "$@" +} -exit 0 +main "$@" diff --git a/lang/py3/setup.cfg b/lang/py3/setup.cfg new file mode 100644 index 0000000..9d1f437 --- /dev/null +++ b/lang/py3/setup.cfg @@ -0,0 +1,65 @@ +## +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +## +# https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files +[metadata] +name = avro-python3 +version = file: avro/VERSION.txt +description = Avro is a serialization and RPC framework. +long_description = file: README.txt +keywords = + avro + serialization + rpc +author = Apache Avro +author_email = [email protected] +url = http://avro.apache.org/ +license = Apache License 2.0 +classifiers = + License :: OSI Approved :: Apache Software License + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +package_dir = + avro = avro +include_package_data = true +packages = avro +install_requires = +zip_safe = true +scripts = + scripts/avro +python_requires = >=3.4 +test_suite = avro.tests.run_tests + +[options.package_data] +avro = + HandshakeRequest.avsc + HandshakeResponse.avsc + VERSION.txt + LICENSE + NOTICE + +[options.extras_require] +snappy = snappy + +[aliases] +dist = sdist --dist-dir ../../dist/py3 diff --git a/lang/py3/setup.py b/lang/py3/setup.py index 5f44dd9..a752779 100755 --- a/lang/py3/setup.py +++ b/lang/py3/setup.py @@ -26,133 +26,96 @@ The avro-python3 software is designed for Python 3, but this file and the packag https://pypi.org/project/avro-python3/ """ - +import distutils.command.clean +import distutils.file_util +import distutils.dir_util +import distutils.log +import fnmatch import os -import shutil -import stat -import sys from setuptools import setup -VERSION_FILE_NAME = 'VERSION.txt' -LICENSE_FILE_NAME = 'LICENSE' -NOTICE_FILE_NAME = 'NOTICE' - -def RunsFromSourceDist(): - """Tests whether setup.py is invoked from a source distribution. - - Returns: - True if setup.py runs from a source distribution. - False otherwise, ie. if setup.py runs from the SVN trunk. - """ - setup_file_path = os.path.abspath(__file__) - # If a file PKG-INFO exists as a sibling of setup.py, - # assume we are running as source distribution: - pkg_info_file_path = \ - os.path.join(os.path.dirname(setup_file_path), 'PKG-INFO') - return os.path.exists(pkg_info_file_path) - - -def SetupSources(): - """Prepares the source directory. - - Runs when setup.py is invoked from the Avro SVN/Git source. - """ - # Avro lang/py3/ source directory: - py3_dir = os.path.dirname(os.path.abspath(__file__)) - - # Avro top-level source directory: - root_dir = os.path.dirname(os.path.dirname(py3_dir)) - - # Read and copy Avro version: - version_file_path = os.path.join(root_dir, 'share', VERSION_FILE_NAME) - with open(version_file_path, 'r') as f: - avro_version = f.read().strip() - shutil.copy( - src=version_file_path, - dst=os.path.join(py3_dir, 'avro', VERSION_FILE_NAME), - ) - - # Copy necessary avsc files: - avsc_file_path = os.path.join( - root_dir, 'share', 'schemas', - 'org', 'apache', 'avro', 'ipc', 'HandshakeRequest.avsc') - shutil.copy( - src=avsc_file_path, - dst=os.path.join(py3_dir, 'avro', 'HandshakeRequest.avsc'), - ) - - avsc_file_path = os.path.join( - root_dir, 'share', 'schemas', - 'org', 'apache', 'avro', 'ipc', 'HandshakeResponse.avsc') - shutil.copy( - src=avsc_file_path, - dst=os.path.join(py3_dir, 'avro', 'HandshakeResponse.avsc'), - ) - - avsc_file_path = os.path.join( - root_dir, 'share', 'test', 'schemas', 'interop.avsc') - shutil.copy( - src=avsc_file_path, - dst=os.path.join(py3_dir, 'avro', 'tests', 'interop.avsc'), - ) - - -def ReadVersion(): - """Returns: the content of the Avro version file.""" - setup_file_path = os.path.abspath(__file__) - install_dir = os.path.dirname(setup_file_path) - version_file_path = os.path.join(install_dir, 'avro', VERSION_FILE_NAME) - with open(version_file_path, 'rt') as f: - avro_version = f.read().strip() - return avro_version - - -def Main(): - if not RunsFromSourceDist(): - SetupSources() - - avro_version = ReadVersion() - - setup( - name = 'avro-python3', - version = avro_version, - packages = ['avro'], - package_dir = {'avro': 'avro'}, - scripts = ['scripts/avro'], - - package_data = { - 'avro': [ - 'HandshakeRequest.avsc', - 'HandshakeResponse.avsc', - VERSION_FILE_NAME, - LICENSE_FILE_NAME, - NOTICE_FILE_NAME, - ], - }, - - test_suite='avro.tests.run_tests', - tests_require=[], - - # metadata for upload to PyPI - author = 'Apache Avro', - author_email = '[email protected]', - description = 'Avro is a serialization and RPC framework.', - license = 'Apache License 2.0', - keywords = 'avro serialization rpc', - url = 'http://avro.apache.org/', - classifiers=( - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - ), - python_requires='>=3.4', - ) +_HERE = os.path.dirname(os.path.abspath(__file__)) +_AVRO_DIR = os.path.join(_HERE, 'avro') +_VERSION_FILE_NAME = 'VERSION.txt' + +def _is_distribution(): + """Tests whether setup.py is invoked from a distribution. + + Returns: + True if setup.py runs from a distribution. + False otherwise, ie. if setup.py runs from a version control work tree. + """ + # If a file PKG-INFO exists as a sibling of setup.py, + # assume we are running as source distribution: + return os.path.exists(os.path.join(_HERE, 'PKG-INFO')) + + +def _generate_package_data(): + """Generate package data. + + This data will already exist in a distribution package, + so this function only runs for local version control work tree. + """ + distutils.log.info('Generating package data') + + # Avro top-level source directory: + root_dir = os.path.dirname(os.path.dirname(_HERE)) + + # Create a PEP440 compliant version file. + version_file_path = os.path.join(root_dir, 'share', _VERSION_FILE_NAME) + with open(version_file_path) as vin: + version = vin.read().replace('-', '+') + with open(os.path.join(_AVRO_DIR, _VERSION_FILE_NAME), 'w') as vout: + vout.write(version) + + # Copy necessary avsc files: + avsc_files = ( + (('schemas', 'org', 'apache', 'avro', 'ipc', 'HandshakeRequest.avsc'), ''), + (('schemas', 'org', 'apache', 'avro', 'ipc', 'HandshakeResponse.avsc'), ''), + (('test', 'schemas', 'interop.avsc'), ('tests',)), + ) + + for src, dst in avsc_files: + src = os.path.join(root_dir, 'share', *src) + dst = os.path.join(_AVRO_DIR, *dst) + distutils.file_util.copy_file(src, dst) + + +class CleanCommand(distutils.command.clean.clean): + """A command to clean up install artifacts and replaceable, generated files.""" + + def _replaceable(self): + """Get the list of files to delete.""" + for name in ('dist', 'avro_python3.egg-info', os.path.join(_AVRO_DIR, _VERSION_FILE_NAME)): + if os.path.exists(name): + yield name + for root, dirnames, filenames in os.walk(_AVRO_DIR): + if '__pycache__' in dirnames: + dirnames.remove('__pycache__') + yield os.path.join(root, '__pycache__') + for name in fnmatch.filter(filenames, '*.avsc'): + yield os.path.join(root, name) + + def run(self): + super().run() + for name in self._replaceable(): + if self.dry_run: + distutils.log.info('Would remove %s', name) + elif os.path.isdir(name): + # distutils logs this for us + distutils.dir_util.remove_tree(name) + else: + distutils.log.info('Removing %s', name) + os.remove(name) + + +def main(): + if not _is_distribution(): + _generate_package_data() + + setup(cmdclass={"clean": CleanCommand}) if __name__ == '__main__': - Main() + main()
