summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-01-11 20:31:19 +0000
committerGerrit Code Review <review@openstack.org>2015-01-11 20:31:19 +0000
commit33d48509bcf0e6afe7637ce4ec2c072c8412fc3a (patch)
tree94e804aa85b00afc5213207aa7181da316842d56
parentc01c2265383fab6414d715cbb08ae8b294b1921c (diff)
parent4ce81f85fbee729a443d5c6e2f20fb328f18a9db (diff)
downloadoslosphinx-33d48509bcf0e6afe7637ce4ec2c072c8412fc3a.tar.gz
Merge "Add an extension for validating blueprint names"
-rw-r--r--doc/source/check_blueprints.rst48
-rw-r--r--doc/source/index.rst1
-rw-r--r--doc/source/usage.rst6
-rw-r--r--oslosphinx/check_blueprints.py110
-rw-r--r--requirements.txt1
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