-
Notifications
You must be signed in to change notification settings - Fork 574
Expand file tree
/
Copy pathlib.py
More file actions
200 lines (163 loc) · 5.27 KB
/
lib.py
File metadata and controls
200 lines (163 loc) · 5.27 KB
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
189
190
191
192
193
194
195
196
197
198
199
200
# pylint: disable=not-context-manager
"""
A library of functions and constants for tasks to make use of.
"""
import os
import sys
import re
from functools import wraps
from fabric.api import run, hide, cd, env
from fabric.context_managers import settings, shell_env
from fabvenv import virtualenv
FABRIC_ROOT = os.path.dirname(__file__)
PROJECT_ROOT = os.path.dirname(FABRIC_ROOT)
VENV_ROOT = os.path.expanduser(os.path.join('~', '.virtualenvs', 'pybitmessage-devops'))
PYTHONPATH = os.path.join(PROJECT_ROOT, 'src',)
def coerce_list(value):
"""Coerce a value into a list"""
if isinstance(value, str):
return value.split(',')
else:
sys.exit("Bad string value {}".format(value))
def coerce_bool(value):
"""Coerce a value into a boolean"""
if isinstance(value, bool):
return value
elif any(
[
value in [0, '0'],
value.lower().startswith('n'),
]
):
return False
elif any(
[
value in [1, '1'],
value.lower().startswith('y'),
]
):
return True
else:
sys.exit("Bad boolean value {}".format(value))
def flatten(data):
"""Recursively flatten lists"""
result = []
for item in data:
if isinstance(item, list):
result.append(flatten(item))
else:
result.append(item)
return result
def filelist_from_git(rev=None):
"""Return a list of files based on git output"""
cmd = 'git diff --name-only'
if rev:
if rev in ['cached', 'staged']:
cmd += ' --{}'.format(rev)
elif rev == 'working':
pass
else:
cmd += ' -r {}'.format(rev)
with cd(PROJECT_ROOT):
with hide('running', 'stdout'):
results = []
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
clean = ansi_escape.sub('', run(cmd))
clean = re.sub('\n', '', clean)
for line in clean.split('\r'):
if line.endswith(".py"):
results.append(os.path.abspath(line))
return results
def pycodestyle(path_to_file):
"""Run pycodestyle on a file"""
with virtualenv(VENV_ROOT):
with hide('warnings', 'running', 'stdout', 'stderr'):
with settings(warn_only=True):
return run(
'pycodestyle --config={0} {1}'.format(
os.path.join(
PROJECT_ROOT,
'setup.cfg',
),
path_to_file,
),
)
def flake8(path_to_file):
"""Run flake8 on a file"""
with virtualenv(VENV_ROOT):
with hide('warnings', 'running', 'stdout'):
with settings(warn_only=True):
return run(
'flake8 --config={0} {1}'.format(
os.path.join(
PROJECT_ROOT,
'setup.cfg',
),
path_to_file,
),
)
def pylint(path_to_file):
"""Run pylint on a file"""
with virtualenv(VENV_ROOT):
with hide('warnings', 'running', 'stdout', 'stderr'):
with settings(warn_only=True):
with shell_env(PYTHONPATH=PYTHONPATH):
return run(
'pylint --rcfile={0} {1}'.format(
os.path.join(
PROJECT_ROOT,
'setup.cfg',
),
path_to_file,
),
)
def autopep8(path_to_file):
"""Run autopep8 on a file"""
with virtualenv(VENV_ROOT):
with hide('running'):
with settings(warn_only=True):
return run(
"autopep8 --experimental --aggressive --aggressive -i --max-line-length=119 {}".format(
path_to_file
),
)
def get_filtered_pycodestyle_output(path_to_file):
"""Clean up the raw results for pycodestyle"""
return [
i
for i in pycodestyle(path_to_file).split(os.linesep)
if i
]
def get_filtered_flake8_output(path_to_file):
"""Clean up the raw results for flake8"""
return [
i
for i in flake8(path_to_file).split(os.linesep)
if i
]
def get_filtered_pylint_output(path_to_file):
"""Clean up the raw results for pylint"""
return [
i
for i in pylint(path_to_file).split(os.linesep)
if all([
i,
not i.startswith(' '),
not i.startswith('\r'),
not i.startswith('-'),
not i.startswith('Y'),
not i.startswith('*'),
not i.startswith('Using config file'),
])
]
def default_hosts(hosts):
"""Decorator to apply default hosts to a task"""
def real_decorator(func):
"""Manipulate env"""
env.hosts = env.hosts or hosts
@wraps(func)
def wrapper(*args, **kwargs):
"""Original function called from here"""
return func(*args, **kwargs)
return wrapper
return real_decorator