Skip to content

Commit

Permalink
Starting on tool to check repository settings.
Browse files Browse the repository at this point in the history
1.  Created `bin/repo_check.py`.
2.  Moved `require()` to `util.py`.
3.  Updated `Makefile` with new target.
  • Loading branch information
gvwilson committed Jul 7, 2016
1 parent 9610f40 commit 9a5ab18
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 9 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
10 changes: 1 addition & 9 deletions bin/lesson_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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'

Expand Down Expand Up @@ -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."""

Expand Down
139 changes: 139 additions & 0 deletions bin/repo_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/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()
8 changes: 8 additions & 0 deletions bin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 9a5ab18

Please sign in to comment.