Allow module name aliases for mapping to Launchpad projects

Some project may have different names for repo and for Launchpad 
project. E.g. Fuel has a number of repos, LP project is called 'fuel' 
and there's no repo called 'fuel'. To enable bugs and blueprint 
processing the project is configured to have alias name 'fuel'.

This patch also improved blueprint details report.

Change-Id: Ic5e5869bba675aa7f7ccb5a73527390cd67739cd
This commit is contained in:
Ilya Shakhat 2015-09-07 17:37:42 +03:00
parent 1597e55b10
commit af11c4285d
7 changed files with 87 additions and 32 deletions

View File

@ -114,7 +114,7 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
for (i = 0; i < data.length; i++) {
if (i < limit - 1) {
chartData.push([data[i].name.trunc(30), data[i].metric]);
chartData.push([data[i].name.trunc(36), data[i].metric]);
} else {
aggregate += data[i].metric;
}
@ -137,7 +137,7 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
}
if (i == limit) {
chartData.push([data[i - 1].name.trunc(30), data[i - 1].metric]);
chartData.push([data[i - 1].name.trunc(36), data[i - 1].metric]);
} else if (i > limit) {
chartData.push(["others", aggregate]);
}

View File

@ -6,30 +6,39 @@ Blueprint &ldquo;{{ blueprint.title }}&rdquo; report
{% endblock %}
{% block content %}
<h1>Blueprint &ldquo;{{ blueprint.name }}&rdquo;</h1>
<h1>Blueprint &ldquo;{{ blueprint.title }}&rdquo;</h1>
<div><span class="label">Title:</span> {{ blueprint.title }}</div>
<div><span class="label">URL:</span> <a href="https://blueprints.launchpad.net/{{ blueprint.module }}/+spec/{{ blueprint.name }}">https://blueprints.launchpad.net/{{ blueprint.module }}/+spec/{{ blueprint.name }}</a></div>
<div><span class="label">Module:</span> {{blueprint.module}}</div>
<div><span class="label">Name:</span> {{ blueprint.name }}</div>
<div><span class="label">URL:</span>
{% if blueprint.web_link %}
<a href="{{ blueprint.web_link }}" class="ext_link">{{ blueprint.web_link }}</a>
{% else %}
<a href="https://blueprints.launchpad.net/{{ blueprint.module }}/+spec/{{ blueprint.name }}" class="ext_link">https://blueprints.launchpad.net/{{ blueprint.module }}/+spec/{{ blueprint.name }}</a>
{% endif %}
</div>
<div><span class="label">Module:</span> {{ blueprint.module_link | safe }}</div>
<div><span class="label">Status:</span> <span class="status{{blueprint.lifecycle_status}}">{{blueprint.lifecycle_status}}</span></div>
<div><span class="label">Priority:</span> <span class="status{{blueprint.priority}}">{{blueprint.priority}}</span></div>
<div><span class="label">Priority:</span> <span class="specpriority{{blueprint.priority}}">{{blueprint.priority}}</span></div>
<div><span class="label">Definition Status:</span> <span class="specstatus{{blueprint.definition_status}}">{{blueprint.definition_status}}</span></div>
<div><span class="label">Implementation Status:</span> <span class="specdelivery{{blueprint.implementation_status}}">{{blueprint.implementation_status}}</span></div>
<div><span class="label">Direction:</span> {% if blueprint.direction_approved %} Approved {% else %} Needs Approval {% endif %}</div>
<div><span class="label">Registered By:</span> {{blueprint.author_name}} ({{ blueprint.company_name }})</div>
<div><span class="label">Registered On:</span> {{blueprint.date_str}}</div>
<div><span class="label">Registered By:</span> {{ blueprint.author_link | safe }} ({{ blueprint.company_link | safe }})</div>
<div><span class="label">Registered On:</span> {{ blueprint.date_str }}</div>
{% if blueprint.mention_count %}
<div><span class="label">Popularity:</span> mentioned {{blueprint.mention_count}} times, last on {{blueprint.mention_date_str}}</div>
{% endif %}
{% if blueprint.specification_url %}
<div><span class="label">Specification:</span> <a href="{{ blueprint.specification_url }}" class="ext_link">{{ blueprint.specification_url }}</a></div>
{% endif %}
{% if blueprint.summary %}
<h2>Summary</h2>
<div class="message">{{ blueprint.summary | safe }}</div>
<div class="record"><div class="message">{{ blueprint.summary | safe }}</div></div>
{% endif %}
{% if blueprint.whiteboard %}
<h2>Whiteboard</h2>
<div class="message">{{ blueprint.whiteboard }}</div>
<div class="record"><div class="message">{{ blueprint.whiteboard }}</div></div>
{% endif %}
{{ activity_log.show_activity_log(blueprint_id=blueprint.id, gravatar_size=64) }}

View File

@ -30,14 +30,7 @@ def _get_bug_id(web_link):
return web_link[web_link.rfind('/') + 1:]
def log(repo, modified_since):
module = repo['module']
LOG.debug('Retrieving list of bugs for module: %s', module)
if not launchpad_utils.lp_module_exists(module):
LOG.debug('Module %s does not exist at Launchpad', module)
return
def _log_module(module, primary_module, modified_since):
for record_draft in launchpad_utils.lp_bug_generator(module,
modified_since):
@ -67,8 +60,24 @@ def log(repo, modified_since):
record[field] = utils.iso8601_to_timestamp(date)
bug_id = _get_bug_id(record_draft['web_link'])
record['module'] = module
record['id'] = utils.make_bug_id(bug_id, module, record.get('release'))
record['module'] = primary_module
record['id'] = utils.make_bug_id(bug_id, primary_module,
record.get('release'))
LOG.debug('New bug: %s', record)
yield record
def log(repo, modified_since):
repo_module = repo['module']
modules = [repo_module] + repo.get('aliases', [])
for module in modules:
if not launchpad_utils.lp_module_exists(module):
LOG.debug('Module %s does not exist at Launchpad, skip it', module)
continue
LOG.debug('Retrieving list of bugs for module: %s', module)
for record in _log_module(module, repo_module, modified_since):
yield record

View File

@ -26,14 +26,7 @@ LINK_FIELDS = ['owner', 'drafter', 'starter', 'completer',
DATE_FIELDS = ['date_created', 'date_completed', 'date_started']
def log(repo):
module = repo['module']
LOG.debug('Retrieving list of blueprints for module: %s', module)
if not launchpad_utils.lp_module_exists(module):
LOG.debug('Module %s does not exist at Launchpad', module)
return
def _log_module(module, primary_module):
for record in launchpad_utils.lp_blueprint_generator(module):
for field in LINK_FIELDS:
link = record[field + '_link']
@ -45,8 +38,22 @@ def log(repo):
if date:
record[field] = utils.iso8601_to_timestamp(date)
record['module'] = module
record['id'] = utils.get_blueprint_id(module, record['name'])
record['module'] = primary_module
record['id'] = utils.get_blueprint_id(primary_module, record['name'])
LOG.debug('New blueprint: %s', record)
yield record
def log(repo):
repo_module = repo['module']
modules = [repo_module] + repo.get('aliases', [])
for module in modules:
if not launchpad_utils.lp_module_exists(module):
LOG.debug('Module %s does not exist at Launchpad, skip it', module)
return
LOG.debug('Retrieving list of blueprints for module: %s', module)
for record in _log_module(module, repo_module):
yield record

View File

@ -468,6 +468,7 @@ class RecordProcessor(object):
bpd['primary_key'] = 'bpd:' + record['id']
bpd['launchpad_id'] = bpd_author
bpd['date'] = record['date_created']
bpd['web_link'] = record.get('web_link')
self._update_record_and_user(bpd)

View File

@ -219,3 +219,32 @@ class TestBps(testtools.TestCase):
actual = list(bps.log(repo, modified_since))
self.assertEqual(expected, actual)
@mock.patch('stackalytics.processor.launchpad_utils.lp_module_exists')
@mock.patch('stackalytics.processor.launchpad_utils.lp_bug_generator')
def test_log_module_alias(self, lp_bug_generator, lp_module_exists):
# bug linked to another project should not appear
repo = {
'module': 'savanna',
'aliases': ['sahara']
}
modified_since = 1234567890
lp_bug_generator.return_value = iter([BUG])
lp_module_exists.side_effect = iter([False, True])
expected = [{
'assignee': 'slukjanov',
'date_created': 1433252154,
'date_fix_committed': 1433266265,
'id': 'savanna/1458945',
'importance': 'Medium',
'module': 'savanna', # should be the same as primary module name
'owner': 'samueldmq',
'status': 'Fix Released',
'title': 'Bug #1458945 in Sahara: "Use graduated oslo.policy"',
'web_link': 'https://bugs.launchpad.net/sahara/+bug/1458945'
}]
actual = list(bps.log(repo, modified_since))
self.assertEqual(expected, actual)

View File

@ -37,4 +37,4 @@ commands = python setup.py build_sphinx
ignore = E123,E125,H904
show-source = true
builtins = _
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,tools,build
exclude=.venv*,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,tools,build