From f27fc0fd7796dfc813d0229eb3a093a9ceba9ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Tue, 17 Nov 2009 16:59:17 +0000 Subject: [PATCH] support review handling of requests (new "osc review accept/decline $REQUEST_ID" command --- NEWS | 1 + osc/commandline.py | 68 +++++++++++++++++++++++++++++++--------------- osc/core.py | 45 ++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/NEWS b/NEWS index 899c0372..d50e61ff 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ - implement "osc mbranch" call to create projects with multiple source package (instances) - new "osc patchinfo" command: basic patchinfo generation and modification support - add support for _patchinfo package submissions in "osc sr" on project level + - support review handling of requests (new "osc review accept/decline $REQUEST_ID" command 0.123 - IMPORTANT: ssl certificate checks are actually performed now to diff --git a/osc/commandline.py b/osc/commandline.py index 69072936..64ee9f46 100755 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -640,6 +640,8 @@ class Osc(cmdln.Cmdln): help='specify message TEXT') @cmdln.option('-r', '--revision', metavar='REV', help='for "create", specify a certain source revision ID (the md5 sum)') + @cmdln.option('-s', '--supersede', metavar='SUPERSEDE', + help='Superseding another request by this one') @cmdln.option('--nodevelproject', action='store_true', help='do not follow a defined devel project ' \ '(primary project where a package is developed)') @@ -880,8 +882,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. opts.message, orev=opts.revision, src_update=src_update) if repl == 'y': for req in myreqs: - change_request_state(apiurl, str(req.reqid), 'revoked', - 'superseeded by %s' % result) + change_request_state(apiurl, str(req.reqid), 'superseded', + 'superseded by %s' % result, result) + + if opts.supersede: + r = change_request_state(conf.config['apiurl'], + opts.supersede, 'superseded', opts.message or '', result) print 'created request id', result @@ -982,6 +988,7 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-B', '--bugowner', action='store_true', help='also show requests about packages where I am bugowner') @cmdln.alias("rq") + @cmdln.alias("review") def do_request(self, subcmd, opts, *args): """${cmd_name}: Show and modify requests @@ -1030,6 +1037,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. osc request revoke [-m TEXT] ID osc request wipe ID osc request checkout/co ID + osc review accept [-m TEXT] ID + osc review decline [-m TEXT] ID ${cmd_option_list} """ @@ -1179,26 +1188,41 @@ Please submit there instead, or use --nodevelproject to force direct submission. if not opts.message: opts.message = edit_message() - # decline - if cmd == 'decline': - r = change_request_state(conf.config['apiurl'], - reqid, 'declined', opts.message or '') - print r - # accept - elif cmd == 'accept': - r = change_request_state(conf.config['apiurl'], - reqid, 'accepted', opts.message or '') - print r - # delete/wipe - elif cmd == 'wipe': - r = change_request_state(conf.config['apiurl'], - reqid, 'deleted', opts.message or '') - print r - # revoke - elif cmd == 'revoke': - r = change_request_state(conf.config['apiurl'], - reqid, 'revoked', opts.message or '') - print r + # Change review state only + if subcmd == 'review': + # decline + if cmd == 'decline': + r = change_review_state(conf.config['apiurl'], + reqid, 'declined', conf.config['user'], '', opts.message or '') + print r + # accept + elif cmd == 'accept': + r = change_review_state(conf.config['apiurl'], + reqid, 'accepted', conf.config['user'], '', opts.message or '') + print r + + # Change state of entire request + else: + # accept + if cmd == 'accept': + r = change_request_state(conf.config['apiurl'], + reqid, 'accepted', opts.message or '') + print r + # decline + elif cmd == 'decline': + r = change_request_state(conf.config['apiurl'], + reqid, 'declined', opts.message or '') + print r + # delete/wipe + elif cmd == 'wipe': + r = change_request_state(conf.config['apiurl'], + reqid, 'deleted', opts.message or '') + print r + # revoke + elif cmd == 'revoke': + r = change_request_state(conf.config['apiurl'], + reqid, 'revoked', opts.message or '') + print r # editmeta and its aliases are all depracated @cmdln.alias("editprj") diff --git a/osc/core.py b/osc/core.py index f2d2fe6c..48170d09 100755 --- a/osc/core.py +++ b/osc/core.py @@ -1408,6 +1408,16 @@ rev: %s if not loop: raise ValueError("Empty filelist") +class ReviewState: + """for objects to represent the review state in a request""" + def __init__(self, state=None, by_user=None, by_group=None, who=None, when=None, comment=None): + self.state = state + self.by_user = by_user + self.by_group = by_group + self.who = who + self.when = when + self.comment = comment + class RequestState: """for objects to represent the "state" of a request""" def __init__(self, name=None, who=None, when=None, comment=None): @@ -1440,6 +1450,7 @@ class Request: self.descr = None self.actions = [] self.statehistory = [] + self.reviews = [] def read(self, root): self.reqid = int(root.get('id')) @@ -1478,6 +1489,20 @@ class Request: except: self.state.comment = None + # read the review states + for r in root.findall('review'): + s = ReviewState() + s.state = r.get('state') + s.by_user = r.get('by_user') + s.by_group = r.get('by_group') + s.who = r.get('who') + s.when = r.get('when') + try: + s.comment = r.find('comment').text.strip() + except: + s.comment = None + self.reviews.append(s) + # read the state history for h in root.findall('history'): s = RequestState() @@ -1575,11 +1600,18 @@ Comment: %s self.state.name, self.state.when, self.state.who, self.state.comment) + if len(self.reviews): + reviewitems = [ '%-10s %s %s %s %s %s' \ + % (i.state, i.by_user, i.by_group, i.when, i.who, i.comment) \ + for i in self.reviews ] + s += '\nReview: ' + '\n '.join(reviewitems) + + s += '\n' if len(self.statehistory): histitems = [ '%-10s %s %s' \ % (i.name, i.when, i.who) \ for i in self.statehistory ] - s += 'History: ' + '\n '.join(histitems) + s += '\nHistory: ' + '\n '.join(histitems) s += '\n' return s @@ -2472,10 +2504,17 @@ def get_request(apiurl, reqid): return r -def change_request_state(apiurl, reqid, newstate, message=''): +def change_review_state(apiurl, reqid, newstate, by_user='', by_group='', message='', supersed=''): u = makeurl(apiurl, ['request', reqid], - query={'cmd': 'changestate', 'newstate': newstate}) + query={'cmd': 'changereviewstate', 'newstate': newstate, 'by_user': by_user, 'superseded_by': supersed}) + f = http_POST(u, data=message) + return f.read() + +def change_request_state(apiurl, reqid, newstate, message='', supersed=''): + u = makeurl(apiurl, + ['request', reqid], + query={'cmd': 'changestate', 'newstate': newstate, 'superseded_by': supersed}) f = http_POST(u, data=message) return f.read()