osclib/list_command.py: Allow overriding reviews filter from the command line.

This patch implements overriding of the filter on reviews set up by the
staging plugin. It is now possible to filter requests that have been
reviewed by more than one group, for example; or to filter requests that
have lack a request by a specific group or bot.
This commit is contained in:
Giacomo Leidi 2024-10-31 16:23:29 +01:00
parent 88108f75a7
commit 6f073412f0
Signed by untrusted user: gleidi
GPG Key ID: DE9BE0ACE8246F08
3 changed files with 19 additions and 9 deletions

View File

@ -120,6 +120,7 @@ def clean_args(args):
@cmdln.option('--merge', action='store_true', help='propose merge where applicable and store details to allow future merges') @cmdln.option('--merge', action='store_true', help='propose merge where applicable and store details to allow future merges')
@cmdln.option('--try-strategies', action='store_true', default=False, help='apply strategies and keep any with desireable outcome') @cmdln.option('--try-strategies', action='store_true', default=False, help='apply strategies and keep any with desireable outcome')
@cmdln.option('--strategy', help='apply a specific strategy') @cmdln.option('--strategy', help='apply a specific strategy')
@cmdln.option('--match-filter', help='xpath by which to filter requests on the basis of the reviews they received', default=None)
@cmdln.option('--no-color', action='store_true', help='strip colors from output (or add staging.color = 0 to the .oscrc general section') @cmdln.option('--no-color', action='store_true', help='strip colors from output (or add staging.color = 0 to the .oscrc general section')
@cmdln.option('--remove-exclusion', action='store_true', help='unignore selected requests automatically', default=False) @cmdln.option('--remove-exclusion', action='store_true', help='unignore selected requests automatically', default=False)
@cmdln.option('--save', action='store_true', help='save the result to the pseudometa package') @cmdln.option('--save', action='store_true', help='save the result to the pseudometa package')
@ -158,6 +159,14 @@ def do_staging(self, subcmd, opts, *args):
"list" will list/supersede requests for ring packages or all if no rings. "list" will list/supersede requests for ring packages or all if no rings.
By just calling list, the staging plugin will list all the request included
in the backlog section of the web UI. It is also possible to optionally limit
results with an XPATH filter. As an example, the following would list all
packages which have received a positive review from a member of the
licensedigger group or the factory-auto one
list --match-filter "state/@name='review' and review[(@by_group='factory-auto' or @by_group='licensedigger') and @state='accepted']"
"lock" acquire a hold on the project in order to execute multiple commands "lock" acquire a hold on the project in order to execute multiple commands
and prevent others from interrupting. An example: and prevent others from interrupting. An example:
@ -309,7 +318,7 @@ def do_staging(self, subcmd, opts, *args):
osc staging frozenage [STAGING...] osc staging frozenage [STAGING...]
osc staging ignore [-m MESSAGE] REQUEST... osc staging ignore [-m MESSAGE] REQUEST...
osc staging unignore [--cleanup] [REQUEST...|all] osc staging unignore [--cleanup] [REQUEST...|all]
osc staging list [--supersede] [--adi-details] osc staging list [--adi-details] [--match-filter] [--supersede]
osc staging lock [-m MESSAGE] osc staging lock [-m MESSAGE]
osc staging select [--no-freeze] [--remove-exclusion] [--move [--filter-from STAGING]] osc staging select [--no-freeze] [--remove-exclusion] [--move [--filter-from STAGING]]
STAGING REQUEST... STAGING REQUEST...
@ -580,7 +589,7 @@ def do_staging(self, subcmd, opts, *args):
elif cmd == 'unignore': elif cmd == 'unignore':
UnignoreCommand(api).perform(args[1:], opts.cleanup) UnignoreCommand(api).perform(args[1:], opts.cleanup)
elif cmd == 'list': elif cmd == 'list':
ListCommand(api).perform(supersede=opts.supersede, adi_details=opts.adi_details) ListCommand(api).perform(adi_details=opts.adi_details, match_filter=opts.match_filter, supersede=opts.supersede)
elif cmd == 'lock': elif cmd == 'lock':
lock.hold(opts.message) lock.hold(opts.message)
elif cmd == 'adi': elif cmd == 'adi':

View File

@ -43,7 +43,7 @@ class ListCommand:
print(' ', line) print(' ', line)
def perform(self, supersede=False, adi_details=False): def perform(self, adi_details=False, match_filter=None, supersede=False):
""" """
Perform the list command Perform the list command
""" """
@ -51,7 +51,7 @@ class ListCommand:
if supersede: if supersede:
SupersedeCommand(self.api).perform() SupersedeCommand(self.api).perform()
requests = self.api.get_open_requests() requests = self.api.get_open_requests(match_filter=match_filter)
if not len(requests): if not len(requests):
return return

View File

@ -574,7 +574,7 @@ class StagingAPI(object):
http_DELETE(url, data=ET.tostring(root)) http_DELETE(url, data=ET.tostring(root))
@memoize(session=True, add_invalidate=True) @memoize(session=True, add_invalidate=True)
def get_open_requests(self, query_extra=None): def get_open_requests(self, match_filter=None, query_extra=None):
""" """
Get all requests with open review for staging project Get all requests with open review for staging project
that are not yet included in any staging project that are not yet included in any staging project
@ -585,12 +585,13 @@ class StagingAPI(object):
# expect Request objects # expect Request objects
requests = [] requests = []
# xpath query, using the -m, -r, -s options
where = f"@by_group='{self.cstaging_group}' and @state='new'"
target = f"target[@project='{self.project}']" target = f"target[@project='{self.project}']"
query = {'match': f"state/@name='review' and review[{where}] and {target}"} # xpath query, using the -m, -r, -s options
if not match_filter:
match_filter = f"state/@name='review' and review[@by_group='{self.cstaging_group}' and @state='new']"
query = {'match': f"{match_filter} and {target}"}
if query_extra is not None: if query_extra is not None:
query.update(query_extra) query.update(query_extra)
url = self.makeurl(['search', 'request'], query) url = self.makeurl(['search', 'request'], query)