Commit 9a5ab181 authored by Greg Wilson's avatar Greg Wilson
Browse files

Starting on tool to check repository settings.

1.  Created `bin/repo_check.py`.
2.  Moved `require()` to `util.py`.
3.  Updated `Makefile` with new target.
parent 9610f407
......@@ -27,6 +27,11 @@ site : lesson-rmd
figures :
@bin/extract_figures.py -s _episodes -p ${PARSER} > _includes/all_figures.html
# repo-check : check repository settings.
repo-check :
@bin/repo_check.py -s .
## clean : clean up junk files.
clean :
@rm -rf ${DST}
......
......@@ -11,7 +11,7 @@ import json
import re
from optparse import OptionParser
from util import Reporter, read_markdown, load_yaml, check_unwanted_files
from util import Reporter, read_markdown, load_yaml, check_unwanted_files, require
__version__ = '0.2'
......@@ -252,14 +252,6 @@ def create_checker(args, filename, info):
return cls(args, filename, **info)
def require(condition, message):
"""Fail if condition not met."""
if not condition:
print(message, file=sys.stderr)
sys.exit(1)
class CheckBase(object):
"""Base class for checking Markdown files."""
......
#!/usr/bin/env python
"""
Check repository settings.
"""
import sys
import os
import re
from optparse import OptionParser
from util import Reporter, load_yaml, require
# Import this way to produce a more useful error message.
try:
import requests
except ImportError:
print('Unable to import requests module: please install requests', file=sys.stderr)
sys.exit(1)
# Pattern to match repository URLs and extract username and project name.
P_REPO_URL = re.compile(r'https?://github\.com/([^.]+)/([^/]+)/?')
# API URL format string.
F_API_URL = 'https://api.github.com/repos/{0}/{1}/labels'
# Expected labels and colors.
EXPECTED = {
'bug' : 'bd2c00',
'discussion' : 'fc8dc1',
'enhancement' : '9cd6dc',
'help-wanted' : 'f4fd9c',
'instructor-training' : '6e5494',
'newcomer-friendly' : 'eec275',
'question' : '808040',
'template-and-tools' : '2b3990',
'work-in-progress' : '7ae78e'
}
def main():
"""
Main driver.
"""
args = parse_args()
reporter = Reporter()
repo_url = get_repo_url(args.source_dir)
check_labels(reporter, repo_url)
reporter.report()
def parse_args():
"""
Parse command-line arguments.
"""
parser = OptionParser()
parser.add_option('-s', '--source',
default=os.curdir,
dest='source_dir',
help='source directory')
args, extras = parser.parse_args()
require(not extras,
'Unexpected trailing command-line arguments "{0}"'.format(extras))
return args
def get_repo_url(source_dir):
"""
Figure out which repository to query.
"""
config_file = os.path.join(source_dir, '_config.yml')
config = load_yaml(config_file)
if 'repo' not in config:
print('"repo" not found in {0}'.format(config_file), file=sys.stderr)
sys.exit(1)
return config['repo']
def check_labels(reporter, repo_url):
"""
Check labels in repository.
"""
actual = get_labels(repo_url)
extra = set(actual.keys()) - set(EXPECTED.keys())
reporter.check(not extra,
None,
'Extra label(s) in repository {0}: {1}',
repo_url, ', '.join(sorted(extra)))
missing = set(EXPECTED.keys()) - set(actual.keys())
reporter.check(not missing,
None,
'Missing label(s) in repository {0}: {1}',
repo_url, ', '.join(sorted(missing)))
overlap = set(EXPECTED.keys()).intersection(set(actual.keys()))
for name in sorted(overlap):
reporter.check(EXPECTED[name] == actual[name],
None,
'Color mis-match for label {0} in {1}: expected {2}, found {3}',
name, repo_url, EXPECTED[name], actual[name])
def get_labels(repo_url):
"""
Get actual labels from repository.
"""
m = P_REPO_URL.match(repo_url)
require(m, 'repository URL {0} does not match expected pattern'.format(repo_url))
username = m.group(1)
require(username, 'empty username in repository URL {0}'.format(repo_url))
project_name = m.group(2)
require(username, 'empty project name in repository URL {0}'.format(repo_url))
url = F_API_URL.format(username, project_name)
r = requests.get(url)
require(r.status_code == 200,
'Request for {0} failed with {1}'.format(url, r.status_code))
result = {}
for entry in r.json():
result[entry['name']] = entry['color']
return result
if __name__ == '__main__':
main()
......@@ -151,3 +151,11 @@ def check_unwanted_files(dir_path, reporter):
reporter.check(not os.path.exists(path),
path,
"Unwanted file found")
def require(condition, message):
"""Fail if condition not met."""
if not condition:
print(message, file=sys.stderr)
sys.exit(1)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment