Merge "Add a script for counting blueprints"

This commit is contained in:
Zuul
2019-04-05 20:18:27 +00:00
committed by Gerrit Code Review
4 changed files with 123 additions and 19 deletions

75
tools/count_blueprints.py Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python
# 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 argparse
import os
import lib
def get_options():
parser = argparse.ArgumentParser(
description='Count blueprints for a given release. Requires '
'launchpadlib to be installed.')
parser.add_argument('release', help='The release to process.',
choices=lib.get_releases())
return parser.parse_args()
def count_blueprints(release):
lp_nova = lib.get_lp_nova('count-specs')
# Valid specifications are specifications that are not obsolete.
blueprints = lp_nova.getSeries(name=release).valid_specifications
targeted = len(blueprints)
approved = 0
implemented = 0
unapproved_blueprint_names = set()
for blueprint in blueprints:
if blueprint.definition_status == 'Approved':
approved += 1
else:
unapproved_blueprint_names.add(blueprint.name)
if blueprint.implementation_status == 'Implemented':
implemented += 1
print('')
print('Summary')
print('-------')
print('Number of Targeted blueprints: %d' % targeted)
print('Number of Approved blueprints: %d' % approved)
print('Number of Implemented blueprints: %d' % implemented)
# Check for approved specs whose blueprints have not been approved
cwd = os.getcwd()
approved_dir = os.path.join(cwd, 'specs', release, 'approved')
approved_specs = os.listdir(approved_dir)
template_file = '%s-template.rst' % release
for spec_fname in sorted(approved_specs):
# get the blueprint name, it should be the name of the rst file
if not spec_fname.endswith('.rst'):
continue
# check for the template file and skip that
if spec_fname == template_file:
continue
bp_name = spec_fname.split('.rst')[0]
if bp_name in unapproved_blueprint_names:
print('WARNING: Blueprint for spec %s needs approval.' %
spec_fname)
def main():
opts = get_options()
count_blueprints(opts.release)
if __name__ == '__main__':
main()

38
tools/lib.py Normal file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python
# 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
from launchpadlib import launchpad
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
def get_releases():
# 3-tuple (dirpath, dirnames, filenames)
for _, choices, _ in os.walk('specs'):
choices.remove('backlog')
choices.sort()
# Quit walking (release dirs are at the first level in 'specs')
break
return choices
def get_lp_nova(consumer_name):
# NOTE(mriedem): We have to use the development API since getSpecification
# is not in the v1.0 API.
# NOTE(melwitt): We have to use the development API because the
# valid_specifications attribute is not in the v1.0 API.
lp = launchpad.Launchpad.login_anonymously(
consumer_name, 'production', LPCACHEDIR, version='devel')
return lp.projects['nova']

View File

@@ -18,19 +18,7 @@ from __future__ import print_function
import argparse
import os
from launchpadlib import launchpad
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
def get_choices():
# 3-tuple (dirpath, dirnames, filenames)
for _, choices, _ in os.walk('specs'):
choices.remove('backlog')
choices.sort()
# Quit walking (release dirs are at the first level in 'specs')
break
return choices
import lib
def get_options():
@@ -43,7 +31,7 @@ def get_options():
help='Do everything except move the files.',
action='store_true')
parser.add_argument('release', help='The release to process.',
choices=get_choices())
choices=lib.get_releases())
return parser.parse_args()
@@ -56,11 +44,7 @@ def move_implemented_specs(release, verbose=False, dry_run=False):
implemented_dir = os.path.join(cwd, 'specs', release, 'implemented')
redirects_file = os.path.join(cwd, 'specs', release, 'redirects')
approved_specs = os.listdir(approved_dir)
# NOTE(mriedem): We have to use the development API since getSpecification
# is not in the v1.0 API.
lp = launchpad.Launchpad.login_anonymously(
'move-specs', 'production', LPCACHEDIR, version='devel')
lp_nova = lp.projects['nova']
lp_nova = lib.get_lp_nova('move-specs')
# yay for stats and summaries
move_count = 0
incomplete_count = 0

View File

@@ -34,5 +34,12 @@ exclude = .venv,.git,.tox,doc,.eggs
# fails if we don't have it.
deps = launchpadlib
simplejson
envdir={toxworkdir}/launchpadlib
commands =
python {toxinidir}/tools/move_implemented_specs.py {posargs}
[testenv:count-blueprints]
deps = {[testenv:move-implemented-specs]deps}
envdir={toxworkdir}/launchpadlib
commands =
python {toxinidir}/tools/count_blueprints.py {posargs}