def main(options, args): if len(args): distros = [Distro.get(a) for a in args] else: distros = Distro.all() # Run through our default distribution and use that for the base # package names. Expire from all distributions. for target in config.targets(args): d = target.distro for pkg in d.packages(target.dist, target.component): if options.package and pkg.name not in options.package: continue try: output_dir = result_dir(target, pkg.name) report = read_report(output_dir) base = report["base_version"] except ValueError: logger.exception('Skipping package %s: unable to read merge ' 'report', pkg.name) continue if report['result'] not in (MergeResult.SYNC_THEIRS, MergeResult.KEEP_OURS, MergeResult.MERGED, MergeResult.CONFLICTS): logger.debug('Skipping expiry for package %s: result=%s', pkg.name, report['result']) continue if base is None: # If there's no suitable base for merges, we don't # automatically expire any versions. logger.debug('Skipping expiry for package %s: ' 'no base version found (result=%s)', pkg.name, report['result']) continue base = Version(base) logger.debug("%s base is %s", pkg.name, base) for distro in distros: if distro.shouldExpire(): for component in distro.components(): try: distro_pkg = distro.package(target.dist, component, pkg.name) expire_pool_sources(distro_pkg, base) except PackageNotFound: continue
def main(options, args): if len(args): distros = [Distro.get(a) for a in args] else: distros = Distro.all() # Run through our default distribution and use that for the base # package names. Expire from all distributions. for target in DISTRO_TARGETS.keys(): our_distro, our_dist, our_component = get_target_distro_dist_component(target) d = Distro.get(our_distro) for source in d.getSources(our_dist, our_component): if options.package and source['Package'] not in options.package: continue try: output_dir = result_dir(target, source['Package']) report = read_report(output_dir) base = report["base_version"] except ValueError: logger.debug('Skipping package %s: unable to read merge report', source['Package']) continue if report['result'] not in (MergeResult.SYNC_THEIRS, MergeResult.KEEP_OURS, MergeResult.MERGED, MergeResult.CONFLICTS): logger.debug('Skipping expiry for package %s: result=%s', source['Package'], report['result']) continue if base is None: # If there's no suitable base for merges, we don't # automatically expire any versions. logger.debug('Skipping expiry for package %s: ' 'no base version found (result=%s)', source['Package'], report['result']) continue logger.debug("%s %s", source["Package"], source["Version"]) logger.debug("base is %s", base) for distro in distros: if distro.shouldExpire(): for component in distro.components(): expire_pool_sources(distro, component, source["Package"], base)
def main(options, args): logger.debug('Sending email if actions are needed...') for target in config.targets(args): logger.debug('%r', target) d = target.distro if not isinstance(d, OBSDistro): logger.debug('Skipping %r distro %r: not an OBSDistro', target, d) continue for pkg in d.packages(target.dist, target.component): if options.package and pkg.name not in options.package: logger.debug('Skipping package %s: not selected', pkg.name) continue if pkg.name in target.blacklist: logger.debug('Skipping package %s: blacklisted', pkg.name) continue try: output_dir = result_dir(target.name, pkg.name) report = read_report(output_dir) except ValueError: logger.debug('Skipping package %s: unable to read report', pkg.name) continue if report.result == MergeResult.KEEP_OURS: logger.debug('Skipping package %s: result=%s', pkg.name, report.result) continue if (target.committable and report.result in (MergeResult.MERGED, MergeResult.SYNC_THEIRS)): logger.debug('Skipping package %s: result=%s, would already ' 'have been committed', pkg.name, report.result) continue try: notify_action_needed(target, output_dir, report) except Exception: logger.exception('Error processing %s:', pkg.name)
def main(options, args): logger.info('Producing merges...') excludes = [] if options.exclude is not None: for filename in options.exclude: logger.info('excluding packages from %s', filename) excludes.extend(read_package_list(filename)) includes = [] if options.include is not None: for filename in options.include: logger.info('including packages from %s', filename) includes.extend(read_package_list(filename)) # For each package in the destination distribution, locate the latest in # the source distribution; calculate the base from the destination and # produce a merge combining both sets of changes for target in config.targets(args): logger.info('considering target %s', target) our_dist = target.dist our_component = target.component d = target.distro for pkg in d.packages(target.dist, target.component): if options.package is not None and pkg.name not in options.package: logger.debug('skipping package %s: not the selected package', pkg.name) continue if len(includes) and pkg.name not in includes: logger.info('skipping package %s: not in include list', pkg.name) continue if len(excludes) and pkg.name in excludes: logger.info('skipping package %s: in exclude list', pkg.name) continue if pkg.name in target.blacklist: logger.info("%s is blacklisted, skipping", pkg.name) continue logger.info('considering package %s', pkg.name) if options.version: our_version = Version(options.version) logger.debug('our version: %s (from command line)', our_version) else: our_version = pkg.newestVersion() logger.debug('our version: %s', our_version) upstream = None for srclist in target.getSourceLists(pkg.name, include_unstable=False): for src in srclist: logger.debug('considering source %s', src) try: for possible in src.distro.findPackage(pkg.name, searchDist=src.dist): logger.debug('- contains version %s', possible) if upstream is None or possible > upstream: logger.debug(' - that version is the best yet seen') upstream = possible except model.error.PackageNotFound: pass output_dir = result_dir(target.name, pkg.name) # There are two situations in which we will look in unstable distros # for a better version: try_unstable = False # 1. If our version is newer than the stable upstream version, we # assume that our version was sourced from unstable, so let's # check for an update there. # However we must use the base version for the comparison here, # otherwise we would consider our version 1.0-1endless1 newer # than the stable 1.0-1 and look in unstable for an update. if upstream is not None and our_version >= upstream: our_base_version = our_version.version.base() logger.info("our version %s >= their version %s, checking base version %s", our_version, upstream, our_base_version) if our_base_version > upstream.version: logger.info("base version still newer than their version, checking in unstable") try_unstable = True # 2. If we didn't find any upstream version at all, it's possible # that it's a brand new package where our version was imported # from unstable, so let's see if we can find a better version # there. if upstream is None: try_unstable = True # However, if this package has been assigned a specific source, # we'll honour that. if target.packageHasSpecificSource(pkg.name): try_unstable = False if try_unstable: for srclist in target.unstable_sources: for src in srclist: logger.debug('considering unstable source %s', src) try: for possible in src.distro.findPackage(pkg.name, searchDist=src.dist): logger.debug('- contains version %s', possible) if upstream is None or possible > upstream: logger.debug(' - that version is the best yet seen') upstream = possible except model.error.PackageNotFound: pass if upstream is None: logger.info("%s not available upstream, skipping", our_version) cleanup(output_dir) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.KEEP_OURS report.merged_version = our_version.version report.write_report(output_dir) continue try: report = read_report(output_dir) # See if sync_upstream_packages already set if not options.force and \ pkg.name in target.sync_upstream_packages and \ Version(report['right_version']) == upstream.version and \ Version(report['left_version']) == our_version.version and \ Version(report['merged_version']) == upstream.version and \ report['result'] == MergeResult.SYNC_THEIRS: logger.info("sync to upstream for %s [ours=%s, theirs=%s] " "already produced, skipping run", pkg, our_version.version, upstream.version) continue elif (not options.force and Version(report['right_version']) == upstream.version and Version(report['left_version']) == our_version.version and # we'll retry the merge if there was an unexpected # failure, a missing base or an unknown result last time report['result'] in (MergeResult.KEEP_OURS, MergeResult.SYNC_THEIRS, MergeResult.MERGED, MergeResult.CONFLICTS)): logger.info("merge for %s [ours=%s, theirs=%s] already produced, skipping run", pkg, our_version.version, upstream.version) continue except (AttributeError, ValueError, KeyError): pass if our_version >= upstream: logger.info("our version %s >= their version %s, skipping", our_version, upstream) cleanup(output_dir) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.KEEP_OURS report.merged_version = our_version.version report.write_report(output_dir) continue elif our_version < upstream and \ pkg.name in target.sync_upstream_packages: logger.info("Syncing to %s per sync_upstream_packages", upstream) cleanup(output_dir) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.SYNC_THEIRS report.merged_version = upstream.version report.message = "Using version in upstream distro per " \ "sync_upstream_packages configuration" report.write_report(output_dir) continue logger.info("local: %s, upstream: %s", our_version, upstream) try: produce_merge(target, our_version, upstream, output_dir) except ValueError as e: logger.exception("Could not produce merge, perhaps %s changed components upstream?", pkg) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.FAILED report.message = 'Could not produce merge: %s' % e report.write_report(output_dir) continue
def handle_package(options, output_dir, target, pkg, our_version): update_info = UpdateInfo(pkg) if update_info.version is None: logger.error('UpdateInfo version %s does not match our version %s"', update_info.version, our_version) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.FAILED report.message = 'Could not find update info for version %s' % \ our_version return report if update_info.upstream_version is None \ or our_version.version >= update_info.upstream_version: logger.debug("No updated upstream version available for %s", our_version) cleanup(output_dir) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.KEEP_OURS report.merged_version = our_version.version return report if update_info.base_version is None: logger.info("No base version available for %s", our_version) cleanup(output_dir) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.NO_BASE return report upstream = target.findSourcePackage(pkg.name, update_info.upstream_version) if not upstream: logger.error('Could not find upstream version %s in pool', update_info.upstream_version) cleanup(output_dir) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.FAILED report.message = 'Could not find upstream version %s in pool' % \ update_info.upstream_version return report upstream = upstream[0] base = None pool_versions = target.getAllPoolVersions(pkg.name) for pv in pool_versions: if pv.version == update_info.base_version: base = pv if base is None: logger.error('Could not find base version %s in pool', update_info.base_version) cleanup(output_dir) report = MergeReport(left=our_version) report.target = target.name report.result = MergeResult.FAILED report.message = 'Could not find base version %s in pool' % \ update_info.base_version return report try: report = read_report(output_dir) # See if sync_upstream_packages already set if not options.force and \ pkg.name in target.sync_upstream_packages and \ Version(report['right_version']) == upstream.version and \ Version(report['left_version']) == our_version.version and \ Version(report['merged_version']) == upstream.version and \ report['result'] == MergeResult.SYNC_THEIRS: logger.info("sync to upstream for %s [ours=%s, theirs=%s] " "already produced, skipping run", pkg, our_version.version, upstream.version) return None elif (not options.force and Version(report['right_version']) == upstream.version and Version(report['left_version']) == our_version.version and # we'll retry the merge if there was an unexpected # failure, a missing base or an unknown result last time report['result'] in (MergeResult.KEEP_OURS, MergeResult.SYNC_THEIRS, MergeResult.MERGED, MergeResult.CONFLICTS)): logger.info("merge for %s [ours=%s, theirs=%s] already produced, " "skipping run", pkg, our_version.version, upstream.version) return None except (AttributeError, ValueError, KeyError): pass if pkg.name in target.sync_upstream_packages: logger.info("Syncing to %s per sync_upstream_packages", upstream) cleanup(output_dir) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.SYNC_THEIRS report.merged_version = upstream.version report.message = "Using version in upstream distro per " \ "sync_upstream_packages configuration" if update_info.specific_upstream: report.notes.append('Synced with specific upstream %s due to ' 'runtime parameters' % update_info.specific_upstream) return report if options.sync_to_upstream: logger.info("Syncing to %s per command line", upstream) cleanup(output_dir) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.SYNC_THEIRS report.merged_version = upstream.version if update_info.specific_upstream: report.notes.append('Synced with specific upstream %s due to ' 'runtime parameters' % update_info.specific_upstream) else: report.notes.append('Force-synced to upstream due to runtime ' 'parameters') return report logger.info("local: %s, upstream: %s", our_version, upstream) try: report = produce_merge(target, base, our_version, upstream, output_dir) if update_info.specific_upstream: report.notes.append('Merged with specific upstream %s due to ' 'runtime parameters' % update_info.specific_upstream) return report except ValueError as e: logger.exception("Could not produce merge, " "perhaps %s changed components upstream?", pkg) report = MergeReport(left=our_version, right=upstream) report.target = target.name report.result = MergeResult.FAILED report.message = 'Could not produce merge: %s' % e return report
def main(options, args): logger.debug('Committing merges...') for target in config.targets(args): d = target.distro if not isinstance(d, OBSDistro): logger.debug('Skipping %r distro %r: not an OBSDistro', target, d) continue for source in d.newestSources(target.dist, target.component): if options.package and source['Package'] not in options.package: logger.debug('Skipping package %s: not selected', source['Package']) continue if source['Package'] in target.blacklist: logger.debug('Skipping package %s: blacklisted', source['Package']) continue try: output_dir = result_dir(target.name, source['Package']) report = read_report(output_dir) except ValueError: logger.debug('Skipping package %s: unable to read report', source['Package']) continue package = d.package(target.dist, target.component, report.source_package) if report['committed']: if options.force: logger.info("Forcing commit of %s", package) else: logger.debug("%s already committed, skipping!", package) continue if report['result'] not in (MergeResult.MERGED, MergeResult.SYNC_THEIRS): logger.debug("%s has nothing to commit: result=%s", package, report['result']) continue filepaths = report['merged_files'] if filepaths == []: logger.warning("Empty merged file list in %s/REPORT" % output_dir) continue if target.committable: # we can commit directly to the target distribution # FIXME: is this still a supported configuration? I wouldn't # want to commit automated merges without some sort of manual # check on the debdiff... logger.info("Committing changes to %s", package) if not options.dry_run: try: package.commit('Automatic update by Merge-O-Matic') except urllib2.HTTPError as e: logger.exception('Failed to commit %s: HTTP error %s at <%s>:', package, e.code, e.geturl()) update_report(report, output_dir, False, "HTTP error %s" % e.code) except Exception as e: logger.exception('Failed to commit %s:', package) # deliberately rather vague, as below update_report(report, output_dir, False, "%s" % e.__class__.__name__) else: update_report(report, output_dir, True, committed_to=d.obsProject(target.dist, target.component)) continue # else we need to branch it and commit to the branch try: logger.debug("Branching %s", package) branchPkg = package.branch("home:%s:branches"%(d.obsUser)) branch = branchPkg.distro branch.sync(target.dist, target.component, [branchPkg,]) logger.info("Committing changes to %s, and submitting merge request to %s", branchPkg, package) if report['result'] == MergeResult.SYNC_THEIRS: srcDistro = Distro.get(report['right_distro']) version = Version(report['right_version']) logger.debug('Copying updated upstream version %s from %r into %r', version, srcDistro, target) for upstream in target.getSourceLists(package.name): for src in upstream: srcDistro = src.distro try: pkg = srcDistro.findPackage(package.name, searchDist=src.dist, version=version)[0] pfx = pkg.poolDirectory().path break except model.error.PackageNotFound: pass else: logger.debug('Copying merged version from %r into %r', branch, target) pfx = result_dir(target.name, package.name) # this might raise an error obsFiles = branchPkg.getOBSFiles() # Get the linked target files since the checkout is expanded # and may contain them linkedFiles = package.getOBSFiles() for f in obsFiles: if f.endswith(".dsc"): oldDsc = '%s/%s'%(branchPkg.obsDir(), f) break for f in filepaths: if f.endswith(".dsc"): newDsc = '%s/%s'%(pfx, f) break #logger.debug("Running debdiff on %s and %s", oldDsc, newDsc) #comment = shell.get(("debdiff", oldDsc, newDsc), okstatus=(0,1)) # FIXME: Debdiff needs implemented in OBS, as large merge descriptions break clucene. comment = '' if report['result'] == MergeResult.SYNC_THEIRS: comment += 'Sync to ' elif report['result'] == MergeResult.MERGED: comment += 'Merge with ' comment += 'version %s from %s %s' %(report['right_version'], report['right_distro'], report['right_suite']) comment += "\n\nMerge report is available at %s"%('/'.join((config.get('MOM_URL'), subdir(config.get('ROOT'), output_dir), 'REPORT.html'))) # The newlines seem to cause create_submit_request to send # UTF-32 over the wire, which OBS promptly chokes on. Encode # the message to UTF-8 first. comment = comment.encode('utf-8') if not options.dry_run: filesUpdated = False for f in obsFiles + linkedFiles: if f == "_link": continue try: logger.debug('deleting %s/%s', branchPkg.obsDir(), f) os.unlink('%s/%s'%(branchPkg.obsDir(), f)) filesUpdated = True except OSError: pass for f in filepaths: if f == "_link": continue logger.debug('copying %s/%s -> %s', pfx, f, branchPkg.obsDir()) shutil.copy2("%s/%s"%(pfx, f), branchPkg.obsDir()) filesUpdated = True if filesUpdated: logger.debug('Submitting request to merge %r from %r into %r', branchPkg, branch, target) try: branchPkg.commit('Automatic update by Merge-O-Matic') obs_project = d.obsProject(target.dist, target.component) reqid = branchPkg.submitMergeRequest(obs_project, comment) update_report(report, output_dir, True, committed_to=obs_project, request_url=branchPkg.webMergeRequest(reqid)) except xml.etree.cElementTree.ParseError: logger.exception("Failed to commit %s", branchPkg) update_report(report, output_dir, False, "OBS API Error") except urllib2.HTTPError as e: logger.exception("Failed to commit %s: HTTP error %s at <%s>:", branchPkg, e.code, e.geturl()) update_report(report, output_dir, False, "HTTP error %s" % e.code) except Exception as e: logger.exception("Failed to commit %s", branchPkg) # deliberately being a bit vague here in case the exact # exception leaks internal info update_report(report, output_dir, False, "%s" % e.__class__.__name__) else: logger.info("Not committing, due to --dry-run") except urllib2.HTTPError as e: logger.exception('Failed to branch %s: HTTP error %s at <%s>:', package, e.code, e.geturl()) update_report(report, output_dir, False, "Failed to branch: HTTP error %s" % e.code) except Exception as e: logger.exception('Failed to branch %s:', package) # deliberately being a bit vague here in case the exact # exception leaks internal info update_report(report, output_dir, False, "Failed to branch: %s" % e.__class__.__name__)
def main(options, args): logger.info('Summarizing merge status...') if options.target: targets = [options.target] else: targets = DISTRO_TARGETS.keys() outstanding = [] if os.path.isfile("%s/outstanding-merges.txt" % ROOT): after_uvf = True with open("%s/outstanding-merges.txt" % ROOT) as f: for line in f: outstanding.append(line.strip()) else: after_uvf = False SECTIONS.remove("new") # For each package in the destination distribution, find out whether # there's an open merge, and if so add an entry to the table for it. for target in targets: logger.info('Considering target %s', target) our_distro, our_dist, our_component = get_target_distro_dist_component(target) merges = [] d = Distro.get(our_distro) for source in d.getSources(our_dist, our_component): logger.debug('Considering package %s', source["Package"]) try: output_dir = result_dir(target, source["Package"]) report = read_report(output_dir) except ValueError: continue if report['result'] == MergeResult.KEEP_OURS: logger.debug('Skipping merge status for %s: result=%s', source['Package'], report['result']) continue try: priority_idx = PRIORITY.index(source["Priority"]) except (KeyError, ValueError) as e: # either it has no priority, or the priority is something # not in our array; Debian packages can end up with # Priority: source priority_idx = 0 if report["committed"]: section = "committed" elif not after_uvf: section = "outstanding" elif source["Package"] in outstanding: section = "outstanding" else: section = "new" merges.append((section, priority_idx, source["Package"], source, report["base_version"], report["left_version"], report["right_version"], report["right_distro"], output_dir, report)) merges.sort() if isinstance(d, OBSDistro): obs_project = d.obsProject(our_dist, our_component) else: obs_project = None write_status_page(target, merges, our_distro, obs_project) write_status_json(target, merges) status_file = "%s/merges/tomerge-%s" % (ROOT, target) remove_old_comments(status_file, merges) write_status_file(status_file, merges)
def main(options, args): logger.debug('Committing merges...') for target in config.targets(args): d = target.distro if not isinstance(d, OBSDistro): logger.debug('Skipping %r distro %r: not an OBSDistro', target, d) continue for package in d.packages(target.dist, target.component): if options.package and package.name not in options.package: logger.debug('Skipping package %s: not selected', package.name) continue if package.name in target.blacklist: logger.debug('Skipping package %s: blacklisted', package.name) continue try: output_dir = result_dir(target.name, pkg.name) report = read_report(output_dir) except ValueError: logger.debug('Skipping package %s: unable to read report', package.name) continue if report['committed']: if options.force: logger.info("Forcing commit of %s", package) else: logger.debug("%s already committed, skipping!", package) continue if report['result'] not in (MergeResult.MERGED, MergeResult.SYNC_THEIRS): logger.debug("%s has nothing to commit: result=%s", package, report['result']) continue filepaths = report['merged_files'] if filepaths == []: logger.warning("Empty merged file list in %s/REPORT" % output_dir) continue if target.committable: # we can commit directly to the target distribution # FIXME: is this still a supported configuration? I wouldn't # want to commit automated merges without some sort of manual # check on the debdiff... logger.info("Committing changes to %s", package) if not options.dry_run: try: package.commit('Automatic update by Merge-O-Matic') except urllib2.HTTPError as e: logger.exception('Failed to commit %s: HTTP error %s at <%s>:', package, e.code, e.geturl()) update_report(report, output_dir, False, "HTTP error %s" % e.code) except Exception as e: logger.exception('Failed to commit %s:', package) # deliberately rather vague, as below update_report(report, output_dir, False, "%s" % e.__class__.__name__) else: update_report(report, output_dir, True, committed_to=d.obsProject(target.dist, target.component)) continue # else we need to branch it and commit to the branch try: logger.debug("Branching %s", package) branchPkg = package.branch("home:%s:branches"%(d.obsUser)) branch = branchPkg.distro branch.sync(target.dist, target.component, [branchPkg,]) logger.info("Committing changes to %s, and submitting merge request to %s", branchPkg, package) if report['result'] == MergeResult.SYNC_THEIRS: srcDistro = Distro.get(report['right_distro']) version = Version(report['right_version']) logger.debug('Copying updated upstream version %s from %r into %r', version, srcDistro, target) for upstream in target.getSourceLists(package.name): for src in upstream: srcDistro = src.distro try: pkg = srcDistro.findPackage(package.name, searchDist=src.dist, version=version)[0] pfx = pkg.poolPath break except model.error.PackageNotFound: pass else: logger.debug('Copying merged version from %r into %r', branch, target) pfx = result_dir(target.name, package.name) # this might raise an error obsFiles = branchPkg.getOBSFiles() # Get the linked target files since the checkout is expanded # and may contain them linkedFiles = package.getOBSFiles() for f in obsFiles: if f.endswith(".dsc"): oldDsc = '%s/%s'%(branchPkg.obsDir(), f) break for f in filepaths: if f.endswith(".dsc"): newDsc = '%s/%s'%(pfx, f) break #logger.debug("Running debdiff on %s and %s", oldDsc, newDsc) #comment = shell.get(("debdiff", oldDsc, newDsc), okstatus=(0,1)) # FIXME: Debdiff needs implemented in OBS, as large merge descriptions break clucene. comment = '' if report['result'] == MergeResult.SYNC_THEIRS: comment += 'Sync to ' elif report['result'] == MergeResult.MERGED: comment += 'Merge with ' comment += 'version %s from %s %s' %(report['right_version'], report['right_distro'], report['right_suite']) comment += "\n\nMerge report is available at %s"%('/'.join((config.get('MOM_URL'), subdir(config.get('ROOT'), output_dir), 'REPORT.html'))) # The newlines seem to cause create_submit_request to send # UTF-32 over the wire, which OBS promptly chokes on. Encode # the message to UTF-8 first. comment = comment.encode('utf-8') if not options.dry_run: filesUpdated = False for f in obsFiles + linkedFiles: if f == "_link": continue try: logger.debug('deleting %s/%s', branchPkg.obsDir(), f) os.unlink('%s/%s'%(branchPkg.obsDir(), f)) filesUpdated = True except OSError: pass for f in filepaths: if f == "_link": continue logger.debug('copying %s/%s -> %s', pfx, f, branchPkg.obsDir()) shutil.copy2("%s/%s"%(pfx, f), branchPkg.obsDir()) filesUpdated = True if filesUpdated: logger.debug('Submitting request to merge %r from %r into %r', branchPkg, branch, target) try: branchPkg.commit('Automatic update by Merge-O-Matic') obs_project = d.obsProject(target.dist, target.component) reqid = branchPkg.submitMergeRequest(obs_project, comment) update_report(report, output_dir, True, committed_to=obs_project, request_url=branchPkg.webMergeRequest(reqid)) except xml.etree.cElementTree.ParseError: logger.exception("Failed to commit %s", branchPkg) update_report(report, output_dir, False, "OBS API Error") except urllib2.HTTPError as e: logger.exception("Failed to commit %s: HTTP error %s at <%s>:", branchPkg, e.code, e.geturl()) update_report(report, output_dir, False, "HTTP error %s" % e.code) except Exception as e: logger.exception("Failed to commit %s", branchPkg) # deliberately being a bit vague here in case the exact # exception leaks internal info update_report(report, output_dir, False, "%s" % e.__class__.__name__) else: logger.info("Not committing, due to --dry-run") except urllib2.HTTPError as e: logger.exception('Failed to branch %s: HTTP error %s at <%s>:', package, e.code, e.geturl()) update_report(report, output_dir, False, "Failed to branch: HTTP error %s" % e.code) except Exception as e: logger.exception('Failed to branch %s:', package) # deliberately being a bit vague here in case the exact # exception leaks internal info update_report(report, output_dir, False, "Failed to branch: %s" % e.__class__.__name__)
def main(options, args): logger.info('Summarizing merge status...') if options.target: targets = [options.target] else: targets = config.get('DISTRO_TARGETS').keys() outstanding = [] if os.path.isfile("%s/outstanding-merges.txt" % config.get('ROOT')): after_uvf = True with open("%s/outstanding-merges.txt" % config.get('ROOT')) as f: for line in f: outstanding.append(line.strip()) else: after_uvf = False SECTIONS.remove("new") # For each package in the destination distribution, find out whether # there's an open merge, and if so add an entry to the table for it. for target in targets: logger.info('Considering target %s', target) our_distro, our_dist, our_component = get_target_distro_dist_component( target) merges = [] d = Distro.get(our_distro) for source in d.getSources(our_dist, our_component): logger.debug('Considering package %s', source["Package"]) try: output_dir = result_dir(target, source["Package"]) report = read_report(output_dir) except ValueError: continue if report['result'] == MergeResult.KEEP_OURS: logger.debug('Skipping merge status for %s: result=%s', source['Package'], report['result']) continue try: priority_idx = PRIORITY.index(source["Priority"]) except (KeyError, ValueError) as e: # either it has no priority, or the priority is something # not in our array; Debian packages can end up with # Priority: source priority_idx = 0 if report["committed"]: section = "committed" elif not after_uvf: section = "outstanding" elif source["Package"] in outstanding: section = "outstanding" else: section = "new" merges.append((section, priority_idx, source["Package"], source, report["base_version"], report["left_version"], report["right_version"], report["right_distro"], output_dir, report)) merges.sort() if isinstance(d, OBSDistro): obs_project = d.obsProject(our_dist, our_component) else: obs_project = None write_status_page(target, merges, our_distro, obs_project) write_status_json(target, merges) status_file = "%s/merges/tomerge-%s" % (config.get('ROOT'), target) remove_old_comments(status_file, merges) write_status_file(status_file, merges)