Provide ignore/unignore request staging commands.
It is not uncommon for a request to be in a pending state which requires action beyond the scope of the staging workflow, but does not make sense to deny the request. For lack of a "postponed" or "pending" state on OBS a sudo-state of "ignore" is provided for the staging workflow. The ignore state will remove a request from the "list" and "adi" commands so as not to be accidentally staged. This avoids the need for keeping a context of what requests should be ignored in one's memory. It is expected that an ignored request will have comments reflecting what is to be done or one should be added via the -m option of ignore command.
This commit is contained in:
parent
d21dbfb8c4
commit
b25fda9b47
@ -31,6 +31,8 @@ from osclib.check_command import CheckCommand
|
||||
from osclib.cleanup_rings import CleanupRings
|
||||
from osclib.conf import Config
|
||||
from osclib.freeze_command import FreezeCommand
|
||||
from osclib.ignore_command import IgnoreCommand
|
||||
from osclib.unignore_command import UnignoreCommand
|
||||
from osclib.list_command import ListCommand
|
||||
from osclib.obslock import OBSLock
|
||||
from osclib.select_command import SelectCommand
|
||||
@ -92,6 +94,7 @@ def _full_project_name(self, project):
|
||||
help='do not update bootstrap-copy when freezing')
|
||||
@cmdln.option('--wipe-cache', dest='wipe_cache', action='store_true', default=False,
|
||||
help='wipe GET request cache before executing')
|
||||
@cmdln.option('-m', '--message', help='message used by ignore command')
|
||||
def do_staging(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Commands to work with staging projects
|
||||
|
||||
@ -115,6 +118,10 @@ def do_staging(self, subcmd, opts, *args):
|
||||
|
||||
"frozenage" will show when the respective staging project was last frozen
|
||||
|
||||
"ignore" will ignore a request from "list" and "adi" commands until unignored
|
||||
|
||||
"unignore" will remove from ignore list
|
||||
|
||||
"list" will pick the requests not in rings
|
||||
|
||||
"select" will add requests to the project
|
||||
@ -127,6 +134,8 @@ def do_staging(self, subcmd, opts, *args):
|
||||
osc staging cleanup_rings
|
||||
osc staging freeze [--no-boostrap] PROJECT...
|
||||
osc staging frozenage PROJECT...
|
||||
osc staging ignore [-m MESSAGE] REQUEST...
|
||||
osc staging unignore REQUEST...|all
|
||||
osc staging list [--supersede]
|
||||
osc staging select [--no-freeze] [--move [--from PROJECT]] LETTER REQUEST...
|
||||
osc staging unselect REQUEST...
|
||||
@ -151,6 +160,8 @@ def do_staging(self, subcmd, opts, *args):
|
||||
min_args, max_args = 1, None
|
||||
elif cmd == 'adi':
|
||||
min_args, max_args = None, None
|
||||
elif cmd in ('ignore', 'unignore'):
|
||||
min_args, max_args = 1, None
|
||||
elif cmd in ('list', 'accept'):
|
||||
min_args, max_args = 0, None
|
||||
elif cmd in ('cleanup_rings', 'acheck'):
|
||||
@ -233,6 +244,10 @@ def do_staging(self, subcmd, opts, *args):
|
||||
opts.from_, opts.no_freeze)
|
||||
elif cmd == 'cleanup_rings':
|
||||
CleanupRings(api).perform()
|
||||
elif cmd == 'ignore':
|
||||
IgnoreCommand(api).perform(args[1:], opts.message)
|
||||
elif cmd == 'unignore':
|
||||
UnignoreCommand(api).perform(args[1:])
|
||||
elif cmd == 'list':
|
||||
ListCommand(api).perform(args[1:], supersede=opts.supersede)
|
||||
elif cmd == 'adi':
|
||||
|
@ -51,6 +51,7 @@ class AdiCommand:
|
||||
|
||||
non_ring_packages = []
|
||||
non_ring_requests = dict()
|
||||
non_ring_requests_ignored = []
|
||||
|
||||
for request in all_requests:
|
||||
# Consolidate all data from request
|
||||
@ -86,6 +87,10 @@ class AdiCommand:
|
||||
if self.api.update_superseded_request(request):
|
||||
continue
|
||||
|
||||
if not len(wanted_requests) and request_id in self.requests_ignored:
|
||||
non_ring_requests_ignored.append(request_id)
|
||||
continue
|
||||
|
||||
non_ring_packages.append(target_package)
|
||||
if split:
|
||||
# request_id pretended to be index of non_ring_requests
|
||||
@ -105,6 +110,10 @@ class AdiCommand:
|
||||
non_ring_requests[source_project] = []
|
||||
non_ring_requests[source_project].append(request_id)
|
||||
|
||||
if len(non_ring_requests_ignored):
|
||||
print "Not in a ring, but ignored:"
|
||||
for request_id in non_ring_requests_ignored:
|
||||
print "- sr#{}: {}".format(request_id, requests_ignored[request_id])
|
||||
if len(non_ring_packages):
|
||||
print "Not in a ring:", ' '.join(sorted(non_ring_packages))
|
||||
else:
|
||||
@ -124,6 +133,7 @@ class AdiCommand:
|
||||
"""
|
||||
Perform the list command
|
||||
"""
|
||||
self.requests_ignored = self.api.get_ignored_requests()
|
||||
if len(packages):
|
||||
requests = set()
|
||||
if move:
|
||||
|
44
osclib/ignore_command.py
Normal file
44
osclib/ignore_command.py
Normal file
@ -0,0 +1,44 @@
|
||||
from osc.core import get_request
|
||||
from osclib.comments import CommentAPI
|
||||
|
||||
|
||||
class IgnoreCommand(object):
|
||||
def __init__(self, api):
|
||||
self.api = api
|
||||
self.comment = CommentAPI(self.api.apiurl)
|
||||
|
||||
def perform(self, request_ids, message=None):
|
||||
"""
|
||||
Ignore a request from "list" and "adi" commands until unignored.
|
||||
"""
|
||||
|
||||
requests_ignored = self.api.get_ignored_requests()
|
||||
length = len(requests_ignored)
|
||||
|
||||
for request_id in request_ids:
|
||||
print('Processing {}'.format(request_id))
|
||||
check = self.check_and_comment(request_id, message)
|
||||
if check is not True:
|
||||
print('- {}'.format(check))
|
||||
elif request_id not in requests_ignored:
|
||||
requests_ignored[int(request_id)] = message
|
||||
|
||||
diff = len(requests_ignored) - length
|
||||
if diff > 0:
|
||||
print('Ignoring {} requests'.format(diff))
|
||||
self.api.set_ignored_requests(requests_ignored)
|
||||
else:
|
||||
print('No new requests to ignore')
|
||||
|
||||
return True
|
||||
|
||||
def check_and_comment(self, request_id, message=None):
|
||||
request = get_request(self.api.apiurl, request_id)
|
||||
if not request:
|
||||
return 'not found'
|
||||
if request.actions[0].tgt_project != self.api.project:
|
||||
return 'not targeting {}'.format(self.api.project)
|
||||
if message:
|
||||
self.comment.add_comment(request_id=request_id, comment=message)
|
||||
|
||||
return True
|
@ -22,6 +22,7 @@ class ListCommand:
|
||||
|
||||
# Print out the left overs
|
||||
requests = self.api.get_open_requests()
|
||||
requests_ignored = self.api.get_ignored_requests()
|
||||
|
||||
non_ring_packages = []
|
||||
change_devel_requests = {}
|
||||
@ -86,13 +87,15 @@ class ListCommand:
|
||||
elif source_prj.startswith('home:'):
|
||||
source_prj = '~' + source_prj[len('home:'):]
|
||||
result[devel][-1] += ' ({})'.format(source_prj)
|
||||
if request_id in requests_ignored:
|
||||
result[devel][-1] += '\nignored: ' + requests_ignored[request_id]
|
||||
else:
|
||||
non_ring_packages.append(target_package)
|
||||
|
||||
for prj in sorted(result.keys()):
|
||||
print prj
|
||||
for line in result[prj]:
|
||||
print ' ', line
|
||||
print ' ', line.replace('\n', '\n ')
|
||||
|
||||
if len(non_ring_packages):
|
||||
print "Not in a ring:", ' '.join(sorted(non_ring_packages))
|
||||
|
@ -459,6 +459,16 @@ class StagingAPI(object):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_ignored_requests(self):
|
||||
ignore = self.load_file_content('{}:Staging'.format(self.project), 'dashboard', 'ignored_requests')
|
||||
if ignore is None:
|
||||
return {}
|
||||
return yaml.safe_load(ignore)
|
||||
|
||||
def set_ignored_requests(self, ignore_requests):
|
||||
ignore = yaml.dump(ignore_requests, default_flow_style=False)
|
||||
self.save_file_content('{}:Staging'.format(self.project), 'dashboard', 'ignored_requests', ignore)
|
||||
|
||||
def get_open_requests(self):
|
||||
"""
|
||||
Get all requests with open review for staging project
|
||||
@ -746,6 +756,14 @@ class StagingAPI(object):
|
||||
self.do_change_review_state(request_id, 'accepted',
|
||||
by_group=self.cstaging_group,
|
||||
message='Picked {}'.format(project))
|
||||
|
||||
# unignore a request selected to a project
|
||||
requests_ignored = self.get_ignored_requests()
|
||||
request_id = int(request_id)
|
||||
if request_id in requests_ignored:
|
||||
del requests_ignored[request_id]
|
||||
self.set_ignored_requests(requests_ignored)
|
||||
|
||||
return True
|
||||
|
||||
def map_ring_package_to_subject(self, project, pkg):
|
||||
|
32
osclib/unignore_command.py
Normal file
32
osclib/unignore_command.py
Normal file
@ -0,0 +1,32 @@
|
||||
from osc.core import get_request
|
||||
|
||||
|
||||
class UnignoreCommand(object):
|
||||
def __init__(self, api):
|
||||
self.api = api
|
||||
|
||||
def perform(self, request_ids):
|
||||
"""
|
||||
Unignore a request by removing from ignore list.
|
||||
"""
|
||||
|
||||
requests_ignored = self.api.get_ignored_requests()
|
||||
length = len(requests_ignored)
|
||||
|
||||
if len(request_ids) == 1 and request_ids[0] == 'all':
|
||||
requests_ignored = {}
|
||||
else:
|
||||
for request_id in request_ids:
|
||||
request_id = int(request_id)
|
||||
if request_id in requests_ignored:
|
||||
print('Removing {}'.format(request_id))
|
||||
del requests_ignored[request_id]
|
||||
|
||||
diff = length - len(requests_ignored)
|
||||
if diff > 0:
|
||||
print('Unignoring {} requests'.format(diff))
|
||||
self.api.set_ignored_requests(requests_ignored)
|
||||
else:
|
||||
print('No requests to unignore')
|
||||
|
||||
return True
|
Loading…
x
Reference in New Issue
Block a user