def session_state(): """Get session state: timestamp, dump of environment, system info.""" return { 'time': gmtime(), 'environment': copy.deepcopy(os.environ), 'system_info': get_system_info(), }
def get_build_stats(app, start_time, command_line): """ Return build statistics for this build """ time_now = time.time() build_time = round(time_now - start_time, 2) buildstats = OrderedDict([ ('easybuild-framework_version', str(FRAMEWORK_VERSION)), ('easybuild-easyblocks_version', str(EASYBLOCKS_VERSION)), ('timestamp', int(time_now)), ('build_time', build_time), ('install_size', app.det_installsize()), ('command_line', command_line), ('modules_tool', app.modules_tool.buildstats()), ]) for key, val in sorted(get_system_info().items()): buildstats.update({key: val}) return buildstats
def test_system_info(self): """Test getting system info.""" system_info = get_system_info() self.assertTrue(isinstance(system_info, dict))
def process_notifications(notifications, github, github_user, github_account, repository, host, pr_test_cmd, core_cnt): """Process provided notifications.""" res = [] cnt = len(notifications) for idx, notification in enumerate(notifications): pr_title = notification['subject']['title'] pr_id = notification['subject']['url'].split('/')[-1] msg = "[%d/%d] Processing notification for %s PR #%s \"%s\"... " % ( idx + 1, cnt, repository, pr_id, pr_title) msg += "(thread id: %s, timestamp: %s)" % (notification['thread_id'], notification['timestamp']) print(msg) # check comments (latest first) pr_data, _ = fetch_pr_data(pr_id, github_account, repository, github_user, full=True, per_page=GITHUB_MAX_PER_PAGE) comments_data = pr_data['issue_comments'] # determine comment that triggered the notification trigger_comment_id = None mention_regex = re.compile(r'\s*@%s:?\s*' % github_user, re.M) for comment_data in comments_data[::-1]: comment_id, comment_txt = comment_data['id'], comment_data['body'] if mention_regex.search(comment_txt): trigger_comment_id = comment_id break check_str = "notification for comment with ID %s processed" % trigger_comment_id processed = False for comment_data in comments_data[::-1]: comment_by, comment_txt = comment_data['user'][ 'login'], comment_data['body'] if comment_by == github_user and check_str in comment_txt: print("check_str '%s' found in: %s" % (check_str, comment_txt)) processed = True break if processed: msg = "Notification %s already processed, so skipping it... " % notification[ 'thread_id'] msg += "(timestamp: %s)" % notification['timestamp'] print(msg) continue host_regex = re.compile(r'@.*%s' % host, re.M) mention_found = False for comment_data in comments_data[::-1]: comment_id, comment_by = comment_data['id'], comment_data['user'][ 'login'] comment_txt = comment_data['body'] if mention_regex.search(comment_txt): print("Found comment including '%s': %s" % (mention_regex.pattern, comment_txt)) msg = mention_regex.sub(' ', comment_txt) # require that @<host> is included in comment before taking any action if host_regex.search(msg): print("Comment includes '%s', so processing it..." % host_regex.pattern) maintainers = [ 'akesandgren', 'bartoldeman', 'bedroge', 'boegel', 'branfosj', 'casparvl', 'jfgrimm', 'lexming', 'Micket', 'migueldiascosta', 'ocaisa', 'SebastianAchilles', 'smoors', 'verdurin' ] contributors = ['robert-mijakovic'] allowed_accounts = maintainers + contributors please_regex = re.compile(r'[Pp]lease test', re.M) if comment_by not in allowed_accounts: allowed_accounts_str = ' or '.join( '@%s' % x for x in allowed_accounts) reply_msg = "@%s: I noticed your comment, " % comment_by reply_msg += "but I only dance when %s tells me (for now), I'm sorry..." % allowed_accounts_str elif "PLEASE " in msg: reply_msg = "Don't scream, it's rude and I don't like people who do..." elif please_regex.search(msg): system_info = get_system_info() hostname = system_info.get('hostname', '(hostname not known)') reply_msg = "@%s: Request for testing this PR well received on %s\n" % ( comment_by, hostname) tmpl_dict = {'pr': pr_id} # check whether custom arguments for 'eb' or submit command are specified tmpl_dict.update({ 'core_cnt': core_cnt, 'eb_args': '', }) for item in shlex.split(msg): for key in ['CORE_CNT', 'EB_ARGS']: if item.startswith(key + '='): _, value = item.split('=', 1) tmpl_dict[key.lower()] = '"%s"' % value break # run pr test command, check exit code and capture output cmd = pr_test_cmd % tmpl_dict (out, ec) = run_cmd(cmd, simple=False) reply_msg += '\n'.join([ '', "PR test command '`%s`' executed!" % cmd, "* exit code: %s" % ec, "* output:", "```", out.strip(), "```", '', "Test results coming soon (I hope)...", ]) else: reply_msg = "Got message \"%s\", but I don't know what to do with it, sorry..." % msg # always include 'details' part than includes a check string # which includes the ID of the comment we're reacting to, # so we can avoid re-processing the same comment again... reply_msg += '\n'.join([ '', '', "<details>", '', "*- %s*" % check_str, '', "*Message to humans: this is just bookkeeping information for me,", "it is of no use to you (unless you think I have a bug, which I don't).*", "</details>", ]) comment(github, github_user, repository, pr_data, reply_msg, verbose=DRY_RUN) else: print( "Pattern '%s' not found in comment for PR #%s, so ignoring it" % (host_regex.pattern, pr_id)) mention_found = True break else: # skip irrelevant comments (no mention found) print( "Pattern '%s' not found in comment for PR #%s, so ignoring it" % (mention_regex.pattern, pr_id)) continue if not mention_found: print_warning( "Relevant comment for notification #%d for PR %s not found?!" % (idx, pr_id)) sys.stderr.write("Notification data:\n" + pformat(notification)) return res
def session_state(): """Get session state: timestamp, dump of environment, system info.""" return {"time": gmtime(), "environment": copy.deepcopy(os.environ), "system_info": get_system_info()}
def process_notifications(notifications, github, github_user, github_account, repository, host, pr_test_cmd): """Process provided notifications.""" res = [] cnt = len(notifications) for idx, notification in enumerate(notifications): pr_title = notification['subject']['title'] pr_id = notification['subject']['url'].split('/')[-1] msg = "[%d/%d] Processing notification for %s PR #%s \"%s\"... " % ( idx + 1, cnt, repository, pr_id, pr_title) msg += "(thread id: %s, timestamp: %s)" % (notification['thread_id'], notification['timestamp']) print(msg) # check comments (latest first) pr_data, _ = fetch_pr_data(pr_id, github_account, repository, github_user, full=True) comments_data = pr_data['issue_comments'] # determine comment that triggered the notification trigger_comment_id = None mention_regex = re.compile(r'\s*@%s:?\s*' % github_user, re.M) for comment_data in comments_data[::-1]: comment_id, comment_txt = comment_data['id'], comment_data['body'] if mention_regex.search(comment_txt): trigger_comment_id = comment_id break check_str = "notification for comment with ID %s processed" % trigger_comment_id processed = False for comment_data in comments_data[::-1]: comment_by, comment_txt = comment_data['user'][ 'login'], comment_data['body'] if comment_by == github_user and check_str in comment_txt: processed = True break if processed: msg = "Notification %s already processed, so skipping it... " % notification[ 'thread_id'] msg += "(timestamp: %s)" % notification['timestamp'] print(msg) continue host_regex = re.compile(r'@.*%s' % host, re.M) mention_found = False for comment_data in comments_data[::-1]: comment_id, comment_by = comment_data['id'], comment_data['user'][ 'login'] comment_txt = comment_data['body'] if mention_regex.search(comment_txt): print("Found comment including '%s': %s" % (mention_regex.pattern, comment_txt)) msg = mention_regex.sub('', comment_txt) # require that @<host> is included in comment before taking any action if host_regex.search(msg): print("Comment includes '%s', so processing it..." % host_regex.pattern) allowed_accounts = [ 'boegel', 'casparvl', 'smoors', 'verdurin' ] if comment_by not in allowed_accounts: allowed_accounts_str = ' or '.join( '@%s' % x for x in allowed_accounts) reply_msg = "@%s: I noticed your comment, " % comment_by reply_msg += "but I only dance when %s tells me (for now), I'm sorry..." % allowed_accounts_str elif "please test" in msg: system_info = get_system_info() hostname = system_info.get('hostname', '(hostname not known)') reply_msg = "@%s: Request for testing this PR well received on %s\n" % ( comment_by, hostname) tmpl_dict = {'pr': pr_id} # check whether custom arguments for 'eb' command are specified eb_args_regex = re.compile(r'EB_ARGS=(?P<eb_args>.*)$', re.M) res = eb_args_regex.search(msg) if res: eb_args = res.group('eb_args').replace('"', '\\"') tmpl_dict.update({'eb_args': '"%s"' % eb_args}) else: tmpl_dict.update({'eb_args': ''}) # run pr test command, check exit code and capture output cmd = pr_test_cmd % tmpl_dict (out, ec) = run_cmd(cmd, simple=False) reply_msg += '\n'.join([ '', "PR test command '`%s`' executed!" % cmd, "* exit code: %s" % ec, "* output:", "```", out.strip(), "```", '', "Test results coming soon (I hope)...", ]) else: reply_msg = "Got message \"%s\", but I don't know what to do with it, sorry..." % msg # always include 'details' part than includes a check string # which includes the ID of the comment we're reacting to, # so we can avoid re-processing the same comment again... reply_msg += '\n'.join([ '', '', "<details>", '', "*- %s*" % check_str, '', "*Message to humans: this is just bookkeeping information for me,", "it is of no use to you (unless you think I have a bug, which I don't).*", "</details>", ]) comment(github, github_user, repository, pr_data, reply_msg, verbose=DRY_RUN) else: print( "Pattern '%s' not found in comment for PR #%s, so ignoring it" % (host_regex.pattern, pr_id)) mention_found = True break else: # skip irrelevant comments (no mention found) print( "Pattern '%s' not found in comment for PR #%s, so ignoring it" % (mention_regex.pattern, pr_id)) continue if not mention_found: print_warning( "Relevant comment for notification #%d for PR %s not found?!" % (idx, pr_id)) sys.stderr.write("Notification data:\n" + pformat(notification)) return res