Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion easybuild/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
from easybuild.tools.filetools import locate_files, read_file, register_lock_cleanup_signal_handlers, write_file
from easybuild.tools.github import check_github, close_pr, find_easybuild_easyconfig
from easybuild.tools.github import add_pr_labels, install_github_token, list_prs, merge_pr, new_branch_github, new_pr
from easybuild.tools.github import new_pr_from_branch
from easybuild.tools.github import new_pr_from_branch, summarize_prs
from easybuild.tools.github import sync_branch_with_develop, sync_pr_with_develop, update_branch, update_pr
from easybuild.tools.hooks import START, END, load_hooks, run_hook
from easybuild.tools.modules import modules_tool
Expand Down Expand Up @@ -644,6 +644,9 @@ def main(args=None, logfile=None, do_build=None, testing=False, modtool=None):
elif options.list_prs:
print(list_prs(options.list_prs))

elif options.summarize_prs:
print(summarize_prs(options.summarize_prs))

elif options.merge_pr:
merge_pr(options.merge_pr)

Expand Down Expand Up @@ -680,6 +683,7 @@ def main(args=None, logfile=None, do_build=None, testing=False, modtool=None):
options.list_prs,
options.merge_pr,
options.review_pr,
options.summarize_prs,
options.terse,
search_query,
]
Expand Down
45 changes: 45 additions & 0 deletions easybuild/tools/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
GITHUB_FRAMEWORK_REPO = 'easybuild-framework'
GITHUB_DEVELOP_BRANCH = 'develop'
GITHUB_FILE_TYPE = u'file'
GITHUB_PR_GROUPS = ['author', 'labels']
GITHUB_PR_STATE_OPEN = 'open'
GITHUB_PR_STATES = [GITHUB_PR_STATE_OPEN, 'closed', 'all']
GITHUB_PR_ORDER_CREATED = 'created'
Expand Down Expand Up @@ -1418,6 +1419,50 @@ def list_prs(params, per_page=GITHUB_MAX_PER_PAGE, github_user=None):
return '\n'.join(lines)


def summarize_prs(params, per_page=GITHUB_MAX_PER_PAGE, github_user=None):
"""
Summarize pull requests according to specified selection/order parameters

:param params: 4-tuple with selection parameters for PRs (<group>, <state>, <sort>, <direction>),
group is one of GITHUB_PR_GROUPS, for the rest see
see https://developer.github.com/v3/pulls/#parameters
"""
group_by = params[0]

parameters = {
'state': params[1],
'sort': params[2],
'direction': 'asc', # params[3],
'per_page': per_page,
}
print_msg("Summarizing PRs with parameters: %s" % ', '.join(k + '=' + str(parameters[k])
for k in sorted(parameters)))

pr_target_account = build_option('pr_target_account')
pr_target_repo = build_option('pr_target_repo') or GITHUB_EASYCONFIGS_REPO

pr_data, _ = fetch_pr_data(None, pr_target_account, pr_target_repo, github_user, **parameters)

summary = {}
for pr in pr_data:
if group_by == 'author':
groups = [pr['user']['login']]
elif group_by == 'labels':
groups = [label['name'] for label in pr['labels']]
else:
groups = [pr[group_by]]

for group in groups:
if group not in summary:
summary[group] = 1
else:
summary[group] += 1

lines = ["%s: %s" % (key, count) for key, count in sorted(summary.items(), key=lambda kv: kv[1], reverse=True)]

return '\n'.join(lines)


def merge_pr(pr):
"""
Merge specified pull request
Expand Down
40 changes: 39 additions & 1 deletion easybuild/tools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
from easybuild.tools.environment import restore_env, unset_env_vars
from easybuild.tools.filetools import CHECKSUM_TYPE_SHA256, CHECKSUM_TYPES, expand_glob_paths, install_fake_vsc
from easybuild.tools.filetools import move_file, which
from easybuild.tools.github import GITHUB_PR_DIRECTION_DESC, GITHUB_PR_ORDER_CREATED
from easybuild.tools.github import GITHUB_PR_DIRECTION_DESC, GITHUB_PR_ORDER_CREATED, GITHUB_PR_GROUPS
from easybuild.tools.github import GITHUB_PR_STATE_OPEN, GITHUB_PR_STATES, GITHUB_PR_ORDERS, GITHUB_PR_DIRECTIONS
from easybuild.tools.github import HAVE_GITHUB_API, HAVE_KEYRING, VALID_CLOSE_PR_REASONS
from easybuild.tools.github import fetch_easyblocks_from_pr, fetch_github_token
Expand Down Expand Up @@ -129,6 +129,8 @@ def terminal_supports_colors(stream):
DEFAULT_LIST_PR_ORDER = GITHUB_PR_ORDER_CREATED
DEFAULT_LIST_PR_DIREC = GITHUB_PR_DIRECTION_DESC

DEFAULT_SUMMARIZE_PR_GROUP = 'author'

_log = fancylogger.getLogger('options', fname=False)


Expand Down Expand Up @@ -722,6 +724,10 @@ def github_options(self):
'review-pr-filter': ("Regex used to filter out easyconfigs to diff against in --review-pr",
None, 'regex', None),
'review-pr-max': ("Maximum number of easyconfigs to diff against in --review-pr", int, 'store', None),
'summarize-prs': ("Summarize pull requests", str, 'store_or_None',
",".join([DEFAULT_SUMMARIZE_PR_GROUP, DEFAULT_LIST_PR_STATE, DEFAULT_LIST_PR_ORDER,
DEFAULT_LIST_PR_DIREC]),
{'metavar': 'GROUP,STATE,ORDER,DIRECTION'}),
'test-report-env-filter': ("Regex used to filter out variables in environment dump of test report",
None, 'regex', None),
'update-branch-github': ("Update specified branch in GitHub", str, 'store', None),
Expand Down Expand Up @@ -959,6 +965,10 @@ def postprocess(self):
if self.options.list_prs:
self._postprocess_list_prs()

# make sure --list-prs has a valid format
if self.options.summarize_prs:
self._postprocess_summarize_prs()

# handle configuration options that affect other configuration options
self._postprocess_config()

Expand Down Expand Up @@ -1025,6 +1035,34 @@ def _postprocess_list_prs(self):

self.options.list_prs = (list_pr_state, list_pr_order, list_pr_direc)

def _postprocess_summarize_prs(self):
"""Postprocess --summarize-prs options"""
summarize_pr_parts = self.options.summarize_prs.split(',')
nparts = len(summarize_pr_parts)

if nparts > 4:
raise EasyBuildError("Argument to --summarize-prs must be in the format 'group[,state[,order[,direction]]]")

summarize_pr_group = summarize_pr_parts[0]
summarize_pr_state = summarize_pr_parts[1] if nparts > 1 else DEFAULT_LIST_PR_STATE
summarize_pr_order = summarize_pr_parts[2] if nparts > 2 else DEFAULT_LIST_PR_ORDER
summarize_pr_direc = summarize_pr_parts[3] if nparts > 3 else DEFAULT_LIST_PR_DIREC

if summarize_pr_group not in GITHUB_PR_GROUPS:
raise EasyBuildError("1st item in --summarize-prs ('%s') must be one of %s",
summarize_pr_group, GITHUB_PR_GROUPS)
if summarize_pr_state not in GITHUB_PR_STATES:
raise EasyBuildError("2nd item in --summarize-prs ('%s') must be one of %s",
summarize_pr_state, GITHUB_PR_STATES)
if summarize_pr_order not in GITHUB_PR_ORDERS:
raise EasyBuildError("3rd item in --summarize-prs ('%s') must be one of %s",
summarize_pr_order, GITHUB_PR_ORDERS)
if summarize_pr_direc not in GITHUB_PR_DIRECTIONS:
raise EasyBuildError("4th item in --summarize-prs ('%s') must be one of %s",
summarize_pr_direc, GITHUB_PR_DIRECTIONS)

self.options.summarize_prs = (summarize_pr_group, summarize_pr_state, summarize_pr_order, summarize_pr_direc)

def _postprocess_include(self):
"""Postprocess --include options."""
# set up included easyblocks, module naming schemes and toolchains/toolchain components
Expand Down