-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake
executable file
·146 lines (113 loc) · 5.07 KB
/
snake
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
#!/usr/bin/env python3
"""snake is a build script with homage to cake, make, and rake."""
import json
import os
import requests
import subprocess
import sys
from typing import Callable, Dict, Tuple
import webbrowser
from wipac_telemetry import __version__
def run(cmd) -> None:
"""Run the command and raise a CalledProcessError if the return code is nonzero."""
subprocess.run(cmd).check_returncode()
def do_clean_task() -> None:
"""Remove directories and files generated in the build process."""
run(["rm", "-fr", ".mypy_cache"])
run(["rm", "-fr", ".pytest_cache"])
run(["rm", "-fr", "build"])
run(["rm", "-fr", "dist"])
run(["rm", "-fr", "htmlcov"])
run(["find", "wipac_telemetry", "-name", "__pycache__", "-exec", "rm", "-fr", "{}", "+"])
run(["find", "wipac_telemetry", "-name", "__init__.pyc", "-exec", "rm", "-fr", "{}", "+"])
run(["rm", "-fr", "wipac_telemetry.egg-info"])
run(["find", "tests", "-name", "__pycache__", "-exec", "rm", "-fr", "{}", "+"])
run(["rm", "-fr", ".coverage"])
def do_check_task() -> None:
"""Check the versions of most dependencies against the latest from PyPi."""
current_path = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(current_path, 'requirements.txt')) as f:
requirements_txt = f.read()
requirements = requirements_txt.split("\n")
for requirement in requirements:
if "==" in requirement:
equals_index = requirement.index("==")
package_name = requirement[0:equals_index]
package_version = requirement[equals_index+2:]
url = f"https://pypi.python.org/pypi/{package_name}/json"
r = requests.get(url)
if r:
data = json.loads(r.text)
latest_version = data["info"]["version"]
if package_version != latest_version:
print(f"{package_name} can be upgraded from {package_version} to {latest_version}")
def do_circleci_task() -> None:
"""Run a CircleCI build."""
run(["circleci", "local", "execute", "--job", "examples"])
def do_coverage_task() -> None:
"""Use pytest to generate a coverage report for our unit tests."""
do_clean_task()
run(["pytest", "--cov=wipac_telemetry", "--cov-report=html", "--no-cov-on-fail", "tests"])
webbrowser.open_new_tab("htmlcov/index.html")
def do_dist_task() -> None:
"""Build a distribution tarball and wheel for the project."""
do_clean_task()
do_rebuild_task()
run(["python", "setup.py", "sdist", "bdist_wheel"])
def do_docker_task() -> None:
"""Build a Docker image for the project."""
do_clean_task()
do_rebuild_task()
run(["docker", "build", "-t", f"wipac/wipac_telemetry:{__version__}", "-f", "Dockerfile", "."])
run(["docker", "image", "tag", f"wipac/wipac_telemetry:{__version__}", "wipac/wipac_telemetry:latest"])
def do_lint_task() -> None:
"""Run static analysis tools on the project."""
flake8_cmd = ["flake8"]
mypy_cmd = ["mypy", "--strict", "--allow-subclassing-any"]
run(flake8_cmd + ["tests"])
# TODO: Maybe when pytest has a mypy library stub
# run(mypy_cmd + ["tests"])
run(flake8_cmd + ["wipac_telemetry"])
run(mypy_cmd + ["wipac_telemetry"])
def do_rebuild_task() -> None:
"""Remove old build caches, test, and lint the project."""
do_clean_task()
run(["pytest", "tests"])
do_lint_task()
def do_test_task() -> None:
"""Remove old build caches and run unit tests on the project."""
do_clean_task()
run(["pytest", "tests"])
# ---------------------------------------------------------------------
TaskType = Tuple[str, str, Callable[[], None]]
def task(taskdef: TaskType) -> None:
"""Add a Task to the task table for this script."""
tasks[taskdef[0]] = taskdef
tasks: Dict[str, TaskType] = {}
if __name__ == "__main__":
# define tasks
task(("clean", "Remove build cruft", do_clean_task))
task(("check", "Check dependency package versions", do_check_task))
task(("circleci", "Perform CI build and test", do_circleci_task))
task(("coverage", "Perform coverage analysis", do_coverage_task))
task(("dist", "Create a distribution tarball and wheel", do_dist_task))
task(("docker", "Build a Docker image", do_docker_task))
task(("lint", "Run static analysis tools", do_lint_task))
task(("rebuild", "Test and lint the module", do_rebuild_task))
task(("test", "Test the module", do_test_task))
# if the user didn't supply a task
if len(sys.argv) < 2:
# provide a menu of tasks to run
print("Try one of the following tasks:\n")
taskList = list(tasks.keys())
taskList.sort()
for taskName in taskList:
print(f"snake {taskName:20} # {tasks[taskName][1]}")
sys.exit(1)
# if the user supplied a task that wasn't defined
if sys.argv[1] not in tasks:
# tell them and show them how to get the menu
print(f"No such task: {sys.argv[1]}\n\nTo see a list of all tasks/options, run 'snake'")
sys.exit(1)
# run the task function that the user identified
tasks[sys.argv[1]][2]()