-
-
Save volf52/ccbc79e701b197c9c00051c43629d80d to your computer and use it in GitHub Desktop.
Auto-run `go test` in the console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
This script scans the current working directory for changes to .go files and | |
runs `go test` in each folder where *_test.go files are found. It does this | |
indefinitely or until a KeyboardInterrupt is raised (<Ctrl+c>). This script | |
passes the verbosity command line argument (-v) to `go test`. | |
""" | |
import os | |
import subprocess | |
import sys | |
import time | |
def main(verbose): | |
working = os.path.abspath(os.path.join(os.getcwd())) | |
scanner = WorkspaceScanner(working) | |
runner = TestRunner(working, verbose) | |
while True: | |
if scanner.scan(): | |
runner.run() | |
class WorkspaceScanner(object): | |
def __init__(self, top): | |
self.state = 0 | |
self.top = top | |
def scan(self): | |
time.sleep(.75) | |
new_state = sum(self._checksums()) | |
if self.state != new_state: | |
self.state = new_state | |
return True | |
return False | |
def _checksums(self): | |
for root, dirs, files in os.walk(self.top): | |
for f in files: | |
if f.endswith('.go'): | |
try: | |
stats = os.stat(os.path.join(root, f)) | |
yield stats.st_mtime + stats.st_size | |
except OSError: | |
pass | |
class TestRunner(object): | |
def __init__(self, top, verbosity): | |
self.repetitions = 0 | |
self.top = top | |
self.working = self.top | |
self.verbosity = verbosity | |
def run(self): | |
self.repetitions += 1 | |
self._display_repetitions_banner() | |
self._run_tests() | |
def _display_repetitions_banner(self): | |
number = ' {} '.format(self.repetitions if self.repetitions % 50 else | |
'Wow, are you going for a top score? Keep it up!') | |
half_delimiter = (EVEN if not self.repetitions % 2 else ODD) * \ | |
((80 - len(number)) / 2) | |
write('\n{0}{1}{0}\n'.format(half_delimiter, number)) | |
def _run_tests(self): | |
self._chdir(self.top) | |
if self.tests_found(): | |
self._run_test() | |
for root, dirs, files in os.walk(self.top): | |
self.search_for_tests(root, dirs, files) | |
def search_for_tests(self, root, dirs, files): | |
for d in dirs: | |
if '.git' in d or '.git' in root: | |
continue | |
self._chdir(os.path.join(root, d)) | |
if self.tests_found(): | |
self._run_test() | |
def tests_found(self): | |
for f in os.listdir(self.working): | |
if f.endswith('_test.go'): | |
return True | |
return False | |
def _run_test(self): | |
subprocess.call('go test -i', shell=True) | |
try: | |
output = subprocess.check_output( | |
'go test ' + self.verbosity, shell=True) | |
self.write_output(output) | |
except subprocess.CalledProcessError as error: | |
self.write_output(error.output) | |
write('\n') | |
def write_output(self, output): | |
write(output) | |
def _chdir(self, new): | |
os.chdir(new) | |
self.working = new | |
def write(value): | |
sys.stdout.write(value) | |
sys.stdout.flush() | |
EVEN = '=' | |
ODD = '-' | |
RESET_COLOR = '\033[0m' | |
RED_COLOR = '\033[31m' | |
YELLOW_COLOR = '\033[33m' | |
GREEN_COLOR = '\033[32m' | |
def parse_bool_arg(name): | |
for arg in sys.argv: | |
if arg == name: | |
return True | |
return False | |
if __name__ == '__main__': | |
verbose = '-v' if parse_bool_arg('-v') else '' | |
main(verbose) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment