setup.py (254 lines of code) (raw):
# test: ignore
import glob
import os
import shutil
import sys
from subprocess import check_call
from typing import Any, List
from setuptools import find_packages, setup
from setuptools.command.test import Command
from setuptools.command.test import test as TestCommand # noqa: N812
import inspect
__version__ = "1.0.6"
SWAGGER_URL = "https://oss.sonatype.org/content/repositories/releases/io/swagger/swagger-codegen-cli/2.2.1/swagger-codegen-cli-2.2.1.jar"
SWAGGER_CLI = SWAGGER_URL.split("/")[-1]
class PyTest(TestCommand):
skip_hypothesis = True
def finalize_options(self) -> None:
TestCommand.finalize_options(self)
import os
xml_out = os.path.join(".", "build", "test-results", "pytest.xml")
if not os.path.exists(os.path.dirname(xml_out)):
os.makedirs(os.path.dirname(xml_out))
# -s is needed so py.test doesn't mess with stdin/stdout
self.test_args = ["-s", "test", "--junitxml=%s" % xml_out]
# needed for older setuptools to actually run this as a test
self.test_suite = True
def run_tests(self) -> None:
# import here, cause outside the eggs aren't loaded
import sys
import pytest
# run the tests, then the format checks.
os.environ["HPC_RUNTIME_CHECKS"] = "true"
errno = pytest.main(self.test_args + ["-k", "not hypothesis"])
if errno != 0:
sys.exit(errno)
if not PyTest.skip_hypothesis:
os.environ["HPC_RUNTIME_CHECKS"] = "false"
errno = pytest.main(self.test_args + ["-k", "hypothesis"])
if errno != 0:
sys.exit(errno)
check_call(
["black", "--check", "src", "test", "util"],
cwd=os.path.dirname(os.path.abspath(__file__)),
)
check_call(
["isort", "-c"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"),
)
check_call(
["isort", "-c"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "test"),
)
check_call(
["isort", "-c"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "util"),
)
run_type_checking()
sys.exit(errno)
class Formatter(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
check_call(
["black", "src", "test", "util"],
cwd=os.path.dirname(os.path.abspath(__file__)),
)
check_call(
["isort", "-y"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"),
)
check_call(
["isort", "-y"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "test"),
)
check_call(
["isort", "-y"],
cwd=os.path.join(os.path.dirname(os.path.abspath(__file__)), "util"),
)
run_type_checking()
class InitCommitHook(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
activate_script = os.path.join(os.path.dirname(sys.executable), "activate")
if not os.path.exists(activate_script):
print("Run this command after activating your venv!")
sys.exit(1)
pre_commit = os.path.join(
os.path.dirname(__file__), ".git", "hooks", "pre-commit"
)
if os.path.exists(pre_commit):
print(pre_commit, "exists already. Please remove it and run it again.")
sys.exit(1)
with open(".git/hooks/pre-commit", "w") as fw:
fw.write("#!/bin/sh\n")
fw.write("source {}\n".format(activate_script))
fw.write("python setup.py commithook")
check_call(["chmod", "+x", pre_commit])
class PreCommitHook(PyTest):
def __init__(self, dist: Any, **kw: Any) -> None:
super().__init__(dist, **kw)
PyTest.skip_hypothesis = True
class ResourceFiles(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
check_call([sys.executable, "util/create_vm_sizes.py"])
shutil.move("new_vm_sizes.json", "src/hpc/autoscale/node/vm_sizes.json")
class AutoDoc(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
from hpc.autoscale.node import constraints
from hpc.autoscale.node.constraints import NodeConstraint # noqa: N812
with open("README.md", "w") as fw:
with open("README.md.in") as fr:
print(fr.read(), file=fw)
print("# Node Properties", file=fw)
print(file=fw)
from hpc.autoscale.node import node as nodelib
print("| Property | Type | Description |", file=fw)
print("| :--- | :--- | :--- |", file=fw)
for prop_name in sorted(nodelib.QUERYABLE_PROPERTIES):
prop = getattr(nodelib.Node, prop_name)
sig = inspect.signature(prop.fget)
ra = sig.return_annotation
return_type: str
if hasattr(ra, "__name__"):
return_type = ra.__name__
elif hasattr(ra, "_name"):
optional = False
inner_types = [x.__name__ for x in ra.__args__]
if "NoneType" in inner_types:
optional = True
inner_types = [x for x in inner_types if x != "NoneType"]
return_type = "\\|".join(inner_types)
if optional:
return_type = "Optional[{}]".format(return_type)
else:
return_type = str(ra)
print(
"| node.{} | {} | {} |".format(
prop_name, return_type, prop.__doc__
),
file=fw,
)
print(file=fw)
print(file=fw)
print("# Constraints", file=fw)
print(file=fw)
for attr in dir(constraints):
if not attr[0].isupper():
continue
value = getattr(constraints, attr)
if not isinstance(value, type):
continue
if inspect.isabstract(value):
continue
if not issubclass(value, NodeConstraint):
continue
if not value.__doc__:
continue
print(file=fw)
print(file=fw)
print("##", value.__name__, file=fw)
print(file=fw)
for line in (value.__doc__ or "").splitlines(keepends=False):
if len(line) > 4 and line[:4] == " ":
line = line[4:]
print(line, file=fw)
print(file=fw)
print("# Contributing", file=fw)
print(file=fw)
print(
"""This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.""",
file=fw,
)
def run_type_checking() -> None:
check_call(
["mypy", os.path.join(os.path.dirname(os.path.abspath(__file__)), "test")]
)
check_call(
["mypy", os.path.join(os.path.dirname(os.path.abspath(__file__)), "src")]
)
check_call(
["mypy", os.path.join(os.path.dirname(os.path.abspath(__file__)), "util")]
)
check_call(["flake8", "--ignore=F405,E501,W503,E203", "src", "test", "setup.py"])
class TypeChecking(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
run_type_checking()
class Swagger(Command):
user_options: List[str] = []
def initialize_options(self) -> None:
pass
def finalize_options(self) -> None:
pass
def run(self) -> None:
if not os.path.exists(".tools"):
os.makedirs(".tools")
if not os.path.exists(f".tools/{SWAGGER_CLI}"):
check_call(["wget", SWAGGER_URL], cwd=".tools")
if not os.path.exists("clusters"):
os.makedirs("clusters")
check_call(["java", "-jar", f"../.tools/{SWAGGER_CLI}", "generate", "-i", "../swagger/Clusters.json", "-l", "python"], cwd="clusters")
check_call([sys.executable, "setup.py", "sdist"], cwd="clusters")
for fil in glob.glob("clusters/dist/*.gz"):
dest = os.path.join("dist", os.path.basename(fil))
if os.path.exists(dest):
os.remove(dest)
shutil.move(fil, dest)
setup(
name="cyclecloud-scalelib",
version=__version__,
packages=find_packages(where="src"),
package_dir={"": "src", "conf": "conf"},
include_package_data=True,
install_requires=[
"requests == 2.24.0",
"requests-cache == 0.7.5",
"typing_extensions==3.7.4.3",
"immutabledict==1.0.0",
"jsonpickle==1.5.2",
"argcomplete==1.12.2",
"certifi==2023.7.22",
]
+ ["urllib3==1.25.11"], # noqa: W503
tests_require=["pytest==3.2.3"],
cmdclass={
"test": PyTest,
"docs": AutoDoc,
"swagger": Swagger,
"format": Formatter,
"types": TypeChecking,
"commithook": PreCommitHook,
"initcommithook": InitCommitHook,
"resourcefiles": ResourceFiles,
},
scripts=["util/install_azscale.sh"],
url="http://www.microsoft.com",
maintainer="Azure CycleCloud",
)