diff options
author | Doug Hellmann <doug@doughellmann.com> | 2014-12-09 09:55:54 -0500 |
---|---|---|
committer | Doug Hellmann <doug@doughellmann.com> | 2014-12-09 15:49:01 -0500 |
commit | 4ce81f85fbee729a443d5c6e2f20fb328f18a9db (patch) | |
tree | 8a403afac53050bdbe4c9820992d0f5aefc5f7c6 | |
parent | 879cbc5e9a0683941cfe32c7aaa5940bcbeecfd3 (diff) | |
download | oslosphinx-4ce81f85fbee729a443d5c6e2f20fb328f18a9db.tar.gz |
Add an extension for validating blueprint names
This new extension requires spec filenames to match blueprint names in
the relevant project. This is based on work originally done in
oslo-specs under https://review.openstack.org/#/c/138392/
Change-Id: Ifd58f4f71f661229f09ecf01047bc7a7b1dc0b08
-rw-r--r-- | doc/source/check_blueprints.rst | 48 | ||||
-rw-r--r-- | doc/source/index.rst | 1 | ||||
-rw-r--r-- | doc/source/usage.rst | 6 | ||||
-rw-r--r-- | oslosphinx/check_blueprints.py | 110 | ||||
-rw-r--r-- | requirements.txt | 1 |
5 files changed, 163 insertions, 3 deletions
diff --git a/doc/source/check_blueprints.rst b/doc/source/check_blueprints.rst new file mode 100644 index 0000000..1d3ed2a --- /dev/null +++ b/doc/source/check_blueprints.rst @@ -0,0 +1,48 @@ +=========================================================== + Using oslosphinx.check_blueprints with Specs Repositories +=========================================================== + +The ``oslosphinx.check_blueprints`` extension verifies that the +filenames in spec repositories match a blueprint under a given +launchpad project. + +Enabling +======== + +Add ``'oslosphinx.check_blueprints'`` to the ``extensions`` list in +the ``conf.py`` file in your Sphinx project. + +Specifying the Launchpad Project +================================ + +Most projects should set ``check_blueprints_project`` to the name of +their launchpad project. This limits the search to the single project +named. + +:: + + check_blueprints_project = 'nova' + +Projects with multiple launchpad projects under their own project +group (such as Oslo), should instead set +``check_blueprints_project_group``. All projects in the group will be +scanned for each spec/blueprint name. + +:: + + check_blueprints_project_group = 'oslo' + +Checking Only the Current Release +================================= + +By default, all files under ``specs/`` are checked. For large specs +repositories, this can take a long time. To limit the checks to a +subdirectory for the current release, set +``check_blueprints_release``. + +For example:: + + check_blueprints_release = 'kilo' + +will cause files under ``specs/kilo`` to be checked, and other files +to be ignored. diff --git a/doc/source/index.rst b/doc/source/index.rst index 24f424d..6481815 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -6,6 +6,7 @@ :maxdepth: 2 usage + check_blueprints contributing Indices and tables diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 61c8fbd..a291a3c 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -1,6 +1,6 @@ -================== - Using oslosphinx -================== +============================ + Using the oslosphinx Theme +============================ To use the theme, add ``'oslosphinx'`` to the ``extensions`` list in the ``conf.py`` file in your Sphinx project. diff --git a/oslosphinx/check_blueprints.py b/oslosphinx/check_blueprints.py new file mode 100644 index 0000000..56fb86d --- /dev/null +++ b/oslosphinx/check_blueprints.py @@ -0,0 +1,110 @@ +# All Rights Reserved. +# +# 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. +"""Ensure that the name of the spec file matches the name of a blueprint. +""" + +import requests + + +class BlueprintChecker(object): + + def __init__(self, app): + self.app = app + self.project_names = [] + self._good_bps = set() + self._prefix = None + self._warn_search = 'unset' + + BP_URL_TEMPLATE = 'https://api.launchpad.net/devel/%s/+spec/%s' + PROJ_LIST_URL_TEMPLATE = 'https://api.launchpad.net/1.0/%s/projects' + + def _load_project_settings(self): + if self.project_names: + return + # If a project_name is set in the configuration, use + # that. Otherwise, allow any project in the project group. + project_name = self.app.config.check_blueprints_project + pg_name = self.app.config.check_blueprints_project_group + if project_name: + self.project_names = [project_name] + self._warn_search = 'the %s project' % project_name + else: + proj_list_response = requests.get(self.PROJ_LIST_URL_TEMPLATE + % pg_name) + projects = proj_list_response.json()['entries'] + self.project_names = [p['name'] for p in projects] + self._warn_search = ('any projects in the %s project group' + % pg_name) + + @property + def desired_prefix(self): + """Determine the prefix for files we care to check. + + We only care about blueprints in the current release, if the + check_blueprints_release option is set. + + """ + if self._prefix is None: + release = self.app.config.check_blueprints_release + if release: + self._prefix = 'specs/%s/' % release + else: + self._prefix = 'specs/' + return self._prefix + + def doctree_resolved(self, app, doctree, docname): + """Hook registered as event handler.""" + if not docname.startswith(self.desired_prefix): + return + bp_name = docname.split('/')[-1] + if bp_name == 'index': + return + self.check(bp_name) + + def blueprint_exists(self, project_name, bp_name): + """Return boolean indicating whether the blueprint exists.""" + url = self.BP_URL_TEMPLATE % (project_name, bp_name) + response = requests.get(url) + return response.status_code == 200 + + def check(self, bp_name): + """Given one blueprint name, check to see if it is valid.""" + if bp_name in self._good_bps: + return True + self._load_project_settings() + self.app.info('') # emit newline + for project_name in self.project_names: + self.app.info('Checking for %s in %s' % (bp_name, project_name)) + if self.blueprint_exists(project_name, bp_name): + self.app.info('Found %s in %s' % (bp_name, project_name)) + self._good_bps.add(bp_name) + break + else: + self.app.warn( + 'Could not find a blueprint called %r in %s' + % (bp_name, self._warn_search), + location=(bp_name, 0), + ) + raise ValueError( + 'Document %s does not match any blueprint name in %s' + % (bp_name, self._warn_search)) + + +def setup(app): + app.info('Initializing %s' % __name__) + checker = BlueprintChecker(app) + app.connect('doctree-resolved', checker.doctree_resolved) + app.add_config_value('check_blueprints_project_group', 'openstack', 'env') + app.add_config_value('check_blueprints_project', '', 'env') + app.add_config_value('check_blueprints_release', '', 'env') diff --git a/requirements.txt b/requirements.txt index c81bd8e..19d3ae5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ # process, which may cause wedges in the gate later. pbr>=0.6,!=0.7,<1.0 +requests>=2.2.0,!=2.4.0 |