2014-03-05 15:12:45 +01:00
|
|
|
from xml.etree import cElementTree as ET
|
|
|
|
|
2014-03-04 15:30:49 +01:00
|
|
|
from osc import oscerr
|
2014-03-05 15:12:45 +01:00
|
|
|
from osc.core import http_GET
|
|
|
|
|
2014-03-04 09:39:14 +01:00
|
|
|
from osclib.request_finder import RequestFinder
|
2014-03-06 14:29:01 +01:00
|
|
|
from osclib.freeze_command import FreezeCommand
|
2014-03-04 09:39:14 +01:00
|
|
|
|
2014-03-04 15:30:49 +01:00
|
|
|
|
|
|
|
class SelectCommand(object):
|
|
|
|
|
2014-03-04 09:39:14 +01:00
|
|
|
def __init__(self, api):
|
|
|
|
self.api = api
|
|
|
|
|
2014-03-05 15:12:45 +01:00
|
|
|
def _package(self, request):
|
2014-03-06 18:23:07 +01:00
|
|
|
"""
|
|
|
|
Get the package name from the submit request XML.
|
|
|
|
:param request: request we check for
|
|
|
|
"""
|
2014-03-05 15:12:45 +01:00
|
|
|
f = http_GET(self.api.makeurl(['request', str(request)]))
|
|
|
|
root = ET.parse(f).getroot()
|
|
|
|
package = str(root.find('action').find('target').attrib['package'])
|
|
|
|
return package
|
|
|
|
|
2014-03-10 16:27:29 +01:00
|
|
|
def _supersede(self, request):
|
2014-03-05 15:12:45 +01:00
|
|
|
"""
|
|
|
|
Check if the request supersede a different request from a
|
|
|
|
staging project.
|
2014-03-10 16:27:29 +01:00
|
|
|
|
|
|
|
SRA supersede SRB when (1) SRA ID > SRB ID and (2) the changes
|
|
|
|
in SRB are in SRA. The second condition is difficult to
|
|
|
|
assure, but the way that we implement RequestFinder can
|
|
|
|
address some corner cases that make the first condition
|
|
|
|
enough.
|
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
:param request: request we check for
|
2014-03-05 15:12:45 +01:00
|
|
|
"""
|
|
|
|
package = self._package(request)
|
|
|
|
|
2014-03-10 16:27:29 +01:00
|
|
|
candidates = [] # Store candidates to be supersede by 'request'
|
2014-03-05 15:12:45 +01:00
|
|
|
for staging in self.api.get_staging_projects():
|
2014-03-06 18:23:07 +01:00
|
|
|
# requests for the same project are fine
|
|
|
|
if staging == self.target_project:
|
2014-03-05 17:20:29 +01:00
|
|
|
continue
|
2014-03-05 15:12:45 +01:00
|
|
|
for rq in self.api.get_prj_pseudometa(staging)['requests']:
|
2014-03-10 16:27:29 +01:00
|
|
|
if int(rq['id']) < int(request) and rq['package'] == package:
|
|
|
|
candidates.append((rq['id'], package, staging))
|
|
|
|
|
|
|
|
assert len(candidates) <= 1, 'There are more thant one candidate to supersede {} ({}): {}'.format(request, package, candidates)
|
|
|
|
|
|
|
|
return candidates[0] if candidates else None
|
2014-03-05 15:12:45 +01:00
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
def select_request(self, request, request_project, move, from_):
|
2014-03-10 16:27:29 +01:00
|
|
|
supersede = self._supersede(request)
|
2014-03-05 15:12:45 +01:00
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
if 'staging' not in request_project and not supersede:
|
2014-03-04 09:39:14 +01:00
|
|
|
# Normal 'select' command
|
2014-03-06 18:23:07 +01:00
|
|
|
return self.api.rq_to_prj(request, self.target_project)
|
|
|
|
elif 'staging' in request_project and (move or supersede):
|
2014-03-04 09:39:14 +01:00
|
|
|
# 'select' command becomes a 'move'
|
|
|
|
fprj = None
|
2014-03-04 15:30:49 +01:00
|
|
|
if from_:
|
|
|
|
fprj = self.api.prj_from_letter(from_)
|
2014-03-04 09:39:14 +01:00
|
|
|
else:
|
2014-03-05 15:12:45 +01:00
|
|
|
# supersede = (new_rq, package, project)
|
2014-03-06 18:23:07 +01:00
|
|
|
fprj = request_project['staging'] if not supersede else supersede[2]
|
2014-03-06 15:59:34 +01:00
|
|
|
|
2014-03-05 15:12:45 +01:00
|
|
|
if supersede:
|
2014-03-06 18:23:07 +01:00
|
|
|
print('"{} ({}) is superseded by {}'.format(request, supersede[1], supersede[0]))
|
2014-03-06 15:59:34 +01:00
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
if fprj == self.target_project:
|
|
|
|
print('"{}" is currently in "{}"'.format(request, self.target_project))
|
2014-03-06 15:59:34 +01:00
|
|
|
return False
|
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
print('Moving "{}" from "{}" to "{}"'.format(request, fprj, self.target_project))
|
|
|
|
return self.api.move_between_project(fprj, request, self.target_project)
|
|
|
|
elif 'staging' in request_project and not move:
|
2014-03-04 09:39:14 +01:00
|
|
|
# Previously selected, but not explicit move
|
2014-03-05 17:20:29 +01:00
|
|
|
msg = 'Request {} is already tracked in "{}".'
|
2014-03-06 18:23:07 +01:00
|
|
|
msg = msg.format(request, request_project['staging'])
|
|
|
|
if request_project['staging'] != self.target_project:
|
2014-03-05 17:20:29 +01:00
|
|
|
msg += '\nUse --move modifier to move the request from "{}" to "{}"'
|
2014-03-06 18:23:07 +01:00
|
|
|
msg = msg.format(request_project['staging'], self.target_project)
|
2014-03-04 09:39:14 +01:00
|
|
|
print(msg)
|
2014-03-05 17:20:29 +01:00
|
|
|
return True
|
2014-03-04 09:39:14 +01:00
|
|
|
else:
|
|
|
|
raise oscerr.WrongArgs('Arguments for select are not correct.')
|
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
def perform(self, target_project, requests, move=False, from_=None):
|
|
|
|
"""
|
|
|
|
Select package and move it accordingly by arguments
|
|
|
|
:param target_project: project we want to target
|
|
|
|
:param requests: requests we are working with
|
|
|
|
:param move: wether to move the requests or not
|
|
|
|
:param from_: location where from move the requests
|
|
|
|
"""
|
2014-03-07 14:49:33 +01:00
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
# If the project is not frozen enough yet freeze it
|
|
|
|
if not self.api.prj_frozen_enough(target_project):
|
2014-03-09 20:13:45 +01:00
|
|
|
print('Freeze the prj first')
|
|
|
|
#FreezeCommand(self.api).perform(target_project)
|
2014-03-06 18:23:07 +01:00
|
|
|
self.target_project = target_project
|
2014-03-04 09:39:14 +01:00
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
for request, request_project in RequestFinder.find_sr(requests, self.api.apiurl).items():
|
|
|
|
if not self.select_request(request, request_project, move, from_):
|
2014-03-04 15:00:25 +01:00
|
|
|
return False
|
|
|
|
|
2014-03-06 18:23:07 +01:00
|
|
|
# now make sure we enable the prj if the prj contains any ringed package
|
2014-03-24 15:15:47 +01:00
|
|
|
self.api.build_switch_staging_project(target_project)
|
2014-03-07 14:49:33 +01:00
|
|
|
|
2014-03-10 11:22:36 +01:00
|
|
|
return True
|