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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#!/usr/bin/env python
"""setuptools module for contract_artifacts package."""
import subprocess # nosec
from shutil import rmtree
from os import environ, path
from sys import argv
from distutils.command.clean import clean
import distutils.command.build_py
from setuptools import find_packages, setup
class LintCommand(distutils.command.build_py.build_py):
"""Custom setuptools command class for running linters."""
description = "Run linters"
def run(self):
"""Run linter shell commands."""
lint_commands = [
# formatter:
"black --line-length 79 --check --diff src setup.py".split(),
# style guide checker (formerly pep8):
"pycodestyle --show-source --show-pep8 src setup.py".split(),
# docstring style checker:
"pydocstyle src setup.py".split(),
# static type checker:
"mypy src setup.py".split(),
# security issue checker:
"bandit -r src ./setup.py".split(),
# HACK: ensure contract artifacts match the authoritative copies:
# this is a hack. ideally we would symlink to the authoritative
# copies, but a problem with setuptools is preventing it from
# following symlinks when gathering package_data. see
# https://github.com/pypa/setuptools/issues/415.
(
"diff src/zero_ex/contract_artifacts/artifacts"
+ " ../../packages/contract-artifacts/artifacts"
).split(),
# general linter:
"pylint src setup.py".split(),
# pylint takes relatively long to run, so it runs last, to enable
# fast failures.
]
# tell mypy where to find interface stubs for 3rd party libs
environ["MYPYPATH"] = path.join(
path.dirname(path.realpath(argv[0])), "stubs"
)
for lint_command in lint_commands:
print(
"Running lint command `", " ".join(lint_command).strip(), "`"
)
subprocess.check_call(lint_command) # nosec
class CleanCommandExtension(clean):
"""Custom command to do custom cleanup."""
def run(self):
"""Run the regular clean, followed by our custom commands."""
super().run()
rmtree("dist", ignore_errors=True)
rmtree(".mypy_cache", ignore_errors=True)
rmtree(".tox", ignore_errors=True)
rmtree(".pytest_cache", ignore_errors=True)
rmtree("src/0x_contract_artifacts.egg-info", ignore_errors=True)
class TestPublishCommand(distutils.command.build_py.build_py):
"""Custom command to publish to test.pypi.org."""
description = (
"Publish dist/* to test.pypi.org. Run sdist & bdist_wheel first."
)
def run(self):
"""Run twine to upload to test.pypi.org."""
subprocess.check_call( # nosec
(
"twine upload --repository-url https://test.pypi.org/legacy/"
+ " --verbose dist/*"
).split()
)
class PublishCommand(distutils.command.build_py.build_py):
"""Custom command to publish to pypi.org."""
description = "Publish dist/* to pypi.org. Run sdist & bdist_wheel first."
def run(self):
"""Run twine to upload to pypi.org."""
subprocess.check_call("twine upload dist/*".split()) # nosec
class PublishDocsCommand(distutils.command.build_py.build_py):
"""Custom command to publish docs to S3."""
description = (
"Publish docs to "
+ "http://0x-contract-artifacts-py.s3-website-us-east-1.amazonaws.com/"
)
def run(self):
"""Run npm package `discharge` to build & upload docs."""
subprocess.check_call("discharge deploy".split()) # nosec
with open("README.md", "r") as file_handle:
README_MD = file_handle.read()
setup(
name="0x-contract-artifacts",
version="2.0.0",
description="0x smart contract compilation artifacts",
long_description=README_MD,
long_description_content_type="text/markdown",
url=(
"https://github.com/0xproject/0x-monorepo/tree/development"
+ "/python-packages/contract_artifacts"
),
author="F. Eugene Aumson",
author_email="feuGeneA@users.noreply.github.com",
cmdclass={
"clean": CleanCommandExtension,
"lint": LintCommand,
"test_publish": TestPublishCommand,
"publish": PublishCommand,
"publish_docs": PublishDocsCommand,
},
install_requires=["mypy_extensions"],
extras_require={
"dev": [
"bandit",
"black",
"coverage",
"coveralls",
"mypy",
"mypy_extensions",
"pycodestyle",
"pydocstyle",
"pylint",
"pytest",
"sphinx",
"tox",
"twine",
]
},
python_requires=">=3.6, <4",
package_data={"zero_ex.contract_artifacts": ["py.typed", "artifacts/*"]},
package_dir={"": "src"},
license="Apache 2.0",
keywords=(
"ethereum cryptocurrency 0x decentralized blockchain dex exchange"
),
namespace_packages=["zero_ex"],
packages=find_packages("src"),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Financial and Insurance Industry",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Office/Business :: Financial",
"Topic :: Other/Nonlisted Topic",
"Topic :: Security :: Cryptography",
"Topic :: Software Development :: Libraries",
"Topic :: Utilities",
],
zip_safe=False, # required per mypy
command_options={
"build_sphinx": {
"source_dir": ("setup.py", "src"),
"build_dir": ("setup.py", "build/docs"),
}
},
)
|