openSUSE-release-tools/osclib/select_command.py

139 lines
5.3 KiB
Python
Raw Normal View History

2014-03-05 15:12:45 +01:00
from xml.etree import cElementTree as ET
from osc import oscerr
2014-03-05 15:12:45 +01:00
from osc.core import http_GET
from osclib.request_finder import RequestFinder
# from osclib.freeze_command import FreezeCommand
SELECT = 'select'
# SUPERSEDE = 'supersede'
MOVE = 'move'
class SelectCommand(object):
def __init__(self, api, target_project):
self.api = api
self.affected_projects = set()
self.target_project = target_project
2014-03-05 15:12:45 +01:00
def _package(self, request):
"""
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.
: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():
# requests for the same project are fine
if staging == self.target_project:
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
def select_request(self, request, move, from_):
2014-03-10 16:27:29 +01:00
supersede = self._supersede(request)
2014-03-05 15:12:45 +01:00
staged_requests = {
self.api.packages_staged[package]['rq_id']: package for package in self.api.packages_staged
}
if request not in staged_requests and not supersede:
# Normal 'select' command
print('Adding request "{}" to project "{}"'.format(request, self.target_project))
2014-05-20 12:26:29 +02:00
return self.api.rq_to_prj(request, self.target_project)
elif request in staged_requests and (move or supersede):
# 'select' command becomes a 'move'
fprj = None
if from_:
fprj = self.api.prj_from_letter(from_)
else:
2014-03-05 15:12:45 +01:00
# supersede = (new_rq, package, project)
fprj = self.api.packages_staged[staged_requests[request]]['prj'] if not supersede else supersede[2]
2014-03-05 15:12:45 +01:00
if supersede:
print('"{} ({}) is superseded by {}'.format(request, supersede[1], supersede[0]))
if fprj == self.target_project:
print('"{}" is currently in "{}"'.format(request, self.target_project))
return False
print('Moving "{}" from "{}" to "{}"'.format(request, fprj, self.target_project))
2014-05-20 12:26:29 +02:00
# Store the source project, we also need to write a comment there
self.affected_projects.add(fprj)
2014-05-20 12:26:29 +02:00
return self.api.move_between_project(fprj, request, self.target_project)
elif request in staged_requests and not move:
# Previously selected, but not explicit move
2014-09-09 13:48:27 +02:00
fprj = self.api.packages_staged[staged_requests[request]]['prj']
msg = 'Request {} is already tracked in "{}".'
2014-09-09 13:48:27 +02:00
msg = msg.format(request, fprj)
if fprj != self.target_project:
msg += '\nUse --move modifier to move the request from "{}" to "{}"'
2014-09-09 13:48:27 +02:00
msg = msg.format(fprj, self.target_project)
print(msg)
return True
else:
raise oscerr.WrongArgs('Arguments for select are not correct.')
2015-07-16 19:35:22 +02:00
def perform(self, requests, move=False,
2015-03-24 14:46:36 +01:00
from_=None, no_freeze=False):
"""
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
"""
2015-07-18 14:12:58 +02:00
if self.api.is_adi_project(self.target_project):
no_freeze = True
# If the project is not frozen enough yet freeze it
2015-07-16 19:35:22 +02:00
if not (no_freeze or self.api.prj_frozen_enough(self.target_project)):
print('Freeze the prj first')
return False
2015-07-16 19:35:22 +02:00
# FreezeCommand(self.api).perform(self.target_project)
for request in RequestFinder.find_sr(requests, self.api):
if not self.select_request(request, move, from_):
2014-03-04 15:00:25 +01:00
return False
# Notify everybody about the changes
2015-07-16 19:35:22 +02:00
self.api.update_status_comments(self.target_project, 'select')
for fprj in self.affected_projects:
self.api.update_status_comments(fprj, 'select')
# now make sure we enable the prj if the prj contains any ringed package
2015-07-16 19:35:22 +02:00
self.api.build_switch_staging_project(self.target_project)
2014-03-10 11:22:36 +01:00
return True