From 2b5642259eb7ca590ce34579b979fbdd6116af94 Mon Sep 17 00:00:00 2001 From: "Pawel Hajdan, Jr" Date: Sun, 16 Oct 2011 05:49:45 +0200 Subject: Improve batch stabilization: - only update bugzilla once per bug - keyword all packages for each bug first, then commit (in case packages stabilized in single bug depend on each other, so that we don't need to worry about their order) - cosmetic logging improvements --- batch-stabilize.py | 87 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/batch-stabilize.py b/batch-stabilize.py index 912d26b..b76bac7 100755 --- a/batch-stabilize.py +++ b/batch-stabilize.py @@ -17,7 +17,7 @@ BUG_REGEX = re.compile("[Bb]ug #?(\d+)") def print_and_log(message, log): try: print message - log.write(message) + log.write(message + '\n') finally: log.flush() @@ -59,7 +59,7 @@ if __name__ == "__main__": bugzilla.auth() with open(options.input_filename, "r") as input_file: - stabilization_list = [] + stabilization_dict = {} bug_id = -1 for line in input_file: if line == "\n": @@ -84,54 +84,67 @@ if __name__ == "__main__": p = portage.versions.catsplit(cpv)[1] pn = portage.versions.pkgsplit(cpv)[0] ebuild_name = p + ".ebuild" - stabilization_list.append((pn, ebuild_name, bug_id)) + if bug_id not in stabilization_dict: + stabilization_dict[bug_id] = [] + stabilization_dict[bug_id].append((pn, ebuild_name)) # Sanity check. success = True - for pn, ebuild_name, bug_id in stabilization_list: - ebuild_path = os.path.join(options.repo, pn, ebuild_name) - if not os.path.exists(ebuild_path): - print '%s: file does not exist' % ebuild_path - success = False + for bug_id in stabilization_dict: + for (pn, ebuild_name) in stabilization_dict[bug_id]: + ebuild_path = os.path.join(options.repo, pn, ebuild_name) + if not os.path.exists(ebuild_path): + print '%s: file does not exist' % ebuild_path + success = False if not success: print 'Sanity check failed. Please make sure your CVS repo is up to date (cvs up).' sys.exit(1) with open('batch-stabilize.log', 'w') as log_file: - for pn, ebuild_name, bug_id in stabilization_list: + for bug_id in stabilization_dict: + print_and_log('Working on bug %d...' % bug_id, log_file) commit_message = "%s stable wrt bug #%d" % (options.arch, bug_id) - cvs_path = os.path.join(options.repo, pn) - print_and_log('Working in %s...' % cvs_path, log_file) - if run_command(["cvs", "up"], cvs_path, log_file)[0] != 0: - print '!!! cvs up failed' - sys.exit(1) - if run_command(["ekeyword", options.arch, ebuild_name], cvs_path, log_file)[0] != 0: - print '!!! ekeyword failed' - sys.exit(1) - return_code, output = run_command(["cvs", "diff"], cvs_path, log_file) - # It seems that cvs diff returns 1 if there are differences. - if return_code == 0 and not output: - print_and_log('Seems already keyworded, skipping.', log_file) - continue - if run_command(["echangelog", commit_message], cvs_path, log_file)[0] != 0: - print '!!! ekeyword failed' - sys.exit(1) - if run_command(["repoman", "manifest"], cvs_path, log_file)[0] != 0: - print '!!! repoman manifest failed' - sys.exit(1) - if run_command(["repoman", "full"], cvs_path, log_file)[0] != 0: - print '!!! repoman full failed' - sys.exit(1) - if run_command(["repoman", "commit", "-m", commit_message], cvs_path, log_file)[0] != 0: - print '!!! repoman full failed' - sys.exit(1) - log_file.write('Posting automated reply in bugzilla...\n') + for (pn, ebuild_name) in stabilization_dict[bug_id]: + cvs_path = os.path.join(options.repo, pn) + print_and_log('Working in %s...' % cvs_path, log_file) + if run_command(["cvs", "up"], cvs_path, log_file)[0] != 0: + print '!!! cvs up failed' + sys.exit(1) + if run_command(["ekeyword", options.arch, ebuild_name], cvs_path, log_file)[0] != 0: + print '!!! ekeyword failed' + sys.exit(1) + for (pn, ebuild_name) in stabilization_dict[bug_id]: + cvs_path = os.path.join(options.repo, pn) + print_and_log('Working in %s...' % cvs_path, log_file) + return_code, output = run_command(["cvs", "diff"], cvs_path, log_file) + # It seems that cvs diff returns 1 if there are differences. + if return_code == 0 and not output: + print_and_log('Seems already keyworded, skipping.', log_file) + continue + if run_command(["echangelog", commit_message], cvs_path, log_file)[0] != 0: + print '!!! echangelog failed' + sys.exit(1) + if run_command(["repoman", "manifest"], cvs_path, log_file)[0] != 0: + print '!!! repoman manifest failed' + sys.exit(1) + if run_command(["repoman", "commit", "-m", commit_message], cvs_path, log_file)[0] != 0: + print '!!! repoman commit failed' + sys.exit(1) bug_xml = bugzilla.get(bug_id).find('bug') + has_my_arch = False has_other_arches = False for cc in bug_xml.findall('cc'): body, domain = cc.text.split('@', 1) + if domain == 'gentoo.org' and body == options.arch: + has_my_arch = True if domain == 'gentoo.org' and body in portage.archlist and body != options.arch: has_other_arches=True + + if not has_my_arch: + print_and_log('Seems that bugzilla has already been updated.', log_file) + continue + + print_and_log('Posting automated reply in bugzilla...', log_file) # We don't close bugs which still have other arches for obvious reasons, # and security bugs because stabilization is not the last step for them. if has_other_arches or 'Security' in bug_xml.find('product').text: @@ -139,7 +152,7 @@ if __name__ == "__main__": bug_id, comment='%s stable' % options.arch, remove_cc='%s@gentoo.org' % options.arch) - log_file.write('Successfully updated bug %d.\n' % bug_id) + print_and_log('Successfully updated bug %d.' % bug_id, log_file) else: bugzilla.modify( bug_id, @@ -147,4 +160,4 @@ if __name__ == "__main__": remove_cc='%s@gentoo.org' % options.arch, status='RESOLVED', resolution='FIXED') - log_file.write('Succesfully updated bug %d and closed it.\n' % bug_id) + print_and_log('Succesfully updated bug %d and closed it.' % bug_id, log_file) -- cgit v1.2.3-65-gdbad