Introduce --remove-exclusion for staging select
The API errors with that option if a request is ignored, so we have to support it. Fixes #2374
This commit is contained in:
parent
00fbc99195
commit
cf2c496116
@ -118,6 +118,7 @@ def clean_args(args):
|
||||
@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('--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')
|
||||
def do_staging(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Commands to work with staging projects
|
||||
@ -266,6 +267,9 @@ def do_staging(self, subcmd, opts, *args):
|
||||
|
||||
select --move --filter-from A B $(< package.list)
|
||||
|
||||
select --remove-exclusion will unignore the requests selected (ignored requests
|
||||
are called excluded in the OBS API)
|
||||
|
||||
"unselect" will remove from the project - pushing them back to the backlog
|
||||
If a message is included the requests will be ignored first.
|
||||
|
||||
@ -304,7 +308,7 @@ def do_staging(self, subcmd, opts, *args):
|
||||
osc staging unignore [--cleanup] [REQUEST...|all]
|
||||
osc staging list [--supersede]
|
||||
osc staging lock [-m MESSAGE]
|
||||
osc staging select [--no-freeze] [--move [--filter-from STAGING]]
|
||||
osc staging select [--no-freeze] [--remove-exclusion] [--move [--filter-from STAGING]]
|
||||
STAGING REQUEST...
|
||||
osc staging select [--no-freeze] [--interactive|--non-interactive]
|
||||
[--filter-by...] [--group-by...]
|
||||
@ -559,13 +563,13 @@ def do_staging(self, subcmd, opts, *args):
|
||||
# api.set_splitter_info_in_prj_pseudometa(target_project, info['group'], info['strategy'])
|
||||
|
||||
SelectCommand(api, target_project) \
|
||||
.perform(request_ids, no_freeze=opts.no_freeze)
|
||||
.perform(request_ids, no_freeze=opts.no_freeze, remove_exclusion=opts.remove_exclusion)
|
||||
else:
|
||||
target_project = api.prj_from_short(stagings[0])
|
||||
filter_from = api.prj_from_short(opts.filter_from) if opts.filter_from else None
|
||||
SelectCommand(api, target_project) \
|
||||
.perform(requests, opts.move,
|
||||
filter_from, opts.no_freeze)
|
||||
filter_from, no_freeze=opts.no_freeze, remove_exclusion=opts.remove_exclusion)
|
||||
elif cmd == 'cleanup_rings':
|
||||
CleanupRings(api).perform()
|
||||
elif cmd == 'ignore':
|
||||
|
@ -55,7 +55,7 @@ class SelectCommand(object):
|
||||
|
||||
return candidates[0] if candidates else None
|
||||
|
||||
def select_request(self, request, move, filter_from):
|
||||
def select_request(self, request, move, filter_from, remove_exclusion=False):
|
||||
supersede = False
|
||||
|
||||
staged_requests = {
|
||||
@ -68,7 +68,7 @@ class SelectCommand(object):
|
||||
# Normal 'select' command
|
||||
print('Adding request "{}" to project "{}"'.format(request, self.target_project))
|
||||
|
||||
return self.api.rq_to_prj(request, self.target_project)
|
||||
return self.api.rq_to_prj(request, self.target_project, remove_exclusion)
|
||||
elif request in staged_requests and (move or supersede):
|
||||
# 'select' command becomes a 'move'
|
||||
# supersede = (new_rq, package, project)
|
||||
@ -106,7 +106,7 @@ class SelectCommand(object):
|
||||
raise oscerr.WrongArgs('Arguments for select are not correct.')
|
||||
|
||||
def perform(self, requests, move=False,
|
||||
filter_from=None, no_freeze=False):
|
||||
filter_from=None, no_freeze=False, remove_exclusion=False):
|
||||
"""
|
||||
Select package and move it accordingly by arguments
|
||||
:param target_project: project we want to target
|
||||
@ -132,7 +132,7 @@ class SelectCommand(object):
|
||||
requests_count = len(requests)
|
||||
for index, request in enumerate(requests, start=1):
|
||||
print('({}/{}) '.format(index, requests_count), end='')
|
||||
if not self.select_request(request, move, filter_from):
|
||||
if not self.select_request(request, move, filter_from, remove_exclusion=remove_exclusion):
|
||||
return False
|
||||
|
||||
# Notify everybody about the changes
|
||||
|
@ -895,7 +895,7 @@ class StagingAPI(object):
|
||||
return (time.time() - float(entry.get('mtime'))) / 3600 / 24
|
||||
return 100000 # quite some!
|
||||
|
||||
def rq_to_prj(self, request_id, project):
|
||||
def rq_to_prj(self, request_id, project, remove_exclusion=False):
|
||||
"""
|
||||
Links request to project - delete or submit
|
||||
:param request_id: request to link
|
||||
@ -923,7 +923,10 @@ class StagingAPI(object):
|
||||
raise oscerr.WrongArgs(msg)
|
||||
|
||||
requestxml = f"<requests><request id='{request_id}'/></requests>"
|
||||
u = makeurl(self.apiurl, ['staging', self.project, 'staging_projects', project, 'staged_requests'])
|
||||
opts = {}
|
||||
if remove_exclusion:
|
||||
opts['remove_exclusion'] = 1
|
||||
u = makeurl(self.apiurl, ['staging', self.project, 'staging_projects', project, 'staged_requests'], opts)
|
||||
f = http_POST(u, data=requestxml)
|
||||
|
||||
if act_type == 'delete':
|
||||
|
@ -1,22 +1,13 @@
|
||||
import unittest
|
||||
import os.path
|
||||
from osc import oscerr
|
||||
import osc.conf
|
||||
from osc.core import http_GET, http_POST, makeurl
|
||||
from lxml import etree as ET
|
||||
from osclib.cache import Cache
|
||||
from osclib.cache_manager import CacheManager
|
||||
from osclib.comments import CommentAPI
|
||||
from osclib.conf import Config
|
||||
from osclib.core import package_list
|
||||
from osclib.select_command import SelectCommand
|
||||
from osclib.unselect_command import UnselectCommand
|
||||
from osclib.supersede_command import SupersedeCommand
|
||||
from osclib.stagingapi import StagingAPI
|
||||
from osclib.memoize import memoize_session_reset
|
||||
from osclib.ignore_command import IgnoreCommand
|
||||
from osclib.core import source_file_load
|
||||
import logging
|
||||
|
||||
from urllib.error import HTTPError
|
||||
from lxml import etree as ET
|
||||
from mock import MagicMock
|
||||
from . import OBSLocal
|
||||
|
||||
@ -136,3 +127,27 @@ class TestSelect(OBSLocal.TestCase):
|
||||
# TODO: record which URLs were called so we can verify them
|
||||
# but we wont' be able to test the actual wipe unless we really build something
|
||||
# which is too expensive
|
||||
|
||||
def test_select_excluded_package(self):
|
||||
self.wf.setup_rings()
|
||||
staging = self.wf.create_staging('A', freeze=True, with_repo=True)
|
||||
|
||||
self.wf.create_submit_request('devel:wine', 'wine')
|
||||
IgnoreCommand(self.wf.api).perform(['wine'])
|
||||
|
||||
with self.assertRaises(HTTPError) as context:
|
||||
SelectCommand(self.wf.api, staging.name).perform(['wine'])
|
||||
|
||||
root = ET.fromstring(context.exception.fp.read())
|
||||
self.assertRegex(root.find('summary').text, r'Use --remove-exclusion')
|
||||
|
||||
def test_excluded_package(self):
|
||||
self.wf.setup_rings()
|
||||
staging = self.wf.create_staging('A', freeze=True, with_repo=True)
|
||||
|
||||
self.wf.create_submit_request('devel:wine', 'wine')
|
||||
IgnoreCommand(self.wf.api).perform(['wine'])
|
||||
|
||||
ret = SelectCommand(self.wf.api, staging.name).perform(['wine'], remove_exclusion=True)
|
||||
self.assertEqual(True, ret)
|
||||
self.assertEqual(0, len(self.wf.api.get_ignored_requests()))
|
||||
|
Loading…
x
Reference in New Issue
Block a user