-
Notifications
You must be signed in to change notification settings - Fork 42
/
automation.py
executable file
·151 lines (109 loc) · 3.75 KB
/
automation.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
#!/usr/bin/env python3
"""Automation of common tasks (such as running multiple tests)."""
import argparse
import glob
import logging
import os
import sys
from subprocess import check_call, CalledProcessError
#-------------------------------------------------------------------------------
# Constants
SCRIPT_NAME = 'helper'
#-------------------------------------------------------------------------------
# Logger setup
logger = logging.getLogger(SCRIPT_NAME)
logger.setLevel(logging.DEBUG)
basic_formatter = logging.Formatter(
'[%(levelname)s] %(message)s'
)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(basic_formatter)
logger.addHandler(stream_handler)
#-------------------------------------------------------------------------------
# Utilities
class cd:
"""Context manager for changing the current working directory"""
def __init__(self, new_path):
self.new_path = os.path.expanduser(new_path)
def __enter__(self):
self.saved_path = os.getcwd()
os.chdir(self.new_path)
def __exit__(self, etype, value, traceback):
os.chdir(self.saved_path)
def command(*args, **kwargs):
opts = {
'can_fail': False,
'capture_output': False
}
for key, default in opts.items():
opts[key] = kwargs.get(key, default)
if key in kwargs:
del kwargs[key]
f = call if opts['can_fail'] else check_call
f = check_output if opts['capture_output'] else f
try:
result = f(*args, **kwargs)
if opts['capture_output']:
return str(result, encoding = 'utf-8')
else:
return result
except CalledProcessError as e:
MAX_ARGS = 10
if len(e.cmd) > MAX_ARGS:
cmd = ' '.join(e.cmd[0:MAX_ARGS])
cmd = '%s ... (%d args truncated)' % (cmd, len(e.cmd) - MAX_ARGS)
else:
cmd = ' '.join(e.cmd)
logger.error(
'Command failed (returned %d): %s' % (e.returncode, cmd)
)
sys.exit(e.returncode)
#-------------------------------------------------------------------------------
# Main tasks
def check(args):
logger.info('Checking quality of project')
command(['go', 'fmt'])
command(['go', 'vet'])
command(['go', 'build', '-v', './...'])
command(['golint'])
def test(args):
logger.info('Running benchmarks, unit tests and examples')
cmd = ['go', 'test']
if args.bench:
cmd = cmd + ['-bench', '.', './...']
command(cmd)
example_files = glob.glob('./examples/**/*.go', recursive=True)
for efile in example_files:
logger.info('Running example %s' % efile)
command(['go', 'run', efile])
#-------------------------------------------------------------------------------
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog=SCRIPT_NAME)
subparsers = parser.add_subparsers()
parser.add_argument(
'--log_level',
type=str,
choices=['error', 'info', 'debug'],
help='Controls the log level, "info" is default'
)
check_parser = subparsers.add_parser('check')
check_parser.set_defaults(func=check)
test_parser = subparsers.add_parser('test')
test_parser.add_argument(
'--bench',
dest='bench',
action='store_true',
help='Controls whether to run benchmark or not'
)
test_parser.set_defaults(bench=False, func=test)
args = parser.parse_args()
if args.log_level == 'debug':
stream_handler.setLevel(logging.DEBUG)
elif args.log_level == 'error':
stream_handler.setLevel(logging.ERROR)
if hasattr(args, 'func'):
args.func(args)
else:
logger.error('No command given to run')
sys.exit(1)