2016-05-30 18:19:49 +02:00
#!/usr/bin/python
# Copyright (c) 2014 SUSE Linux Products GmbH
# Copyright (c) 2016 SUSE LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from pprint import pprint
2016-09-26 11:16:30 +02:00
import os
import sys
import re
2016-05-30 18:19:49 +02:00
import logging
from optparse import OptionParser
import cmdln
try :
from xml . etree import cElementTree as ET
except ImportError :
import cElementTree as ET
import osc . conf
import osc . core
import urllib2
import yaml
import ReviewBot
from check_maintenance_incidents import MaintenanceChecker
from check_source_in_factory import FactorySourceChecker
2016-09-26 11:16:30 +02:00
from osclib . comments import CommentAPI
class LogToString ( logging . Filter ) :
def __init__ ( self , obj , propname ) :
self . obj = obj
self . propname = propname
def filter ( self , record ) :
if record . levelno > = logging . INFO :
line = record . getMessage ( )
2016-09-30 11:51:00 +02:00
comment_log = getattr ( self . obj , self . propname )
if comment_log is not None :
comment_log . append ( line )
setattr ( self . obj , self . propname , comment_log )
2016-09-26 11:16:30 +02:00
return True
2016-05-30 18:19:49 +02:00
class Leaper ( ReviewBot . ReviewBot ) :
def __init__ ( self , * args , * * kwargs ) :
ReviewBot . ReviewBot . __init__ ( self , * args , * * kwargs )
2016-09-26 11:16:30 +02:00
self . do_comments = True
self . commentapi = CommentAPI ( self . apiurl )
2016-05-30 18:19:49 +02:00
self . maintbot = MaintenanceChecker ( * args , * * kwargs )
# for FactorySourceChecker
self . factory = FactorySourceChecker ( * args , * * kwargs )
2016-07-29 10:55:37 +02:00
self . needs_reviewteam = False
self . pending_factory_submission = False
2016-09-30 11:51:00 +02:00
self . source_in_factory = None
2016-09-26 11:16:30 +02:00
self . needs_release_manager = False
self . release_manager_group = ' leap-reviewers '
2016-10-10 16:20:30 +02:00
self . must_approve_version_updates = False
self . must_approve_maintenance_updates = False
2016-12-29 00:34:56 -06:00
self . needs_check_source = False
self . check_source_group = None
2016-09-26 11:16:30 +02:00
self . comment_marker_re = re . compile ( r ' <!-- leaper state=(?P<state>done|seen)(?: result=(?P<result>accepted|declined))? --> ' )
self . comment_log = None
self . commentlogger = LogToString ( self , ' comment_log ' )
self . logger . addFilter ( self . commentlogger )
2016-07-29 10:55:37 +02:00
2016-12-06 17:00:32 +01:00
# project => package list
self . packages = { }
2016-07-29 10:55:37 +02:00
def prepare_review ( self ) :
2017-01-18 13:50:05 +01:00
# update lookup information on every run
2017-01-17 22:08:34 -06:00
if self . ibs :
2017-01-18 13:50:05 +01:00
self . factory . parse_lookup ( ' SUSE:SLE-12-SP3:GA ' )
self . lookup_sp3 = self . factory . lookup . copy ( )
2017-01-17 22:08:34 -06:00
return
2016-07-29 10:55:37 +02:00
2016-12-06 17:00:32 +01:00
self . factory . parse_lookup ( ' openSUSE:Leap:42.3 ' )
self . factory . parse_lookup ( ' openSUSE:Leap:42.3:NonFree ' )
self . lookup_423 = self . factory . lookup . copy ( )
self . factory . reset_lookup ( )
self . factory . parse_lookup ( ' openSUSE:Leap:42.2:Update ' )
self . factory . parse_lookup ( ' openSUSE:Leap:42.2:NonFree:Update ' )
2016-06-26 13:52:56 +02:00
self . lookup_422 = self . factory . lookup . copy ( )
2016-12-06 17:00:32 +01:00
self . factory . reset_lookup ( )
2016-06-26 13:52:56 +02:00
self . factory . parse_lookup ( ' openSUSE:Leap:42.1:Update ' )
self . lookup_421 = self . factory . lookup . copy ( )
2016-12-06 17:00:32 +01:00
self . factory . reset_lookup ( )
def get_source_packages ( self , project , expand = False ) :
""" Return the list of packages in a project. """
query = { ' expand ' : 1 } if expand else { }
root = ET . parse ( osc . core . http_GET ( osc . core . makeurl ( self . apiurl , [ ' source ' , project ] ,
query = query ) ) ) . getroot ( )
packages = [ i . get ( ' name ' ) for i in root . findall ( ' entry ' ) ]
return packages
def is_package_in_project ( self , project , package ) :
if not project in self . packages :
self . packages [ project ] = self . get_source_packages ( project )
return True if package in self . packages [ project ] else False
2016-06-26 13:52:56 +02:00
2017-01-31 17:09:39 +01:00
def rdiff_link ( self , src_project , src_package , src_rev , target_project , target_package = None ) :
if target_package is None :
target_package = src_package
return ' [ %(target_project)s / %(target_package)s ](/package/rdiff/ %(src_project)s / %(src_package)s ?opackage= %(target_package)s &oproject= %(target_project)s &rev= %(src_rev)s ) ' % {
' src_project ' : src_project ,
' src_package ' : src_package ,
' src_rev ' : src_rev ,
' target_project ' : target_project ,
' target_package ' : target_package ,
}
2016-05-30 18:19:49 +02:00
def check_source_submission ( self , src_project , src_package , src_rev , target_project , target_package ) :
2016-06-26 13:52:56 +02:00
self . logger . info ( " %s / %s @ %s -> %s / %s " % ( src_project , src_package , src_rev , target_project , target_package ) )
src_srcinfo = self . get_sourceinfo ( src_project , src_package , src_rev )
package = target_package
2017-01-18 13:50:05 +01:00
origin = None
2016-06-26 13:52:56 +02:00
if src_srcinfo is None :
# source package does not exist?
# handle here to avoid crashing on the next line
self . logger . warn ( " Could not get source info for %s / %s @ %s " % ( src_project , src_package , src_rev ) )
return False
2017-01-17 22:09:25 -06:00
if self . ibs and target_project . startswith ( ' SUSE:SLE ' ) :
2017-01-18 13:50:05 +01:00
if package in self . lookup_sp3 :
origin = self . lookup_sp3 [ package ]
origin_same = True
if origin :
origin_same = True if origin == ' FORK ' else src_project . startswith ( origin )
self . logger . info ( " expected origin is ' %s ' ( %s ) " , origin ,
" unchanged " if origin_same else " changed " )
2017-01-19 10:29:39 +01:00
prj = ' openSUSE.org:openSUSE:Factory '
2017-01-17 22:09:25 -06:00
# True or None (open request) are acceptable for SLE.
2017-01-19 10:29:39 +01:00
self . source_in_factory = self . _check_factory ( package , src_srcinfo , prj )
2017-01-18 13:50:05 +01:00
if self . source_in_factory is None :
self . pending_factory_submission = True
if self . source_in_factory is not False :
return self . source_in_factory
2017-01-17 22:09:25 -06:00
2017-01-19 10:29:39 +01:00
# got false. could mean package doesn't exist or no match
if self . is_package_in_project ( prj , package ) :
2017-01-31 17:09:39 +01:00
self . logger . info ( ' different sources in {} ' . format ( self . rdiff_link ( src_project , src_package , src_rev , prj , package ) ) )
2017-01-19 10:29:39 +01:00
prj = ' openSUSE.org:openSUSE:Leap:42.2 '
if self . is_package_in_project ( prj , package ) :
if self . _check_factory ( package , src_srcinfo , prj ) is True :
self . logger . info ( ' found source match in {} ' . format ( prj ) )
else :
2017-01-31 17:09:39 +01:00
self . logger . info ( ' different sources in {} ' . format ( self . rdiff_link ( src_project , src_package , src_rev , prj , package ) ) )
2017-01-17 22:09:25 -06:00
2017-01-18 13:50:05 +01:00
devel_project , devel_package = self . get_devel_project ( ' openSUSE.org:openSUSE:Factory ' , package )
if devel_project is not None :
# specifying devel package is optional
if devel_package is None :
devel_package = package
2017-01-19 10:29:39 +01:00
if self . is_package_in_project ( devel_project , devel_package ) :
if self . factory . _check_project ( devel_project , devel_package , src_srcinfo . verifymd5 ) == True :
self . logger . info ( ' matching sources in {} / {} ' . format ( devel_project , devel_package ) )
return True
else :
2017-01-31 17:09:39 +01:00
self . logger . info ( ' different sources in {} ' . format ( self . rdiff_link ( src_project , src_package , src_rev , devel_project , devel_package ) ) )
2017-01-17 22:09:25 -06:00
else :
2017-01-18 13:50:05 +01:00
self . logger . info ( ' no devel project found for {} / {} ' . format ( ' openSUSE.org:openSUSE:Factory ' , package ) )
2017-01-17 22:09:25 -06:00
2017-01-19 10:29:39 +01:00
self . logger . info ( ' no matching sources in Factory, Leap:42.2, nor devel project ' )
2017-01-17 22:09:25 -06:00
2017-01-18 13:50:05 +01:00
return origin_same
2017-01-17 22:09:25 -06:00
2016-12-06 17:00:32 +01:00
if package in self . lookup_423 :
origin = self . lookup_423 [ package ]
2016-06-26 13:52:56 +02:00
2016-09-26 11:16:30 +02:00
is_fine_if_factory = False
2016-09-30 11:51:00 +02:00
not_in_factory_okish = False
2016-06-26 13:52:56 +02:00
if origin :
2017-01-11 14:37:26 -06:00
origin_same = src_project . startswith ( origin )
self . logger . info ( " expected origin is ' %s ' ( %s ) " , origin ,
" unchanged " if origin_same else " changed " )
2016-06-26 13:52:56 +02:00
if origin . startswith ( ' Devel; ' ) :
( dummy , origin , dummy ) = origin . split ( ' ; ' )
2016-09-26 11:16:30 +02:00
if origin != src_project :
self . logger . debug ( " not submitted from devel project " )
return False
is_fine_if_factory = True
2016-09-30 11:51:00 +02:00
not_in_factory_okish = True
2016-10-10 16:20:30 +02:00
if self . must_approve_version_updates :
self . needs_release_manager = True
2016-09-26 11:16:30 +02:00
# fall through to check history and requests
2016-06-26 13:52:56 +02:00
elif origin . startswith ( ' openSUSE:Factory ' ) :
2016-10-13 18:08:13 +02:00
if self . must_approve_version_updates :
self . needs_release_manager = True
2016-09-26 11:16:30 +02:00
if origin == src_project :
2016-09-30 11:51:00 +02:00
self . source_in_factory = True
2016-09-26 11:16:30 +02:00
return True
is_fine_if_factory = True
# fall through to check history and requests
elif origin == ' FORK ' :
is_fine_if_factory = True
2016-09-30 11:51:00 +02:00
not_in_factory_okish = True
2016-09-26 11:16:30 +02:00
self . needs_release_manager = True
2016-12-29 00:34:56 -06:00
self . needs_check_source = True
2016-09-26 11:16:30 +02:00
# fall through to check history and requests
2016-12-06 17:00:32 +01:00
elif origin . startswith ( ' openSUSE:Leap:42.2 ' ) :
2016-10-10 16:20:30 +02:00
if self . must_approve_maintenance_updates :
self . needs_release_manager = True
2016-06-26 13:52:56 +02:00
# submitted from :Update
2017-01-11 14:37:26 -06:00
if origin_same :
2016-12-06 17:00:32 +01:00
self . logger . debug ( " submission from 42.2 ok " )
return True
# switching to sle package might make sense
if src_project . startswith ( ' SUSE:SLE-12 ' ) :
self . needs_release_manager = True
2016-06-26 13:52:56 +02:00
return True
# submitted from elsewhere but is in :Update
else :
2016-12-06 17:00:32 +01:00
good = self . factory . _check_project ( ' openSUSE:Leap:42.2:Update ' , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good :
2016-12-06 17:00:32 +01:00
self . logger . info ( " submission found in 42.2 " )
2016-06-26 13:52:56 +02:00
return good
# check release requests too
2016-12-06 17:00:32 +01:00
good = self . factory . _check_requests ( ' openSUSE:Leap:42.2:Update ' , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good or good == None :
self . logger . debug ( " found request " )
return good
# let's see where it came from before
2016-12-06 17:00:32 +01:00
if package in self . lookup_422 :
oldorigin = self . lookup_422 [ package ]
2016-06-26 13:52:56 +02:00
self . logger . debug ( " oldorigin {} " . format ( oldorigin ) )
# Factory. So it's ok to keep upgrading it to Factory
# TODO: whitelist packages where this is ok and block others?
if oldorigin . startswith ( ' openSUSE:Factory ' ) :
2016-12-06 17:00:32 +01:00
self . logger . info ( " Package was from Factory in 42.2 " )
2016-09-30 11:51:00 +02:00
# check if an attempt to switch to SLE package is made
2016-12-06 17:00:32 +01:00
for sp in ( ' SP2:GA ' , ' SP2:Update ' , ' SP3:GA ' ) :
good = self . factory . _check_project ( ' SUSE:SLE-12- {} ' . format ( sp ) , target_package , src_srcinfo . verifymd5 )
if good :
self . logger . info ( " request sources come from SLE " )
self . needs_release_manager = True
return good
2016-09-26 11:16:30 +02:00
# the release manager needs to review attempts to upgrade to Factory
is_fine_if_factory = True
self . needs_release_manager = True
2016-06-26 13:52:56 +02:00
elif origin . startswith ( ' SUSE:SLE-12 ' ) :
2016-10-10 16:20:30 +02:00
if self . must_approve_maintenance_updates :
self . needs_release_manager = True
2016-12-06 17:00:32 +01:00
for v in ( ' 42.3 ' , ' 42.2 ' ) :
prj = ' openSUSE:Leap: {} :SLE-workarounds ' . format ( v )
if self . is_package_in_project ( prj , target_package ) :
self . logger . info ( " found package in %s " , prj )
if not self . factory . _check_project ( prj ,
target_package ,
src_srcinfo . verifymd5 ) :
self . logger . info ( " sources in %s are NOT identical " , prj )
self . needs_release_manager = True
2016-06-26 13:52:56 +02:00
# submitted from :Update
2016-09-30 11:51:00 +02:00
if origin == src_project :
self . logger . debug ( " submission origin ok " )
return True
elif origin . endswith ( ' :GA ' ) \
2016-08-24 16:47:26 +02:00
and src_project == origin [ : - 2 ] + ' Update ' :
self . logger . debug ( " sle update submission " )
2016-06-26 13:52:56 +02:00
return True
2016-12-06 17:00:32 +01:00
# check if submitted from higher SP
priolist = [ ' SUSE:SLE-12: ' , ' SUSE:SLE-12-SP1: ' , ' SUSE:SLE-12-SP2: ' , ' SUSE:SLE-12-SP3: ' ]
for i in range ( len ( priolist ) - 1 ) :
if origin . startswith ( priolist [ i ] ) :
for prj in priolist [ i + 1 : ] :
if src_project . startswith ( prj ) :
self . logger . info ( " submission from higher service pack %s :* ok " , prj )
return True
2016-09-30 11:51:00 +02:00
self . needs_release_manager = True
2016-09-26 11:16:30 +02:00
# the release manager needs to review attempts to upgrade to Factory
is_fine_if_factory = True
else :
self . logger . error ( " unhandled origin %s " , origin )
return False
2016-06-26 13:52:56 +02:00
else : # no origin
2016-09-30 11:51:00 +02:00
# submission from SLE is ok
if src_project . startswith ( ' SUSE:SLE-12 ' ) :
2016-06-26 13:52:56 +02:00
return True
2016-09-30 11:51:00 +02:00
is_fine_if_factory = True
self . needs_release_manager = True
# we came here because none of the above checks find it good, so
# let's see if the package is in Factory at least
is_in_factory = self . _check_factory ( target_package , src_srcinfo )
if is_in_factory :
self . source_in_factory = True
self . needs_reviewteam = False
elif is_in_factory is None :
self . pending_factory_submission = True
self . needs_reviewteam = False
else :
if src_project . startswith ( ' SUSE:SLE-12 ' ) \
or src_project . startswith ( ' openSUSE:Leap:42. ' ) :
self . needs_reviewteam = False
else :
self . needs_reviewteam = True
2016-10-12 14:33:14 +02:00
self . source_in_factory = False
2016-06-26 13:52:56 +02:00
2016-09-26 11:16:30 +02:00
if is_fine_if_factory :
if self . source_in_factory :
return True
elif self . pending_factory_submission :
return None
2016-09-30 11:51:00 +02:00
elif not_in_factory_okish :
self . needs_reviewteam = True
2016-09-26 11:16:30 +02:00
return True
2016-06-26 13:52:56 +02:00
return False
2017-01-17 22:09:25 -06:00
def _check_factory ( self , target_package , src_srcinfo , target_project = ' openSUSE:Factory ' ) :
good = self . factory . _check_project ( target_project , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good :
return good
2017-01-17 22:09:25 -06:00
good = self . factory . _check_requests ( target_project , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good or good == None :
self . logger . debug ( " found request to Factory " )
return good
2017-01-17 22:09:25 -06:00
target_project_nonfree = ' {} :NonFree ' . format ( target_project )
good = self . factory . _check_project ( target_project_nonfree , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good :
return good
2017-01-17 22:09:25 -06:00
good = self . factory . _check_requests ( target_project_nonfree , target_package , src_srcinfo . verifymd5 )
2016-06-26 13:52:56 +02:00
if good or good == None :
2017-01-17 22:09:25 -06:00
self . logger . debug ( ' found request to {} ' . format ( target_project_nonfree ) )
2016-06-26 13:52:56 +02:00
return good
return False
2016-05-30 18:19:49 +02:00
2016-09-30 11:51:00 +02:00
def _check_project_and_request ( self , project , target_package , src_srcinfo ) :
good = self . factory . _check_project ( project , target_package , src_srcinfo . verifymd5 )
if good :
return good
good = self . factory . _check_requests ( project , target_package , src_srcinfo . verifymd5 )
if good or good == None :
return good
return False
2016-05-30 18:19:49 +02:00
def check_one_request ( self , req ) :
self . review_messages = self . DEFAULT_REVIEW_MESSAGES . copy ( )
2016-06-26 13:52:56 +02:00
self . needs_reviewteam = False
2016-09-26 11:16:30 +02:00
self . needs_release_manager = False
2016-06-26 13:52:56 +02:00
self . pending_factory_submission = False
2016-09-30 11:51:00 +02:00
self . source_in_factory = None
self . comment_log = [ ]
2016-12-06 17:00:32 +01:00
self . packages = { }
2016-05-30 18:19:49 +02:00
2016-06-07 11:49:25 +02:00
if len ( req . actions ) != 1 :
msg = " only one action per request please "
self . review_messages [ ' declined ' ] = msg
return False
2016-09-26 11:16:30 +02:00
request_ok = ReviewBot . ReviewBot . check_one_request ( self , req )
2017-01-18 13:50:05 +01:00
if not self . ibs :
has_correct_maintainer = self . maintbot . check_one_request ( req )
self . logger . debug ( " has_correct_maintainer: %s " , has_correct_maintainer )
2016-05-30 18:19:49 +02:00
2016-09-26 11:16:30 +02:00
self . logger . debug ( " review result: %s " , request_ok )
if self . pending_factory_submission :
self . logger . info ( " submission is waiting for a Factory request to complete " )
elif self . source_in_factory :
2016-09-30 11:51:00 +02:00
self . logger . info ( " the submitted sources are in or accepted for Factory " )
elif self . source_in_factory == False :
2016-09-26 11:16:30 +02:00
self . logger . info ( " the submitted sources are NOT in Factory " )
2016-09-30 11:51:00 +02:00
if request_ok == False :
self . logger . info ( " NOTE: if you think the automated review was wrong here, please talk to the release team before reopening the request " )
elif self . needs_release_manager :
self . logger . info ( " request needs review by release management " )
2016-09-26 11:16:30 +02:00
if self . comment_log :
2016-09-30 11:51:00 +02:00
result = None
2016-09-26 11:16:30 +02:00
if request_ok is None :
state = ' seen '
elif request_ok :
2016-09-30 11:51:00 +02:00
state = ' done '
result = ' accepted '
2016-09-26 11:16:30 +02:00
else :
2016-09-30 11:51:00 +02:00
state = ' done '
result = ' declined '
self . add_comment ( req , ' \n \n ' . join ( self . comment_log ) , state )
2016-09-26 11:16:30 +02:00
self . comment_log = None
2016-09-30 11:51:00 +02:00
if self . needs_release_manager :
add_review = True
for r in req . reviews :
if r . by_group == self . release_manager_group and ( r . state == ' new ' or r . state == ' accepted ' ) :
add_review = False
self . logger . debug ( " %s already is a reviewer " , self . release_manager_group )
break
if add_review :
if self . add_review ( req , by_group = self . release_manager_group ) != True :
self . review_messages [ ' declined ' ] + = ' \n adding %s failed ' % self . release_manager_group
return False
if self . needs_reviewteam :
add_review = True
self . logger . info ( " %s needs review by opensuse-review-team " % req . reqid )
for r in req . reviews :
if r . by_group == ' opensuse-review-team ' :
add_review = False
self . logger . debug ( " opensuse-review-team already is a reviewer " )
break
if add_review :
if self . add_review ( req , by_group = " opensuse-review-team " ) != True :
self . review_messages [ ' declined ' ] + = ' \n adding opensuse-review-team failed '
return False
2016-09-26 11:16:30 +02:00
2016-12-29 00:34:56 -06:00
if self . needs_check_source and self . check_source_group is not None :
add_review = True
self . logger . info ( " %s needs review by %s " % ( req . reqid , self . check_source_group ) )
for r in req . reviews :
if r . by_group == self . check_source_group :
add_review = False
self . logger . debug ( " %s already is a reviewer " , self . check_source_group )
break
if add_review :
if self . add_review ( req , by_group = self . check_source_group ) != True :
self . review_messages [ ' declined ' ] + = ' \n adding %s failed ' % self . check_source_group
return False
2016-09-26 11:16:30 +02:00
return request_ok
2016-05-30 18:19:49 +02:00
2016-06-26 13:52:56 +02:00
def check_action__default ( self , req , a ) :
# decline all other requests for fallback reviewer
self . logger . debug ( " auto decline request type %s " % a . type )
return False
2016-09-26 11:16:30 +02:00
# TODO: make generic, move to Reviewbot. Used by multiple bots
def add_comment ( self , req , msg , state , result = None ) :
if not self . do_comments :
return
comment = " <!-- leaper state= %s %s --> \n " % ( state , ' result= %s ' % result if result else ' ' )
comment + = " \n " + msg
( comment_id , comment_state , comment_result , comment_text ) = self . find_obs_request_comment ( req , state )
if comment_id is not None and state == comment_state :
2016-09-30 11:51:00 +02:00
# count number of lines as aproximation to avoid spamming requests
# for slight wording changes in the code
if len ( comment_text . split ( ' \n ' ) ) == len ( comment . split ( ' \n ' ) ) :
2016-09-26 11:16:30 +02:00
self . logger . debug ( " not worth the update, previous comment %s is state %s " , comment_id , comment_state )
return
self . logger . debug ( " adding comment to %s , state %s result %s " , req . reqid , state , result )
self . logger . debug ( " message: %s " , msg )
if not self . dryrun :
if comment_id is not None :
self . commentapi . delete ( comment_id )
self . commentapi . add_comment ( request_id = req . reqid , comment = str ( comment ) )
def find_obs_request_comment ( self , req , state = None ) :
""" Return previous comments (should be one). """
if self . do_comments :
comments = self . commentapi . get_comments ( request_id = req . reqid )
for c in comments . values ( ) :
m = self . comment_marker_re . match ( c [ ' comment ' ] )
if m and ( state is None or state == m . group ( ' state ' ) ) :
return c [ ' id ' ] , m . group ( ' state ' ) , m . group ( ' result ' ) , c [ ' comment ' ]
return None , None , None , None
2016-09-30 11:51:00 +02:00
def check_action__default ( self , req , a ) :
self . logger . info ( " unhandled request type %s " % a . type )
self . needs_release_manager = True
return True
2016-05-30 18:19:49 +02:00
class CommandLineInterface ( ReviewBot . CommandLineInterface ) :
def __init__ ( self , * args , * * kwargs ) :
ReviewBot . CommandLineInterface . __init__ ( self , args , kwargs )
2017-01-02 02:34:13 -06:00
self . clazz = Leaper
2016-05-30 18:19:49 +02:00
def get_optparser ( self ) :
parser = ReviewBot . CommandLineInterface . get_optparser ( self )
2016-09-26 11:16:30 +02:00
parser . add_option ( " --no-comment " , dest = ' comment ' , action = " store_false " , default = True , help = " don ' t actually post comments to obs " )
2016-10-10 16:20:30 +02:00
parser . add_option ( " --manual-version-updates " , action = " store_true " , help = " release manager must approve version updates " )
parser . add_option ( " --manual-maintenance-updates " , action = " store_true " , help = " release manager must approve maintenance updates " )
2016-12-29 00:34:56 -06:00
parser . add_option ( " --check-source-group " , dest = " check_source_group " , metavar = " GROUP " , help = " group used by check_source.py bot which will be added as a reviewer should leaper checks pass " )
2016-09-26 11:16:30 +02:00
2016-05-30 18:19:49 +02:00
return parser
def setup_checker ( self ) :
2017-01-02 02:34:13 -06:00
bot = ReviewBot . CommandLineInterface . setup_checker ( self )
2016-05-30 18:19:49 +02:00
2016-10-10 16:20:30 +02:00
if self . options . manual_version_updates :
bot . must_approve_version_updates = True
if self . options . manual_maintenance_updates :
bot . must_approve_maintenance_updates = True
2016-12-29 00:34:56 -06:00
if self . options . check_source_group :
bot . check_source_group = self . options . check_source_group
2016-09-26 11:16:30 +02:00
bot . do_comments = self . options . comment
2016-05-30 18:19:49 +02:00
return bot
if __name__ == " __main__ " :
app = CommandLineInterface ( )
sys . exit ( app . main ( ) )
# vim: sw=4 et