diff --git a/osc-staging.py b/osc-staging.py index d164fae51..b6e928ac8 100644 --- a/osc-staging.py +++ b/osc-staging.py @@ -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('--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('--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('--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') @@ -158,6 +159,14 @@ def do_staging(self, subcmd, opts, *args): "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 and prevent others from interrupting. An example: @@ -309,7 +318,7 @@ def do_staging(self, subcmd, opts, *args): osc staging frozenage [STAGING...] osc staging ignore [-m MESSAGE] REQUEST... 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 select [--no-freeze] [--remove-exclusion] [--move [--filter-from STAGING]] STAGING REQUEST... @@ -580,7 +589,7 @@ def do_staging(self, subcmd, opts, *args): elif cmd == 'unignore': UnignoreCommand(api).perform(args[1:], opts.cleanup) 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': lock.hold(opts.message) elif cmd == 'adi': diff --git a/osclib/list_command.py b/osclib/list_command.py index 9af760c16..b30f427a2 100644 --- a/osclib/list_command.py +++ b/osclib/list_command.py @@ -43,7 +43,7 @@ def print_request(self, request): 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 """ @@ -51,7 +51,7 @@ def perform(self, supersede=False, adi_details=False): if supersede: SupersedeCommand(self.api).perform() - requests = self.api.get_open_requests() + requests = self.api.get_open_requests(match_filter=match_filter) if not len(requests): return diff --git a/osclib/stagingapi.py b/osclib/stagingapi.py index 9b52cd867..59a6996ba 100644 --- a/osclib/stagingapi.py +++ b/osclib/stagingapi.py @@ -574,7 +574,7 @@ def del_ignored_request(self, request_id): http_DELETE(url, data=ET.tostring(root)) @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 that are not yet included in any staging project @@ -585,12 +585,14 @@ def get_open_requests(self, query_extra=None): # expect Request objects requests = [] + target = f"target[@project='{self.project}']" # xpath query, using the -m, -r, -s options - where = f"@by_group='{self.cstaging_group}' and @state='new'" - target = f"target[@project='{self.project}']" + if not match_filter: + review_where = f"review[@by_group='{self.cstaging_group}' and @state='new']" + match_filter = f"state/@name='review' and {review_where}" - query = {'match': f"state/@name='review' and review[{where}] and {target}"} + query = {'match': f"{match_filter} and {target}"} if query_extra is not None: query.update(query_extra) url = self.makeurl(['search', 'request'], query)