File: setup.py

package info (click to toggle)
python-avro 1.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,624 kB
  • sloc: python: 11,437; xml: 4,061; sh: 752; java: 386; makefile: 21
file content (171 lines) | stat: -rwxr-xr-x 5,699 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python
# -*- mode: python -*-
# -*- coding: utf-8 -*-

# 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
#
#     https://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.

"""
Provide the code necessary for packaging and installing avro-python3.

The avro-python3 software is designed for Python 3, but this file and the packaging software supports Python 2.7.

https://pypi.org/project/avro-python3/
"""

import distutils.command.clean
import distutils.dir_util
import distutils.errors
import distutils.file_util
import distutils.log
import fnmatch
import glob
import os
import subprocess

import setuptools

_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)


class GenerateInteropDataCommand(setuptools.Command):
    """A command to generate Avro files for data interop test."""

    user_options = [
      ('schema-file=', None, 'path to input Avro schema file'),
      ('output-path=', None, 'path to output Avro data files'),
    ]

    def initialize_options(self):
        self.schema_file = os.path.join(os.getcwd(), 'interop.avsc')
        self.output_path = os.getcwd()

    def finalize_options(self):
        pass

    def run(self):
        from avro.tests import gen_interop_data
        gen_interop_data.generate(self.schema_file, self.output_path)


class LintCommand(setuptools.Command):
    """Run pycodestyle on all your modules"""
    description = __doc__
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        # setuptools does not seem to make pycodestyle available
        # in the pythonpath, so we do it ourselves.
        try:
            env = {'PYTHONPATH': next(glob.iglob('.eggs/pycodestyle-*.egg'))}
        except StopIteration:
            env = None  # pycodestyle is already installed
        try:
            subprocess.run(['python3', '-m', 'pycodestyle', '.'], env=env, check=True)
        except subprocess.CalledProcessError:
            raise distutils.errors.DistutilsError("pycodestyle exited with a nonzero exit code.")


def main():
    if not _is_distribution():
        _generate_package_data()

    setuptools.setup(cmdclass={
        "clean": CleanCommand,
        "generate_interop_data": GenerateInteropDataCommand,
    })


if __name__ == '__main__':
    main()