Improve git2lp and is_direct_release behaviour
* git2lp and is_direct_release are now functions extracted to the projects.py; * git2lp and is_direct_release mappings are now loaded from projects.yaml; * temporarily old mappings are used if no info found in projects.yaml. Fixes: bug #1202820 Fixes: bug #1202800 Fixes: bug #1082792 Change-Id: I487761d110cf781acea26b997486ea24a7deb25e
This commit is contained in:
parent
268f92f0c6
commit
32a6775fd5
@ -28,6 +28,9 @@ from launchpadlib import launchpad
|
||||
from launchpadlib import uris
|
||||
import MySQLdb
|
||||
|
||||
from jeepyb import projects as p
|
||||
|
||||
|
||||
BASE_DIR = '/home/gerrit2/review_site'
|
||||
GERRIT_CACHE_DIR = os.path.expanduser(
|
||||
os.environ.get('GERRIT_CACHE_DIR',
|
||||
@ -63,22 +66,11 @@ DB_PASS = SECURE_CONFIG.get("database", "password")
|
||||
DB_DB = GERRIT_CONFIG.get("database", "database")
|
||||
|
||||
|
||||
def short_project(full_project_name):
|
||||
"""Return the project part of the git repository name."""
|
||||
return full_project_name.split('/')[-1]
|
||||
|
||||
|
||||
def git2lp(full_project_name):
|
||||
"""Convert Git repo name to Launchpad project."""
|
||||
project_map = {
|
||||
'stackforge/puppet-openstack_dev_env': 'puppet-openstack',
|
||||
'stackforge/puppet-quantum': 'puppet-neutron',
|
||||
}
|
||||
return project_map.get(full_project_name, short_project(full_project_name))
|
||||
|
||||
|
||||
def update_spec(launchpad, project, name, subject, link, topic=None):
|
||||
project = git2lp(project)
|
||||
if p.is_no_launchpad_blueprints(project):
|
||||
return
|
||||
|
||||
project = p.git2lp(project)
|
||||
spec = launchpad.projects[project].getSpecification(name=name)
|
||||
if not spec:
|
||||
return
|
||||
|
@ -26,6 +26,9 @@ from launchpadlib import launchpad
|
||||
from launchpadlib import uris
|
||||
|
||||
import jeepyb.gerritdb
|
||||
from jeepyb import projects as p
|
||||
from jeepyb import utils as u
|
||||
|
||||
|
||||
BASE_DIR = '/home/gerrit2/review_site'
|
||||
GERRIT_CACHE_DIR = os.path.expanduser(
|
||||
@ -46,7 +49,8 @@ def fix_or_related_fix(related):
|
||||
def add_change_proposed_message(bugtask, change_url, project, branch,
|
||||
related=False):
|
||||
fix = fix_or_related_fix(related)
|
||||
subject = '%s proposed to %s (%s)' % (fix, short_project(project), branch)
|
||||
subject = ('%s proposed to %s (%s)'
|
||||
% (fix, u.short_project_name(project), branch))
|
||||
body = '%s proposed to branch: %s\nReview: %s' % (fix, branch, change_url)
|
||||
bugtask.bug.newMessage(subject=subject, content=body)
|
||||
|
||||
@ -54,7 +58,7 @@ def add_change_proposed_message(bugtask, change_url, project, branch,
|
||||
def add_change_merged_message(bugtask, change_url, project, commit,
|
||||
submitter, branch, git_log, related=False):
|
||||
subject = '%s merged to %s (%s)' % (fix_or_related_fix(related),
|
||||
short_project(project), branch)
|
||||
u.short_project_name(project), branch)
|
||||
git_url = 'http://github.com/%s/commit/%s' % (project, commit)
|
||||
body = '''Reviewed: %s
|
||||
Committed: %s
|
||||
@ -140,106 +144,6 @@ def tag_in_branchname(bugtask, branch):
|
||||
lp_bug.lp_save()
|
||||
|
||||
|
||||
def short_project(full_project_name):
|
||||
"""Return the project part of the git repository name."""
|
||||
return full_project_name.split('/')[-1]
|
||||
|
||||
|
||||
def git2lp(full_project_name):
|
||||
"""Convert Git repo name to Launchpad project."""
|
||||
project_map = {
|
||||
'openstack/api-site': 'openstack-api-site',
|
||||
'openstack/identity-api': 'openstack-api-site',
|
||||
'openstack/object-api': 'openstack-api-site',
|
||||
'openstack/volume-api': 'openstack-api-site',
|
||||
'openstack/netconn-api': 'openstack-api-site',
|
||||
'openstack/compute-api': 'openstack-api-site',
|
||||
'openstack/image-api': 'openstack-api-site',
|
||||
'openstack/database-api': 'openstack-api-site',
|
||||
'openstack/quantum': 'neutron',
|
||||
'openstack/python-quantumclient': 'python-neutronclient',
|
||||
'openstack/oslo-incubator': 'oslo',
|
||||
'openstack/tripleo-incubator': 'tripleo',
|
||||
'openstack-infra/askbot-theme': 'openstack-ci',
|
||||
'openstack-infra/config': 'openstack-ci',
|
||||
'openstack-infra/devstack-gate': 'openstack-ci',
|
||||
'openstack-infra/gear': 'openstack-ci',
|
||||
'openstack-infra/gerrit': 'openstack-ci',
|
||||
'openstack-infra/gerritbot': 'openstack-ci',
|
||||
'openstack-infra/gerritlib': 'openstack-ci',
|
||||
'openstack-infra/gitdm': 'openstack-ci',
|
||||
'openstack-infra/jeepyb': 'openstack-ci',
|
||||
'openstack-infra/jenkins-job-builder': 'openstack-ci',
|
||||
'openstack-infra/lodgeit': 'openstack-ci',
|
||||
'openstack-infra/meetbot': 'openstack-ci',
|
||||
'openstack-infra/nose-html-output': 'openstack-ci',
|
||||
'openstack-infra/publications': 'openstack-ci',
|
||||
'openstack-infra/puppet-apparmor': 'openstack-ci',
|
||||
'openstack-infra/puppet-dashboard': 'openstack-ci',
|
||||
'openstack-infra/puppet-vcsrepo': 'openstack-ci',
|
||||
'openstack-infra/reviewday': 'openstack-ci',
|
||||
'openstack-infra/statusbot': 'openstack-ci',
|
||||
'openstack-infra/zmq-event-publisher': 'openstack-ci',
|
||||
'stackforge/cookbook-openstack-block-storage': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-common': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-compute': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-dashboard': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-identity': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-image': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-metering': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-network': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-object-storage': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-ops-database': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-ops-messaging': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-orchestration': 'openstack-chef',
|
||||
'stackforge/openstack-chef-repo': 'openstack-chef',
|
||||
'stackforge/puppet-openstack_dev_env': 'puppet-openstack',
|
||||
'stackforge/puppet-quantum': 'puppet-neutron',
|
||||
'stackforge/tripleo-heat-templates': 'tripleo',
|
||||
'stackforge/tripleo-image-elements': 'tripleo',
|
||||
}
|
||||
return project_map.get(full_project_name, short_project(full_project_name))
|
||||
|
||||
|
||||
def is_direct_release(full_project_name):
|
||||
"""Test against a list of projects who directly release changes."""
|
||||
return full_project_name in [
|
||||
'openstack/openstack-manuals',
|
||||
'openstack/api-site',
|
||||
'openstack/tripleo-incubator',
|
||||
'openstack/tempest',
|
||||
'openstack-dev/devstack',
|
||||
'openstack-infra/askbot-theme',
|
||||
'openstack-infra/config',
|
||||
'openstack-infra/devstack-gate',
|
||||
'openstack-infra/gerrit',
|
||||
'openstack-infra/gerritbot',
|
||||
'openstack-infra/gerritlib',
|
||||
'openstack-infra/gitdm',
|
||||
'openstack-infra/lodgeit',
|
||||
'openstack-infra/meetbot',
|
||||
'openstack-infra/nose-html-output',
|
||||
'openstack-infra/publications',
|
||||
'openstack-infra/reviewday',
|
||||
'openstack-infra/statusbot',
|
||||
'stackforge/cookbook-openstack-block-storage',
|
||||
'stackforge/cookbook-openstack-common',
|
||||
'stackforge/cookbook-openstack-compute',
|
||||
'stackforge/cookbook-openstack-dashboard',
|
||||
'stackforge/cookbook-openstack-identity',
|
||||
'stackforge/cookbook-openstack-image',
|
||||
'stackforge/cookbook-openstack-metering',
|
||||
'stackforge/cookbook-openstack-network',
|
||||
'stackforge/cookbook-openstack-object-storage',
|
||||
'stackforge/cookbook-openstack-ops-database',
|
||||
'stackforge/cookbook-openstack-ops-messaging',
|
||||
'stackforge/cookbook-openstack-orchestration',
|
||||
'stackforge/openstack-chef-repo',
|
||||
'stackforge/tripleo-heat-templates',
|
||||
'stackforge/tripleo-image-elements',
|
||||
]
|
||||
|
||||
|
||||
class Task:
|
||||
def __init__(self, lp_task, prefix):
|
||||
'''Prefixes associated with bug references will allow for certain
|
||||
@ -291,7 +195,7 @@ def process_bugtask(launchpad, task, git_log, args):
|
||||
|
||||
if args.hook == "change-merged":
|
||||
if args.branch == 'master':
|
||||
if (is_direct_release(args.project) and
|
||||
if (p.is_direct_release(args.project) and
|
||||
task.needs_change('set_fix_released')):
|
||||
set_fix_released(bugtask)
|
||||
else:
|
||||
@ -362,6 +266,13 @@ def find_bugs(launchpad, git_log, args):
|
||||
:returns: an iterable containing Task objects.
|
||||
'''
|
||||
|
||||
project = args.project
|
||||
|
||||
if p.is_no_launchpad_bugs(project):
|
||||
return []
|
||||
|
||||
project = p.git2lp(project)
|
||||
|
||||
part1 = r'^[\t ]*(?P<prefix>[-\w]+)?[\s:]*'
|
||||
part2 = r'(?:\b(?:bug|lp)\b[\s#:]*)+'
|
||||
part3 = r'(?P<bug_number>\d+)\s*?$'
|
||||
@ -377,7 +288,7 @@ def find_bugs(launchpad, git_log, args):
|
||||
try:
|
||||
lp_bug = launchpad.bugs[bug_num]
|
||||
for lp_task in lp_bug.bug_tasks:
|
||||
if lp_task.bug_target_name == git2lp(args.project):
|
||||
if lp_task.bug_target_name == project:
|
||||
bugtasks[bug_num] = Task(lp_task, prefix)
|
||||
break
|
||||
except KeyError:
|
||||
@ -424,5 +335,6 @@ def main():
|
||||
for task in find_bugs(lpconn, git_log, args):
|
||||
process_bugtask(lpconn, task, git_log, args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
186
jeepyb/projects.py
Normal file
186
jeepyb/projects.py
Normal file
@ -0,0 +1,186 @@
|
||||
# Copyright (c) 2013 Mirantis.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Expected review.projects.yaml format:
|
||||
|
||||
- project: some/project
|
||||
launchpad: awesomeproject
|
||||
description: Best project ever.
|
||||
options:
|
||||
- direct-release
|
||||
- no-launchpad-bugs
|
||||
- no-launchpad-blueprints
|
||||
"""
|
||||
|
||||
import jeepyb.utils as u
|
||||
|
||||
|
||||
registry = u.ProjectsYamlRegistry('/home/gerrit2/projects.yaml',
|
||||
'PROJECTS_YAML')
|
||||
|
||||
|
||||
def git2lp(project_full_name):
|
||||
try:
|
||||
return registry[project_full_name]['launchpad']
|
||||
except KeyError:
|
||||
return _hardcoded_git2lp(project_full_name)
|
||||
# return u.short_project_name(project_full_name)
|
||||
|
||||
|
||||
def _is_no_launchpad(project_full_name, obj_type):
|
||||
try:
|
||||
return ('no-launchpad-' + obj_type
|
||||
in registry[project_full_name]['options'])
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
|
||||
def is_no_launchpad_bugs(project_full_name):
|
||||
return _is_no_launchpad(project_full_name, 'bugs')
|
||||
|
||||
|
||||
def is_no_launchpad_blueprints(project_full_name):
|
||||
return _is_no_launchpad(project_full_name, 'blueprints')
|
||||
|
||||
|
||||
def is_direct_release(project_full_name):
|
||||
try:
|
||||
direct = 'direct-release' in registry[project_full_name]['options']
|
||||
# return ...
|
||||
except KeyError:
|
||||
direct = False
|
||||
# return False
|
||||
|
||||
return direct or _hardcoded_is_direct_release(project_full_name)
|
||||
|
||||
|
||||
# The following functions should be deleted when projects.yaml will be updated
|
||||
|
||||
def _hardcoded_is_direct_release(project_full_name):
|
||||
"""Test against a list of projects who directly release changes.
|
||||
|
||||
This function should be removed when projects.yaml will be updated.
|
||||
To specify direct_release you just need add option 'direct_relese' to your
|
||||
project declaration in projects.yaml
|
||||
|
||||
Example:
|
||||
- project: some/project
|
||||
options:
|
||||
- direct-release
|
||||
description: Best project ever.
|
||||
"""
|
||||
return project_full_name in [
|
||||
'openstack/openstack-manuals',
|
||||
'openstack/api-site',
|
||||
'openstack/tripleo-incubator',
|
||||
'openstack/tempest',
|
||||
'openstack-dev/devstack',
|
||||
'openstack-infra/askbot-theme',
|
||||
'openstack-infra/config',
|
||||
'openstack-infra/devstack-gate',
|
||||
'openstack-infra/gerrit',
|
||||
'openstack-infra/gerritbot',
|
||||
'openstack-infra/gerritlib',
|
||||
'openstack-infra/gitdm',
|
||||
'openstack-infra/lodgeit',
|
||||
'openstack-infra/meetbot',
|
||||
'openstack-infra/nose-html-output',
|
||||
'openstack-infra/publications',
|
||||
'openstack-infra/reviewday',
|
||||
'openstack-infra/statusbot',
|
||||
'stackforge/cookbook-openstack-block-storage',
|
||||
'stackforge/cookbook-openstack-common',
|
||||
'stackforge/cookbook-openstack-compute',
|
||||
'stackforge/cookbook-openstack-dashboard',
|
||||
'stackforge/cookbook-openstack-identity',
|
||||
'stackforge/cookbook-openstack-image',
|
||||
'stackforge/cookbook-openstack-metering',
|
||||
'stackforge/cookbook-openstack-network',
|
||||
'stackforge/cookbook-openstack-object-storage',
|
||||
'stackforge/cookbook-openstack-ops-database',
|
||||
'stackforge/cookbook-openstack-ops-messaging',
|
||||
'stackforge/cookbook-openstack-orchestration',
|
||||
'stackforge/openstack-chef-repo',
|
||||
'stackforge/tripleo-heat-templates',
|
||||
'stackforge/tripleo-image-elements',
|
||||
]
|
||||
|
||||
|
||||
def _hardcoded_git2lp(project_full_name):
|
||||
"""Convert Git repo name to Launchpad project.
|
||||
|
||||
This function should be removed when projects.yaml will be updated.
|
||||
To specify launchpad project name you just need add parameter 'lp' to your
|
||||
project declaration in projects.yaml
|
||||
|
||||
Example:
|
||||
- project: some/project
|
||||
launchpad: awesomeproject
|
||||
description: Best project ever.
|
||||
"""
|
||||
|
||||
project_map = {
|
||||
'openstack/api-site': 'openstack-api-site',
|
||||
'openstack/identity-api': 'openstack-api-site',
|
||||
'openstack/object-api': 'openstack-api-site',
|
||||
'openstack/volume-api': 'openstack-api-site',
|
||||
'openstack/netconn-api': 'openstack-api-site',
|
||||
'openstack/compute-api': 'openstack-api-site',
|
||||
'openstack/image-api': 'openstack-api-site',
|
||||
'openstack/database-api': 'openstack-api-site',
|
||||
'openstack/quantum': 'neutron',
|
||||
'openstack/python-quantumclient': 'python-neutronclient',
|
||||
'openstack/oslo-incubator': 'oslo',
|
||||
'openstack/tripleo-incubator': 'tripleo',
|
||||
'openstack-infra/askbot-theme': 'openstack-ci',
|
||||
'openstack-infra/config': 'openstack-ci',
|
||||
'openstack-infra/devstack-gate': 'openstack-ci',
|
||||
'openstack-infra/gear': 'openstack-ci',
|
||||
'openstack-infra/gerrit': 'openstack-ci',
|
||||
'openstack-infra/gerritbot': 'openstack-ci',
|
||||
'openstack-infra/gerritlib': 'openstack-ci',
|
||||
'openstack-infra/gitdm': 'openstack-ci',
|
||||
'openstack-infra/jeepyb': 'openstack-ci',
|
||||
'openstack-infra/jenkins-job-builder': 'openstack-ci',
|
||||
'openstack-infra/lodgeit': 'openstack-ci',
|
||||
'openstack-infra/meetbot': 'openstack-ci',
|
||||
'openstack-infra/nose-html-output': 'openstack-ci',
|
||||
'openstack-infra/publications': 'openstack-ci',
|
||||
'openstack-infra/puppet-apparmor': 'openstack-ci',
|
||||
'openstack-infra/puppet-dashboard': 'openstack-ci',
|
||||
'openstack-infra/puppet-vcsrepo': 'openstack-ci',
|
||||
'openstack-infra/reviewday': 'openstack-ci',
|
||||
'openstack-infra/statusbot': 'openstack-ci',
|
||||
'openstack-infra/zmq-event-publisher': 'openstack-ci',
|
||||
'stackforge/cookbook-openstack-block-storage': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-common': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-compute': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-dashboard': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-identity': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-image': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-metering': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-network': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-object-storage': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-ops-database': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-ops-messaging': 'openstack-chef',
|
||||
'stackforge/cookbook-openstack-orchestration': 'openstack-chef',
|
||||
'stackforge/openstack-chef-repo': 'openstack-chef',
|
||||
'stackforge/puppet-openstack_dev_env': 'puppet-openstack',
|
||||
'stackforge/puppet-quantum': 'puppet-neutron',
|
||||
'stackforge/tripleo-heat-templates': 'tripleo',
|
||||
'stackforge/tripleo-image-elements': 'tripleo',
|
||||
}
|
||||
return project_map.get(project_full_name,
|
||||
u.short_project_name(project_full_name))
|
47
jeepyb/utils.py
Normal file
47
jeepyb/utils.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright (c) 2013 Mirantis.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import yaml
|
||||
|
||||
|
||||
def short_project_name(full_project_name):
|
||||
"""Return the project part of the git repository name."""
|
||||
return full_project_name.split('/')[-1]
|
||||
|
||||
|
||||
class ProjectsYamlRegistry(object):
|
||||
"""review.projects.yaml style config file parser.
|
||||
|
||||
It could be used as dict 'project name' -> 'project properties'.
|
||||
"""
|
||||
|
||||
def __init__(self, file_path, env_name=None):
|
||||
self.file_path = file_path
|
||||
self.env_name = env_name
|
||||
|
||||
self._parse_file()
|
||||
|
||||
def _parse_file(self):
|
||||
file_path = os.environ.get(self.env_name, self.file_path)
|
||||
configs_list = [config for config in yaml.load_all(open(file_path))][1]
|
||||
|
||||
configs = {}
|
||||
for section in configs_list:
|
||||
configs[section['project']] = section
|
||||
|
||||
self.configs = configs
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.configs[item]
|
Loading…
x
Reference in New Issue
Block a user