def osrt_origin_list(apiurl, opts, *args): lookup = osrt_origin_lookup(apiurl, opts.project, opts.force_refresh, quiet=opts.format != 'plain') if opts.format != 'plain': # Suppliment data with request information. requests = get_request_list(apiurl, opts.project, None, None, ['new', 'review'], 'submit') requests.extend(get_request_list(apiurl, opts.project, None, None, ['new', 'review'], 'delete')) requests_map = {} for request in requests: for action in request.actions: requests_map[action.tgt_package] = request.reqid # Convert data from lookup to list. out = [] for package, details in sorted(lookup.items()): out.append({ 'package': package, 'origin': details['origin'], 'revisions': details.get('revisions', []), 'request': requests_map.get(package), }) osrt_origin_dump(opts.format, out) return line_format = '{:<' + str(osrt_origin_max_key(lookup, 7)) + '} {}' print(line_format.format('package', 'origin')) for package, details in sorted(lookup.items()): print(line_format.format(package, details['origin']))
def test_no_source_maintainer(self): """Declines the request when the 'required_maintainer' is not maintainer of the source project Create also request to add required maintainers to source project unless it is already open """ self._setup_devel_project() # Change the required maintainer self.wf.create_group(FACTORY_MAINTAINERS.replace('group:', '')) self.wf.remote_config_set( {'required-source-maintainer': FACTORY_MAINTAINERS}) req = self.wf.create_submit_request(SRC_PROJECT, 'blowfish', add_commit=False) self.assertReview(req.reqid, by_user=(self.bot_user, 'new')) self.review_bot.set_request_ids([req.reqid]) self.review_bot.check_requests() review = self.assertReview(req.reqid, by_user=(self.bot_user, 'declined')) add_role_req = get_request_list(self.wf.apiurl, SRC_PROJECT, req_state=['new'], req_type='add_role')[0] self.assertIn( 'unless %s is a maintainer of %s' % (FACTORY_MAINTAINERS, SRC_PROJECT), review.comment) self.assertIn('Created the add_role request %s' % add_role_req.reqid, review.comment) self.assertEqual(add_role_req.actions[0].tgt_project, SRC_PROJECT) self.assertEqual('Created automatically from request %s' % req.reqid, add_role_req.description) # reopen request and do it again to test that new add_role request won't be created req.change_state('new') self.review_bot.check_requests() add_role_reqs = get_request_list(self.wf.apiurl, SRC_PROJECT, req_state=['new'], req_type='add_role') self.assertEqual(len(add_role_reqs), 1)
def requests(args): apiurl = osc.conf.config['apiurl'] devel_projects = devel_projects_load(args) # Disable including source project in get_request_list() query. osc.conf.config['include_request_from_project'] = False for devel_project in devel_projects: requests = get_request_list(apiurl, devel_project, req_state=('new', 'review'), req_type='submit', withfullhistory=True) for request in requests: action = request.actions[0] age = request_age(request).days if age < args.min_age: continue print(' '.join(( request.reqid, '/'.join((action.tgt_project, action.tgt_package)), '/'.join((action.src_project, action.src_package)), '({} days old)'.format(age), ))) if args.remind: remind_comment(apiurl, args.repeat_age, request.reqid, action.tgt_project, action.tgt_package)
def requests(args): apiurl = osc.conf.config['apiurl'] devel_projects = devel_projects_load(args) # Disable including source project in get_request_list() query. osc.conf.config['include_request_from_project'] = False for devel_project in devel_projects: requests = get_request_list(apiurl, devel_project, req_state=('new', 'review'), req_type='submit', withfullhistory=True) for request in requests: action = request.actions[0] age = request_age(request).days if age < args.min_age: continue print(' '.join(( request.reqid, '/'.join((action.tgt_project, action.tgt_package)), '/'.join((action.src_project, action.src_package)), '({} days old)'.format(age), ))) if args.remind: remind_comment(apiurl, args.repeat_age, request.reqid, action.tgt_project, action.tgt_package)
def sle_workarounds_unneeded_check(self, package): # If SLE-workarounds project and package was not sourced from # SLE-workarounds, but it does exist in SLE-workarounds. if (self.sle_workarounds and not self.sle_workarounds_sourced and package in self.packages[self.sle_workarounds]): # Determine how recently the package was updated. root = ET.fromstringlist( get_commitlog(self.apiurl, self.sle_workarounds, package, None, format='xml')) updated_last = date_parse(root.find('logentry/date').text) age = datetime.now() - updated_last if age.total_seconds() < 3600 * 24: logger.debug( 'skip removal of {}/{} since updated within 24 hours'. format(self.sle_workarounds, package)) return requests = get_request_list(self.apiurl, self.sle_workarounds, package, req_type='submit') if len(requests): logger.debug('existing submit request involving {}/{}'.format( self.sle_workarounds, package)) return self.delete_request( self.sle_workarounds, package, 'sourced from {}'.format(self.lookup.get(package)))
def requests(args): apiurl = osc.conf.config['apiurl'] devel_projects = devel_projects_load(args) for devel_project in devel_projects: requests = get_request_list( apiurl, devel_project, req_state=('new', 'review'), req_type='submit', # Seems to work backwards, as it includes only. exclude_target_projects=[devel_project], withfullhistory=True) for request in requests: action = request.actions[0] age = request_age(request).days if age < args.min_age: continue print(' '.join(( request.reqid, '/'.join((action.tgt_project, action.tgt_package)), '/'.join((action.src_project, action.src_package)), '({} days old)'.format(age), ))) if args.remind: remind_comment(apiurl, args.repeat_age, request.reqid, action.tgt_project, action.tgt_package)
def origin_find_fallback(apiurl, target_project, package, source_hash, user): # Search accepted requests (newest to oldest), find the last review made by # the specified user, load comment as annotation, and extract origin. requests = get_request_list(apiurl, target_project, package, None, ['accepted'], 'submit') for request in sorted(requests, key=lambda r: r.reqid, reverse=True): review = review_find_last(request, user) if not review: continue annotation = origin_annotation_load(review.comment) return OriginInfo(annotation.get('origin'), False) # Fallback to searching workaround project. fallback_workaround = config_load(apiurl, target_project).get('fallback-workaround') if fallback_workaround: if project_source_contain(apiurl, fallback_workaround['project'], package, source_hash): return OriginInfo(fallback_workaround['origin'], False) # Attempt to find a revision of target package that matches an origin. first = True for source_hash_consider in package_source_hash_history(apiurl, target_project, package): if first: first = False continue origin_info = origin_find( apiurl, target_project, package, source_hash_consider, pending_allow=False, fallback=False) if origin_info: return origin_info return None
def origin_find_fallback(apiurl, target_project, package, source_hash, user): # Search accepted requests (newest to oldest), find the last review made by # the specified user, load comment as annotation, and extract origin. requests = get_request_list(apiurl, target_project, package, None, ['accepted'], 'submit') for request in sorted(requests, key=lambda r: r.reqid, reverse=True): review = review_find_last(request, user) if not review: continue annotation = origin_annotation_load(review.comment) return OriginInfo(annotation.get('origin'), False) # Fallback to searching workaround project. fallback_workaround = config_load(apiurl, target_project).get('fallback-workaround') if fallback_workaround: if project_source_contain(apiurl, fallback_workaround['project'], package, source_hash): return OriginInfo(fallback_workaround['origin'], False) # Attempt to find a revision of target package that matches an origin. first = True for source_hash_consider in package_source_hash_history(apiurl, target_project, package): if first: first = False continue origin_info = origin_find( apiurl, target_project, package, source_hash_consider, pending_allow=False, fallback=False) if origin_info: return origin_info return None
def delete_request(self, project, package, message): requests = get_request_list(self.apiurl, project, package, req_type='delete') if len(requests): logger.debug('existing delete request for {}/{}'.format(project, package)) return logger.info('creating delete request for {}/{}'.format(project, package)) # No proper API function to perform the same operation. message = '"{}"'.format(message) print(subprocess.check_output( ' '.join(['osc', 'dr', '-m', message, project, package]), shell=True))
def delete_request(self, project, package, message): requests = get_request_list(self.apiurl, project, package, req_type='delete') if len(requests): logger.debug('existing delete request for {}/{}'.format(project, package)) return logger.info('creating delete request for {}/{}'.format(project, package)) # No proper API function to perform the same operation. message = '"{}"'.format(message) print(subprocess.check_output( ' '.join(['osc', 'dr', '-m', message, project, package]), shell=True))
def submitMergeRequest(self, upstreamDistro, msg): reqs = osccore.get_request_list(self.distro.config('obs', 'url'), self.distro.obsProject(self.dist, self.component), self.obsName, req_type='submit', req_state=['new', 'review']) user = self.distro.obsUser oldreqs = [ i for i in reqs if i.state.who == user ] result = osccore.create_submit_request(self.distro.config('obs', 'url'), self.distro.obsProject(self.dist, self.component), self.obsName, upstreamDistro, self.obsName, msg) for req in oldreqs: osccore.change_request_state(self.distro.config('obs', 'url'), req.reqid, 'superseded', 'superseded by %s' % result, result) return result
def request_action_simple_list(apiurl, project, package, states, request_type): # Disable including source project in get_request_list() query. before = conf.config['include_request_from_project'] conf.config['include_request_from_project'] = False requests = get_request_list(apiurl, project, package, None, states, request_type, withfullhistory=True) conf.config['include_request_from_project'] = before for request in requests: for action in request.actions: if action.tgt_project == project and action.tgt_package == package: yield request, action break
def project_source_pending(apiurl, project, package, source_hash): apiurl_remote, project_remote = project_remote_apiurl(apiurl, project) requests = get_request_list(apiurl_remote, project_remote, package, None, ['new', 'review'], 'submit') for request in requests: for action in request.actions: source_hash_consider = package_source_hash( apiurl_remote, action.src_project, action.src_package, action.src_rev) project_source_log('pending', project, source_hash_consider, source_hash) if source_hash_consider == source_hash: return PendingRequestInfo( request_remote_identifier(apiurl, apiurl_remote, request.reqid), reviews_remaining(request)) return False
def project_source_pending(apiurl, project, package, source_hash): apiurl_remote, project_remote = project_remote_apiurl(apiurl, project) requests = get_request_list(apiurl_remote, project_remote, package, None, ['new', 'review'], 'submit') for request in requests: for action in request.actions: source_hash_consider = package_source_hash( apiurl_remote, action.src_project, action.src_package, action.src_rev) project_source_log('pending', project, source_hash_consider, source_hash) if source_hash_consider == source_hash: return PendingRequestInfo( request_remote_identifier(apiurl, apiurl_remote, request.reqid), reviews_remaining(request)) return False
def __ensure_add_role_request(self, source_project): """Returns add_role request ID for given source project. Creates that add role if needed.""" try: add_roles = get_request_list(self.apiurl, source_project, req_state=['new', 'review'], req_type='add_role') add_roles = list(filter(self.__is_required_maintainer, add_roles)) if len(add_roles) > 0: return add_roles[0].reqid else: add_role_msg = 'Created automatically from request %s' % self.request.reqid return create_add_role_request(self.apiurl, source_project, self.required_maintainer, 'maintainer', message=add_role_msg) except HTTPError as e: self.logger.error( 'Cannot create the corresponding add_role request for %s: %s' % (self.request.reqid, e) )
def submitMergeRequest(self, upstreamDistro, msg): reqs = osccore.get_request_list(self.distro.config('obs', 'url'), self.distro.obsProject( self.dist, self.component), self.obsName, req_type='submit', req_state=['new', 'review']) user = self.distro.obsUser oldreqs = [i for i in reqs if i.state.who == user] result = osccore.create_submit_request( self.distro.config('obs', 'url'), self.distro.obsProject(self.dist, self.component), self.obsName, upstreamDistro, self.obsName, msg) for req in oldreqs: osccore.change_request_state(self.distro.config('obs', 'url'), req.reqid, 'superseded', 'superseded by %s' % result, result) return result
def origin_history(apiurl, target_project, package, user): history = [] requests = get_request_list(apiurl, target_project, package, None, ['all'], 'submit') for request in sorted(requests, key=lambda r: r.reqid, reverse=True): review = review_find_last(request, user) if not review: continue annotation = origin_annotation_load(review.comment) if not annotation: continue history.append({ 'origin': annotation.get('origin', 'None'), 'request': request.reqid, 'state': request.state.name, }) return history
def origin_history(apiurl, target_project, package, user): history = [] requests = get_request_list(apiurl, target_project, package, None, ['all'], 'submit') for request in sorted(requests, key=lambda r: r.reqid, reverse=True): review = review_find_last(request, user) if not review: continue annotation = origin_annotation_load(review.comment) if not annotation: continue history.append({ 'origin': annotation.get('origin', 'None'), 'request': request.reqid, 'state': request.state.name, }) return history
def sle_workarounds_unneeded_check(self, package): # If SLE-workarounds project and package was not sourced from # SLE-workarounds, but it does exist in SLE-workarounds. if (self.sle_workarounds and not self.sle_workarounds_sourced and package in self.packages[self.sle_workarounds]): # Determine how recently the package was updated. root = ET.fromstringlist( get_commitlog(self.apiurl, self.sle_workarounds, package, None, format='xml')) updated_last = date_parse(root.find('logentry/date').text) age = datetime.now() - updated_last if age.total_seconds() < 3600 * 24: logger.debug('skip removal of {}/{} since updated within 24 hours'.format( self.sle_workarounds, package)) return requests = get_request_list(self.apiurl, self.sle_workarounds, package, req_type='submit') if len(requests): logger.debug('existing submit request involving {}/{}'.format(self.sle_workarounds, package)) return self.delete_request(self.sle_workarounds, package, 'sourced from {}'.format(self.lookup.get(package)))
def test_source_inherited_maintainer(self): """Declines the request when the 'required_maintainer' is only inherited maintainer of the source project""" # Change the required maintainer group_name = FACTORY_MAINTAINERS.replace('group:', '') self.wf.create_group(group_name) self.wf.remote_config_set( {'required-source-maintainer': FACTORY_MAINTAINERS}) self.wf.create_project(SRC_PROJECT.rsplit(':', 1)[0], maintainer={'groups': [group_name]}) self._setup_devel_project() req = self.wf.create_submit_request(SRC_PROJECT, 'blowfish', add_commit=False) self.assertReview(req.reqid, by_user=(self.bot_user, 'new')) self.review_bot.set_request_ids([req.reqid]) self.review_bot.check_requests() review = self.assertReview(req.reqid, by_user=(self.bot_user, 'declined')) add_role_req = get_request_list(self.wf.apiurl, SRC_PROJECT, req_state=['new'], req_type='add_role')[0] self.assertIn( 'unless %s is a maintainer of %s' % (FACTORY_MAINTAINERS, SRC_PROJECT), review.comment) self.assertIn('Created the add_role request %s' % add_role_req.reqid, review.comment) self.assertEqual(add_role_req.actions[0].tgt_project, SRC_PROJECT) self.assertEqual('Created automatically from request %s' % req.reqid, add_role_req.description)