diff --git a/git_aggregator/main.py b/git_aggregator/main.py index 845030d..defe6ac 100644 --- a/git_aggregator/main.py +++ b/git_aggregator/main.py @@ -98,6 +98,13 @@ def get_parser(): help='Expand environment variables in configuration file', ) + main_parser.add_argument( + 'command', + nargs='?', + default='aggregate', + help='aggregate (default): run the aggregation process\n' + 'show-closed-prs: show pull requests that are not in open state') + return main_parser @@ -115,8 +122,9 @@ def main(): ) try: - if args.config: - load_aggregate(args) + if args.config and \ + args.command in ('aggregate', 'show-closed-prs'): + run(args) else: parser.print_help() except KeyboardInterrupt: @@ -133,7 +141,7 @@ def match_dir(cwd, dirmatch=None): def load_aggregate(args): """Load YAML and JSON configs and begin creating / updating , aggregating - and pushing the repos""" + and pushing the repos (deprecated in favor or run())""" repos = load_config(args.config, args.expand_env) dirmatch = args.dirmatch for repo_dict in repos: @@ -145,3 +153,22 @@ def load_aggregate(args): r.aggregate() if args.do_push: r.push() + + +def run(args): + """Load YAML and JSON configs and run the command specified + in args.command""" + repos = load_config(args.config, args.expand_env) + dirmatch = args.dirmatch + for repo_dict in repos: + r = Repo(**repo_dict) + logger.debug('%s' % r) + if not match_dir(r.cwd, dirmatch): + logger.info("Skip %s", r.cwd) + continue + if args.command == 'aggregate': + r.aggregate() + if args.do_push: + r.push() + elif args.command == 'show-closed-prs': + r.show_closed_prs() diff --git a/git_aggregator/repo.py b/git_aggregator/repo.py index 7cf1cc2..86d5d68 100644 --- a/git_aggregator/repo.py +++ b/git_aggregator/repo.py @@ -6,8 +6,11 @@ from __future__ import unicode_literals import os import logging +import re import subprocess +import requests + from .utils import working_directory_keeper from .exception import GitAggregatorException from ._compat import console_to_str @@ -284,3 +287,44 @@ def _set_remote(self, name, url): name, exising_url, url) self.log_call(['git', 'remote', 'rm', name]) self.log_call(['git', 'remote', 'add', name, url]) + + def _github_api_get(self, path): + url = 'https://api.github.com' + path + token = os.environ.get('GITHUB_TOKEN') + if token: + url += '?access_token=' + token + return requests.get(url) + + def show_closed_prs(self): + REPO_RE = re.compile( + '^(https://github.com/|git@github.com:)' + '(?P.*?)/(?P.*?)(.git)?$') + PULL_RE = re.compile( + '^(refs/)?pull/(?P[0-9]+)/head$') + remotes = {r['name']: r['url'] for r in self.remotes} + for merge in self.merges: + remote = merge['remote'] + ref = merge['ref'] + repo_url = remotes[remote] + repo_mo = REPO_RE.match(repo_url) + if not repo_mo: + logger.debug('%s is not a github repo', repo_url) + continue + pull_mo = PULL_RE.match(ref) + if not pull_mo: + logger.debug('%s is not a github pull reqeust', ref) + continue + owner = repo_mo.group('owner') + repo = repo_mo.group('repo') + pr = pull_mo.group('pr') + r = self._github_api_get( + '/repos/{owner}/{repo}/pulls/{pr}'.format(**locals())) + if r.status_code != 200: + logger.warning( + 'Could not get status of /{owner}/{repo}/pulls/{pr}'. + format(**locals())) + continue + state = r.json().get('state') + if state != 'open': + logger.info('https://github.com/{owner}/{repo}/pull/{pr} ' + 'in state {state}'.format(**locals())) diff --git a/setup.py b/setup.py index 75ecda2..8142380 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,7 @@ 'kaptan', 'argcomplete', 'colorama', + 'requests', ], entry_points=dict( console_scripts=['gitaggregate=git_aggregator.main:main']),