You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by fo...@apache.org on 2019/05/31 17:43:48 UTC
[avro] branch master updated: AVRO-2391 Refactor Py3 Setup (#514)
This is an automated email from the ASF dual-hosted git repository.
fokko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new f33e36f AVRO-2391 Refactor Py3 Setup (#514)
f33e36f is described below
commit f33e36f70f5f149b38b9056273f584184591c23f
Author: Michael A. Smith <mi...@smith-li.com>
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} | 55 +---------
lang/py3/build.sh | 56 +++-------
lang/py3/setup.cfg | 65 ++++++++++++
lang/py3/setup.py | 209 +++++++++++++++----------------------
4 files changed, 171 insertions(+), 214 deletions(-)
diff --git a/lang/py3/build.sh b/lang/py3/MANIFEST.in
old mode 100755
new mode 100644
similarity index 54%
copy from lang/py3/build.sh
copy to lang/py3/MANIFEST.in
index fdb457a..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.
@@ -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 fdb457a..e443985 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 = dev@avro.apache.org
+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 1b31223..6eb6e2e 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 = 'dev@avro.apache.org',
- 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()