mirror of
https://github.com/openSUSE/osc.git
synced 2024-11-10 06:46:15 +01:00
- add a new subcommand 'mergereq' to handle merge requests. So far, it can
create, list, show requests. - internally, add a MergeReq class, and do the needed (HTTP) requests.
This commit is contained in:
parent
6c20c7203f
commit
aec7129a9b
@ -348,6 +348,107 @@ class Osc(cmdln.Cmdln):
|
||||
|
||||
|
||||
|
||||
@cmdln.option('-m', '--message', metavar='TEXT',
|
||||
help='specify message TEXT')
|
||||
def do_mergereq(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Handle requests to merge two packages
|
||||
|
||||
For "create", the DESTPAC name is optional; the source packages' name
|
||||
will be used if DESTPAC is omitted.
|
||||
|
||||
"list" lists open requests attached to a project or package.
|
||||
|
||||
"show" will show the request itself, and generate a diff for review.
|
||||
|
||||
refuse, accept:
|
||||
Not implemented. Requires more intelligence.
|
||||
|
||||
|
||||
usage:
|
||||
osc mergereq create [-m TEXT] SOURCEPRJ SOURCEPAC DESTPRJ [DESTPAC]
|
||||
osc mergereq list PRJ [PKG]
|
||||
osc mergereq show ID
|
||||
osc mergereq refuse ID
|
||||
osc mergereq accept ID
|
||||
${cmd_option_list}
|
||||
"""
|
||||
|
||||
args = slash_split(args)
|
||||
|
||||
cmds = ['create', 'list', 'show', 'refuse', 'accept']
|
||||
if not args or args[0] not in cmds:
|
||||
print >>sys.stderr, 'Unknown mergereq action. Choose one of %s.' % ', '.join(cmds)
|
||||
return 2
|
||||
|
||||
cmd = args[0]
|
||||
del args[0]
|
||||
|
||||
if cmd in ['create']:
|
||||
min_args, max_args = 3, 4
|
||||
elif cmd in ['list']:
|
||||
min_args, max_args = 1, 2
|
||||
else:
|
||||
min_args, max_args = 1, 1
|
||||
if len(args) < min_args:
|
||||
print >>sys.stderr, 'Too few arguments.'
|
||||
return 2
|
||||
if len(args) > max_args:
|
||||
print >>sys.stderr, 'Too many arguments.'
|
||||
return 2
|
||||
|
||||
# collect specific arguments
|
||||
if cmd == 'create':
|
||||
src_project, src_package, dst_project = args[0:3]
|
||||
if len(args) > 3:
|
||||
dst_package = args[3]
|
||||
else:
|
||||
dst_package = src_package
|
||||
|
||||
elif cmd == 'list':
|
||||
project = args[0]
|
||||
if len(args) > 1:
|
||||
package = args[1]
|
||||
else:
|
||||
package = None
|
||||
elif cmd in ['show', 'refuse', 'accepd']:
|
||||
reqid = args[0]
|
||||
|
||||
|
||||
# create
|
||||
if cmd == 'create':
|
||||
result = create_merge_request(conf.config['apiurl'],
|
||||
src_project, src_package,
|
||||
dst_project, dst_package,
|
||||
opts.message)
|
||||
print 'created request id', result
|
||||
|
||||
|
||||
# list
|
||||
elif cmd == 'list':
|
||||
results = get_merge_request_list(conf.config['apiurl'],
|
||||
project, package)
|
||||
for result in results:
|
||||
print result.list_view()
|
||||
|
||||
# show
|
||||
elif cmd == 'show':
|
||||
r = get_merge_request(conf.config['apiurl'], reqid)
|
||||
print r
|
||||
# fixme: will inevitably fail if the given target doesn't exist
|
||||
print pretty_diff(conf.config['apiurl'],
|
||||
r.src_project, r.src_package, None,
|
||||
r.dst_project, r.dst_package, None)
|
||||
|
||||
|
||||
# refuse
|
||||
elif cmd == 'refuse':
|
||||
print 'not implemented yet.'
|
||||
|
||||
# accept
|
||||
elif cmd == 'accept':
|
||||
print 'not implemented yet.'
|
||||
|
||||
|
||||
# editmeta and its aliases are all depracated
|
||||
@cmdln.alias("editprj")
|
||||
@cmdln.alias("createprj")
|
||||
|
141
osc/core.py
141
osc/core.py
@ -643,6 +643,84 @@ rev: %s
|
||||
os.unlink(filename)
|
||||
|
||||
|
||||
class MergeReq:
|
||||
"""represent a merge request and holds its metadata
|
||||
it has methods to read in metadata from xml,
|
||||
different views, ..."""
|
||||
def __init__(self):
|
||||
self.reqid = None
|
||||
self.state = None
|
||||
self.who = None
|
||||
self.when = None
|
||||
self.last_author = None
|
||||
self.src_project = None
|
||||
self.src_package = None
|
||||
self.dst_project = None
|
||||
self.dst_package = None
|
||||
self.descr = None
|
||||
self.history = None
|
||||
|
||||
def read(self, root):
|
||||
self.reqid = root.get('id')
|
||||
|
||||
n = root.find('merge').find('source')
|
||||
self.src_project = n.get('project')
|
||||
self.src_package = n.get('package')
|
||||
|
||||
n = root.find('merge').find('target')
|
||||
self.dst_project = n.get('project')
|
||||
self.dst_package = n.get('package')
|
||||
|
||||
n = root.find('state')
|
||||
self.state, self.who, self.when \
|
||||
= n.get('name'), n.get('who'), n.get('when')
|
||||
|
||||
try:
|
||||
n = root.find('description').text
|
||||
self.descr = n
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
n = root.find('history').text
|
||||
self.history = n
|
||||
except:
|
||||
pass
|
||||
|
||||
def list_view(self):
|
||||
return '%s %s %s/%s -> %s/%s %s' % \
|
||||
(self.reqid,
|
||||
self.state,
|
||||
self.src_project,
|
||||
self.src_package,
|
||||
self.dst_project,
|
||||
self.dst_package,
|
||||
repr(self.descr) or '')
|
||||
|
||||
def __str__(self):
|
||||
return """\
|
||||
Request to merge (id %s):
|
||||
%s/%s -> %s/%s
|
||||
|
||||
Message:
|
||||
%s
|
||||
|
||||
State: %s
|
||||
(%s, %s)
|
||||
|
||||
"""% \
|
||||
(self.reqid,
|
||||
self.src_project,
|
||||
self.src_package,
|
||||
self.dst_project,
|
||||
self.dst_package,
|
||||
repr(self.descr) or '',
|
||||
self.state,
|
||||
self.when, self.who,
|
||||
#self.history,
|
||||
)
|
||||
|
||||
|
||||
def shorttime(t):
|
||||
"""format time as Apr 02 18:19
|
||||
or Apr 02 2005
|
||||
@ -1184,6 +1262,69 @@ def read_meta_from_spec(specfile, *args):
|
||||
return spec_data
|
||||
|
||||
|
||||
def create_merge_request(apiurl,
|
||||
src_project, src_package,
|
||||
dst_project, dst_package,
|
||||
message):
|
||||
|
||||
r = MergeReq()
|
||||
r.src_project = src_project
|
||||
r.src_package = src_package
|
||||
r.dst_project = dst_project
|
||||
r.dst_package = dst_package
|
||||
import cgi
|
||||
r.descr = cgi.escape(message)
|
||||
|
||||
xml = """\
|
||||
<request type="merge">
|
||||
<merge>
|
||||
<source project="%s" package="%s" />
|
||||
<target project="%s" package="%s" />
|
||||
</merge>
|
||||
<state name="new"/>
|
||||
<description>%s</description>
|
||||
</request>
|
||||
""" % (r.src_project,
|
||||
r.src_package,
|
||||
r.dst_project,
|
||||
r.dst_package,
|
||||
r.descr)
|
||||
|
||||
u = makeurl(apiurl, ['request'], query=['cmd=create'])
|
||||
f = http_POST(u, data=xml)
|
||||
|
||||
root = ET.parse(f).getroot()
|
||||
return root.get('id')
|
||||
|
||||
|
||||
def get_merge_request(apiurl, reqid):
|
||||
u = makeurl(apiurl, ['request', reqid])
|
||||
f = http_GET(u)
|
||||
root = ET.parse(f).getroot()
|
||||
|
||||
r = MergeReq()
|
||||
r.read(root)
|
||||
return r
|
||||
|
||||
|
||||
def get_merge_request_list(apiurl, project, package):
|
||||
match = 'merge/target/@project=\'%s\'' % quote_plus(project)
|
||||
if package:
|
||||
match += '%20and%20' + 'merge/target/@package=\'%s\'' % quote_plus(package)
|
||||
|
||||
u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match])
|
||||
f = http_GET(u)
|
||||
collection = ET.parse(f).getroot()
|
||||
|
||||
requests = []
|
||||
for root in collection.findall('request'):
|
||||
r = MergeReq()
|
||||
r.read(root)
|
||||
requests.append(r)
|
||||
|
||||
return requests
|
||||
|
||||
|
||||
def get_user_meta(apiurl, user):
|
||||
u = makeurl(apiurl, ['person', quote_plus(user)])
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user