Merge branch 'github-actions-lint' into develop

develop
lethosor 2020-06-30 00:48:35 -04:00
commit 6a712b8b28
8 changed files with 106 additions and 38 deletions

@ -82,34 +82,47 @@ jobs:
if: success() || failure()
run: |
rm -rf "$DF_FOLDER"
lint:
runs-on: ubuntu-18.04
steps:
- name: Install dependencies
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: 3
- name: Set up Ruby 2.7
uses: actions/setup-ruby@v1
with:
ruby-version: 2.7
- name: Install Lua
run: |
sudo apt-get update
sudo apt-get install \
lua5.3 \
ruby
sudo apt-get install lua5.3
- name: Clone DFHack
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
submodules: true
# don't need tags here
- name: Check whitespace
run: |
python travis/lint.py
- name: Check Authors.rst
if: success() || failure()
run: |
python travis/authors-rst.py
- name: Check for missing documentation
if: success() || failure()
run: |
python travis/script-docs.py
- name: Check Lua syntax
if: success() || failure()
run: |
python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p"
python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" --github-actions
- name: Check Ruby syntax
if: success() || failure()
run: |
python travis/script-syntax.py --ext=rb --cmd="ruby -c"
python travis/script-syntax.py --ext=rb --cmd="ruby -c" --github-actions
check-pr:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import argparse, os, sys, time
parser = argparse.ArgumentParser()

@ -1,3 +1,4 @@
#!/usr/bin/env python3
""" Overly-complicated script to check formatting/sorting in Authors.rst """
import re, sys

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import glob
import sys

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import re, os, sys
valid_extensions = ['c', 'cpp', 'h', 'hpp', 'mm', 'lua', 'rb', 'proto',
@ -18,28 +19,13 @@ def valid_file(filename):
not len(list(filter(lambda path: path.replace('\\', '/') in filename.replace('\\', '/'), path_blacklist)))
success = True
def error(msg):
def error(msg=None):
global success
success = False
if msg:
sys.stderr.write(msg + '\n')
class LinterError(Exception): pass
class Linter(object):
ignore = False
def check(self, lines):
failures = []
for i, line in enumerate(lines):
if not self.check_line(line):
failures.append(i + 1)
if len(failures):
raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines))))
def fix(self, lines):
for i in range(len(lines)):
lines[i] = self.fix_line(lines[i])
def display_lines(self, lines, total):
def format_lines(lines, total):
if len(lines) == total - 1:
return 'entire file'
if not len(lines):
@ -64,6 +50,34 @@ class Linter(object):
s += ('%i-%i, ' % (range_start, range_end))
return s.rstrip(' ').rstrip(',')
class LinterError(Exception):
def __init__(self, message, lines, total_lines):
self.message = message
self.lines = lines
self.total_lines = total_lines
def __str__(self):
return '%s: %s' % (self.message, format_lines(self.lines, self.total_lines))
def github_actions_workflow_command(self, filename):
first_line = self.lines[0] if self.lines else 1
return '::error file=%s,line=%i::%s' % (filename, first_line, self)
class Linter(object):
ignore = False
def check(self, lines):
failures = []
for i, line in enumerate(lines):
if not self.check_line(line):
failures.append(i + 1)
if len(failures):
raise LinterError(self.msg, failures, len(lines))
def fix(self, lines):
for i in range(len(lines)):
lines[i] = self.fix_line(lines[i])
class NewlineLinter(Linter):
msg = 'Contains DOS-style newlines'
# git supports newline conversion. Catch in CI, ignore on Windows.
@ -91,6 +105,7 @@ class TabLinter(Linter):
linters = [cls() for cls in Linter.__subclasses__() if not cls.ignore]
def main():
is_github_actions = os.environ.get('GITHUB_ACTIONS')
root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.')
if not os.path.exists(root_path):
print('Nonexistent path: %s' % root_path)
@ -112,12 +127,21 @@ def main():
try:
lines[i] = line.decode('utf-8')
except UnicodeDecodeError:
error('%s:%i: Invalid UTF-8 (other errors will be ignored)' % (rel_path, i + 1))
msg_params = (rel_path, i + 1, 'Invalid UTF-8 (other errors will be ignored)')
if is_github_actions:
error()
print('::error file=%s,line=%i::%s' % msg_params)
else:
error('%s:%i: %s' % msg_params)
lines[i] = ''
for linter in linters:
try:
linter.check(lines)
except LinterError as e:
if is_github_actions:
error()
print(e.github_actions_workflow_command(rel_path))
else:
error('%s: %s' % (rel_path, e))
if fix:
linter.fix(lines)

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import argparse
import enum
import json

@ -1,3 +1,4 @@
#!/usr/bin/env python3
from __future__ import print_function
from io import open
import os

@ -1,8 +1,26 @@
#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
def print_stderr(stderr, args):
if not args.github_actions:
sys.stderr.write(stderr + '\n')
return
for line in stderr.split('\n'):
parts = list(map(str.strip, line.split(':')))
# e.g. luac prints "luac:" in front of messages, so find the first part
# containing the actual filename
for i in range(len(parts) - 1):
if parts[i].endswith('.' + args.ext) and parts[i + 1].isdigit():
print('::error file=%s,line=%s::%s' % (parts[i], parts[i + 1], ':'.join(parts[i + 2:])))
break
print(line)
def main(args):
root_path = os.path.abspath(args.path)
cmd = args.cmd.split(' ')
@ -19,7 +37,13 @@ def main(args):
continue
full_path = os.path.join(cur, filename)
try:
subprocess.check_output(cmd + [full_path])
p = subprocess.Popen(cmd + [full_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
_, stderr = p.communicate()
stderr = stderr.decode('utf-8', errors='ignore')
if stderr:
print_stderr(stderr, args)
if p.returncode != 0:
err = True
except subprocess.CalledProcessError:
err = True
except IOError:
@ -34,5 +58,7 @@ if __name__ == '__main__':
parser.add_argument('--path', default='.', help='Root directory')
parser.add_argument('--ext', help='Script extension', required=True)
parser.add_argument('--cmd', help='Command', required=True)
parser.add_argument('--github-actions', action='store_true',
help='Enable GitHub Actions workflow command output')
args = parser.parse_args()
main(args)