-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtasks.py
155 lines (139 loc) · 3.88 KB
/
tasks.py
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
#! /usr/bin/env python
####
#
# General:
# inv [--dry] TASK [OPTIONS]
# inv --list
# inv --help TASK
#
# Tasks:
# inv tags
# inv test [--cov]
# inv tox
# inv workareas
# inv bump [--kind <major|minor|patch>] [--local]
# inv dist [--publish] [--test]
#
####
import subprocess
import sys
from invoke import task
from pathlib import Path
LIB = 'mvs'
@task
def tags(c):
'''
Run mtags for the project
'''
c.run('mtags --recipe .mvspy --write w')
c.run('mtags --recipe .mvstxt --write u --toc order')
@task
def test(c, func = None, cov = False, vv = False):
'''
Run pytest. optionally opening coverage report.
'''
# Set the target: the thing to be tested.
if func is None:
target = 'tests'
else:
path = path_for_test_func(func)
target = f'{path}::{func}'
# Build pytest command.
cov_args = f'--cov {LIB} --cov-report html' if cov else ''
verbosity = '-vv' if vv else '-v'
cmd = f'pytest --color yes -s {verbosity} {cov_args} {target}'
# Run and cover.
c.run(cmd)
if cov:
c.run('open htmlcov/index.html')
def path_for_test_func(func):
# Takes a test function name.
# Returns the path to its test file, or exits.
args = ('ack', '-l', f'^def {func}', 'tests')
result = subprocess.run(args, stdout = subprocess.PIPE)
out = result.stdout.decode('utf-8').strip()
paths = out.split('\n') if out else []
n = len(paths)
if n == 1:
return paths[0]
elif n == 0:
sys.exit('No matching paths.')
else:
txt = '\n'.join(paths)
sys.exit(f'Too many matching paths.\n{txt}')
@task
def workareas(c):
'''
Create renaming work areas in tmp directory
'''
ws = ('tmp/work1', 'tmp/work2')
subdirs = ('d1', 'd2', 'd3')
for w in ws:
c.run(f'rm -rf {w}')
c.run(f'mkdir {w}')
for sd in subdirs:
c.run(f'mkdir {w}/{sd}')
n = int(sd[-1]) * 10
for i in range(n, n + 3):
f = f'{w}/{sd}/{i}'
c.run(f'touch {f}.txt')
c.run(f'touch {f}.mp3')
@task
def clearlogs(c):
'''
Clear log files.
'''
home = Path.home()
c.run(f'rm -f {home}/.{LIB}/2*.json')
@task
def bump(c, kind = 'minor', edit_only = False, push = False, suffix = None):
'''
Version bump: --kind minor|major|patch [--edit-only] [--push]
'''
# Validate.
assert kind in ('major', 'minor', 'patch')
# Get current version as a 3-element list.
path = f'src/{LIB}/version.py'
lines = open(path).readlines()
version = lines[0].split("'")[1]
major, minor, patch = [int(x) for x in version.split('.')]
# Compute new version.
tup = (
(major + 1, 0, 0) if kind == 'major' else
(major, minor + 1, 0) if kind == 'minor' else
(major, minor, patch + 1)
)
version = '.'.join(str(x) for x in tup)
# Write new version file.
if c['run']['dry']:
print(f'# Dry run: modify version.py: {version}')
else:
with open(path, 'w') as fh:
fh.write(f"__version__ = '{version}'\n\n")
print(f'Bumped to {version}.')
# Commit and push.
if not edit_only:
suffix = '' if suffix is None else f': {suffix}'
msg = f'Version {version}{suffix}'
c.run(f"git commit {path} -m '{msg}'")
if push:
c.run('git push origin master')
@task
def tox(c):
'''
Run tox for the project
'''
d = dict(PYENV_VERSION = '3.11.1:3.10.9:3.9.4:3.8.9:3.7.10:3.6.13:3.5.10')
c.run('tox', env = d)
@task
def dist(c, publish = False, test = False):
'''
Create distribution, optionally publishing to pypi or testpypi.
'''
repo = 'testpypi' if test else 'pypi'
c.run('rm -rf dist')
c.run('python setup.py sdist bdist_wheel')
c.run('echo')
c.run('twine check dist/*')
if publish:
c.run(f'twine upload -r {repo} dist/*')