3 # This file is part of REPA: Release Engineering Process Assistant.
5 # Copyright (C) 2013 Intel Corporation
7 # REPA is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # version 2 as published by the Free Software Foundation.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 REPA: Release Engineering Process Assistant.
24 Copyright (C) Intel Corporation 2013
25 Licence: GPL version 2
26 Author: Ed Bartosh <eduard.bartosh@intel.com>
29 Common functions, classes, exceptions.
36 from functools import wraps, partial
38 OBS_PROJECT_PREFIX = "home:prerelease:"
40 class RepaException(Exception):
41 """Custom repa exception. All repa modules should use it."""
44 def get_project_by_name(obs, name, target):
45 """Lookup for a project in OBS by submission or group name."""
46 projects = list(obs.get_projects('^%s%s:%s$' % (OBS_PROJECT_PREFIX, target,
47 name.replace('/', ':'))))
49 raise RepaException('OBS project not found for %s %s' % \
53 plist = '\n '.join(prj for prj, _desc, _build_results in projects)
54 raise RepaException('%s %s resolves into multiple projects:\n %s' % \
55 (target, name, plist))
57 return projects[0][0], json.loads(projects[0][1]), projects[0][2]
60 def _resolve_submissions(obs, name, target):
61 """Get list of submissions with meta. Resolves submitgroups."""
62 project, meta, _bresults = get_project_by_name(obs, name, target)
63 if name.startswith('submitgroup'):
64 for subm in meta['submissions']:
65 sprj, smeta, _bresults = get_project_by_name(obs, subm, target)
66 yield subm, sprj, smeta
68 yield name, project, meta
71 def delete_project(obs, name, target):
72 """Delete OBS project related to submission or submit group."""
73 project = get_project_by_name(obs, name, target)[0]
74 obs.delete_project(project)
77 def accept_or_reject(obs, submission, state, target, comment=''):
78 """Create SRs and set their state for one submission or for a group."""
79 for name, project, meta in _resolve_submissions(obs, submission, target):
80 # osc submitreq [OPTIONS] SOURCEPRJ SOURCEPKG DESTPRJ [DESTPKG]
81 # osc request accept [-m TEXT] ID
82 print "submission %s" % str(name)
84 commit = meta.get('git_commit') or meta['git_tag']
85 submitter = meta.get('submitter')
88 message = "Submitter: %s\n" % submitter
90 message += "Comments: %s \nGit project: %s\nTag: %s\nCommit: %s" \
91 % (comment or "submission %s" % str(name),
96 for pkg in obs.get_source_packages(project):
99 reqid = obs.create_sr(project, pkg, str(meta['obs_target_prj']),
100 message=str(message))
101 except RepaException:
102 if state == 'declined':
103 # Broken sources. Try to avoid queryng source by
104 # providing revision 1. It always exists and it doesn't
105 # matter which revision to reject.
106 reqid = obs.create_sr(project, pkg,
107 str(meta['obs_target_prj']),
108 message=str(message), revision=1)
112 print 'package %s: created SR %s' % (pkg, reqid)
114 # and immediately set its state
115 message = "SR %s is set to %s" % (reqid, state)
118 obs.set_sr_state(reqid, state=state,
119 message=str(message), force=True)
120 print 'set SR state to', state
122 # delete submit group
123 if submission.startswith('submitgroup'):
124 delete_project(obs, submission, target)
126 class CancelRetryError(Exception):
127 """Exception for handling cancelling of the retry loop. Needed for
128 transparently re-raising the previous exception."""
130 Exception.__init__(self)
131 self.typ, self.val, self.backtrace = sys.exc_info()
133 def retry(exceptions, tries=10, sleep=1):
134 """Decorator for re-trying function calls"""
136 """The "real" decorator function"""
138 def wrap(*args, **kwargs):
139 """Wrapper for re-trying func"""
140 for attempt in range(1, tries + 1):
142 return func(*args, **kwargs)
143 except CancelRetryError as err:
144 raise err.typ, err.val, err.backtrace
145 except exceptions as err:
154 """Colorize text with ANSI colors."""
155 colors = {'black': '\033[90m', 'red': '\033[91m',
156 'green': '\033[92m', 'yellow': '\033[93m',
157 'blue': '\033[94m', 'magenta': '\033[95m',
158 'cyan': '\033[96m', 'white': '\033[97m'
162 def __init__(self, enable=True):
163 self.enabled = enable
165 def __getattr__(self, name):
166 if name in self.colors:
167 return partial(self.colorize, color=name)
170 """Disable colorizing."""
174 """Enable colorizing."""
177 def colorize(self, text, color):
180 return self.reset + self.colors[color] + text + self.reset
184 def get_download_url(meta):
185 """Get download url from meta."""
186 if 'download_url' in meta:
187 return meta['download_url']
188 # Guess url from image url if download_url is not in the meta
189 if 'images' not in meta:
191 for img in meta['images']:
193 return img['url'].split('images')[0]
196 def get_obs_url(meta, buildurl='https://build.tizen.org'):
197 """Get obs project url from meta."""
198 if 'obs_url' in meta:
199 return meta['obs_url']
200 # Make it from git tag and obs_target_prj if obs_url is not in the meta
201 if 'obs_target_prj' not in meta:
203 if 'name' not in meta and 'git_tag' not in meta:
205 name = meta.get('git_tag') or meta.get('name')
206 return os.path.join(buildurl, 'project/show?project=home:prerelease:%s:%s'
207 % (meta['obs_target_prj'], name.replace('/', ':')))