group service and library projects separately
Split the deliverables based on whether they are a service or library. Default to service, since we do have some untagged projects and they tend toward service rather than library. Change-Id: Icaa2bacf5aadf7c53543c6c4a1abc5ef62eb77e7
This commit is contained in:
77
openstack_releases/governance.py
Normal file
77
openstack_releases/governance.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# 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.
|
||||
|
||||
"""Work with the governance repository.
|
||||
"""
|
||||
|
||||
import weakref
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
PROJECTS_LIST = "http://git.openstack.org/cgit/openstack/governance/plain/reference/projects.yaml" # noqa
|
||||
|
||||
|
||||
def get_team_data(url=PROJECTS_LIST):
|
||||
"""Return the parsed team data from the governance repository.
|
||||
|
||||
:param url: Optional URL to the location of the projects.yaml
|
||||
file. Defaults to the most current version in the public git
|
||||
repository.
|
||||
|
||||
"""
|
||||
r = requests.get(url)
|
||||
return yaml.load(r.text)
|
||||
|
||||
|
||||
class Team(object):
|
||||
def __init__(self, name, data):
|
||||
self.name = name
|
||||
self.data = data
|
||||
self.deliverables = {
|
||||
dn: Deliverable(dn, di, self)
|
||||
for dn, di in self.data.get('deliverables', {}).items()
|
||||
}
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return set(self.data.get('tags', []))
|
||||
|
||||
|
||||
class Deliverable(object):
|
||||
def __init__(self, name, data, team):
|
||||
self.name = name
|
||||
self.data = data
|
||||
self.team = weakref.proxy(team)
|
||||
self.repositories = {
|
||||
rn: Repository(rn, self)
|
||||
for rn in self.data.get('repos', [])
|
||||
}
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return set(self.data.get('tags', [])).union(self.team.tags)
|
||||
|
||||
|
||||
class Repository(object):
|
||||
def __init__(self, name, deliverable):
|
||||
self.name = name
|
||||
self.deliverable = weakref.proxy(deliverable)
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return self.deliverable.tags
|
||||
|
||||
@property
|
||||
def code_related(self):
|
||||
return not (self.name.endswith('-specs')
|
||||
or 'cookiecutter' in self.name)
|
||||
@@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import glob
|
||||
import os.path
|
||||
|
||||
@@ -23,6 +24,8 @@ from sphinx.util.nodes import nested_parse_with_titles
|
||||
|
||||
import yaml
|
||||
|
||||
from openstack_releases import governance
|
||||
|
||||
|
||||
def _list_table(add, headers, data, title='', columns=None):
|
||||
"""Build a list-table directive.
|
||||
@@ -46,16 +49,35 @@ def _list_table(add, headers, data, title='', columns=None):
|
||||
add('')
|
||||
|
||||
|
||||
def _get_deliverable_type(deliverable_types, name):
|
||||
if (name.startswith('python-') and not name.endswith('client')):
|
||||
name = name[7:]
|
||||
if (name.startswith('python-') and name.endswith('client')):
|
||||
return 'type:library'
|
||||
if name in deliverable_types:
|
||||
return deliverable_types[name]
|
||||
no_dashes = name.replace('-', '_')
|
||||
if no_dashes in deliverable_types:
|
||||
return deliverable_types[no_dashes]
|
||||
return 'type:service'
|
||||
|
||||
|
||||
class DeliverableDirective(rst.Directive):
|
||||
|
||||
option_spec = {
|
||||
'series': directives.unchanged,
|
||||
}
|
||||
|
||||
_TYPE_ORDER = [
|
||||
'type:service',
|
||||
'type:library',
|
||||
]
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
app = env.app
|
||||
source_name = '<' + __name__ + '>'
|
||||
|
||||
team_data = governance.get_team_data()
|
||||
|
||||
series = self.options.get('series')
|
||||
if not series:
|
||||
@@ -65,25 +87,74 @@ class DeliverableDirective(rst.Directive):
|
||||
line=self.lineno)
|
||||
return [error]
|
||||
|
||||
deliverable_types = {}
|
||||
for team in (governance.Team(n, i) for n, i in team_data.items()):
|
||||
for dn, di in team.deliverables.items():
|
||||
for tag in di.tags:
|
||||
if tag.startswith('type:'):
|
||||
deliverable_types[dn] = tag
|
||||
|
||||
result = ViewList()
|
||||
|
||||
# Read all of the deliverable data for the series.
|
||||
|
||||
deliverables = []
|
||||
deliverables = collections.defaultdict(list)
|
||||
|
||||
for filename in sorted(glob.glob('deliverables/%s/*.yaml' % series)):
|
||||
app.info('[deliverables] reading %s' % filename)
|
||||
deliverable_name = os.path.basename(filename)[:-5] # strip .yaml ext
|
||||
deliverable_name = os.path.basename(filename)[:-5] # strip .yaml
|
||||
deliverable_type = _get_deliverable_type(
|
||||
deliverable_types,
|
||||
deliverable_name,
|
||||
)
|
||||
with open(filename, 'r') as f:
|
||||
deliverables.append((deliverable_name,
|
||||
filename,
|
||||
yaml.load(f.read())))
|
||||
deliverables[deliverable_type].append(
|
||||
(deliverable_name,
|
||||
filename,
|
||||
yaml.load(f.read())))
|
||||
|
||||
for type_tag in self._TYPE_ORDER:
|
||||
self._add_deliverables(
|
||||
type_tag,
|
||||
deliverables[type_tag],
|
||||
series,
|
||||
app,
|
||||
result,
|
||||
)
|
||||
|
||||
# NOTE(dhellmann): Useful for debugging.
|
||||
# print('\n'.join(result))
|
||||
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, result, node)
|
||||
return node.children
|
||||
|
||||
_TYPE_TITLE = {
|
||||
'type:service': 'Service Projects',
|
||||
'type:library': 'Library Projects',
|
||||
}
|
||||
|
||||
def _add_deliverables(self, type_tag, deliverables, series, app, result):
|
||||
source_name = '<' + __name__ + '>'
|
||||
|
||||
if not deliverables:
|
||||
# There are no deliverables of this type, and that's OK.
|
||||
return
|
||||
|
||||
result.append('', source_name)
|
||||
title = self._TYPE_TITLE.get(type_tag, 'Unknown Projects')
|
||||
result.append('-' * len(title), source_name)
|
||||
result.append(title, source_name)
|
||||
result.append('-' * len(title), source_name)
|
||||
result.append('', source_name)
|
||||
|
||||
# Build a table of the most recent version of each deliverable.
|
||||
|
||||
most_recent = []
|
||||
for deliverable_name, filename, deliverable_info in deliverables:
|
||||
version = deliverable_info.get('releases', {})[-1].get('version', 'unreleased')
|
||||
version = deliverable_info.get('releases', {})[-1].get(
|
||||
'version', 'unreleased')
|
||||
ref = ':ref:`%s-%s`' % (series, deliverable_name)
|
||||
most_recent.append((ref, version))
|
||||
_list_table(
|
||||
@@ -103,7 +174,7 @@ class DeliverableDirective(rst.Directive):
|
||||
result.append(text, filename)
|
||||
|
||||
def _title(text, underline):
|
||||
text = str(text) # version numbers might be converted to floats
|
||||
text = str(text) # version numbers might be seen as floats
|
||||
_add('.. _%s-%s:' % (series, text))
|
||||
_add('')
|
||||
_add(text)
|
||||
@@ -111,7 +182,7 @@ class DeliverableDirective(rst.Directive):
|
||||
_add('')
|
||||
|
||||
def _rubric(text):
|
||||
text = str(text) # version numbers might be converted to floats
|
||||
text = str(text) # version numbers might be seen as floats
|
||||
_add('.. rubric:: %s' % text)
|
||||
_add('')
|
||||
|
||||
@@ -128,11 +199,6 @@ class DeliverableDirective(rst.Directive):
|
||||
columns=[10, 40, 50],
|
||||
)
|
||||
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, result, node)
|
||||
return node.children
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('deliverable', DeliverableDirective)
|
||||
|
||||
Reference in New Issue
Block a user