Add specs base structure

This patch adds base structure for specs

Change-Id: Ie9da0b6070f16d6b78bd06aa44f0da2aad23dd5e
This commit is contained in:
Boris Pavlovic 2015-11-08 20:32:16 -08:00
parent b3011ad24a
commit 51761f3751
6 changed files with 223 additions and 0 deletions

11
doc/specs/README.rst Normal file
View File

@ -0,0 +1,11 @@
OSProfiler Specs
================
Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.
This directory contains 2 subdirectories:
- in-progress - These specs are approved, but they are not implemented yet
- implemented - Implemented specs archive

View File

@ -0,0 +1,8 @@
OSprofiler Implemented Specs
============================
Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.
This directory contains files with implemented specs, 1 file is 1 spec.

View File

@ -0,0 +1,9 @@
OSprofiler In-Progress Specs
============================
Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.
This directory contains files with accepted by not implemented specs,
1 file is 1 spec.

78
doc/specs/template.rst Normal file
View File

@ -0,0 +1,78 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
..
This template should be in ReSTructured text. The filename in the git
repository should match the launchpad URL, for example a URL of
https://blueprints.launchpad.net/heat/+spec/awesome-thing should be named
awesome-thing.rst . Please do not delete any of the sections in this
template. If you have nothing to say for a whole section, just write: None
For help with syntax, see http://sphinx-doc.org/rest.html
To test out your formatting, see http://www.tele3.cz/jbar/rest/rest.html
=======================
The title of your Spec
=======================
Introduction paragraph -- why are we doing anything?
Problem description
===================
A detailed description of the problem.
Proposed change
===============
Here is where you cover the change you propose to make in detail. How do you
propose to solve this problem?
If this is one part of a larger effort make it clear where this piece ends. In
other words, what's the scope of this effort?
Include where in the heat tree hierarchy this will reside.
Alternatives
------------
This is an optional section, where it does apply we'd just like a demonstration
that some thought has been put into why the proposed approach is the best one.
Implementation
==============
Assignee(s)
-----------
Who is leading the writing of the code? Or is this a blueprint where you're
throwing it out there to see who picks it up?
If more than one person is working on the implementation, please designate the
primary author and contact.
Primary assignee:
<launchpad-id or None>
Can optionally can list additional ids if they intend on doing
substantial implementation work on this blueprint.
Work Items
----------
Work items or tasks -- break the feature up into the things that need to be
done to implement it. Those parts might end up being done by different people,
but we're mostly trying to understand the timeline for implementation.
Dependencies
============
- Include specific references to specs and/or blueprints in heat, or in other
projects, that this one either depends on or is related to.
- Does this feature require any new library dependencies or code otherwise not
included in OpenStack? Or does it depend on a specific version of library?

0
tests/doc/__init__.py Normal file
View File

117
tests/doc/test_specs.py Normal file
View File

@ -0,0 +1,117 @@
# 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 glob
import os
import re
import docutils.core
from tests import test
class TitlesTestCase(test.TestCase):
specs_path = os.path.join(
os.path.dirname(__file__), os.pardir, os.pardir, "doc", "specs")
def _get_title(self, section_tree):
section = {"subtitles": []}
for node in section_tree:
if node.tagname == "title":
section["name"] = node.rawsource
elif node.tagname == "section":
subsection = self._get_title(node)
section["subtitles"].append(subsection["name"])
return section
def _get_titles(self, spec):
titles = {}
for node in spec:
if node.tagname == "section":
# Note subsection subtitles are thrown away
section = self._get_title(node)
titles[section["name"]] = section["subtitles"]
return titles
def _check_titles(self, filename, expect, actual):
missing_sections = [x for x in expect.keys() if x not in actual.keys()]
extra_sections = [x for x in actual.keys() if x not in expect.keys()]
msgs = []
if len(missing_sections) > 0:
msgs.append("Missing sections: %s" % missing_sections)
if len(extra_sections) > 0:
msgs.append("Extra sections: %s" % extra_sections)
for section in expect.keys():
missing_subsections = [x for x in expect[section]
if x not in actual.get(section, {})]
# extra subsections are allowed
if len(missing_subsections) > 0:
msgs.append("Section '%s' is missing subsections: %s"
% (section, missing_subsections))
if len(msgs) > 0:
self.fail("While checking '%s':\n %s"
% (filename, "\n ".join(msgs)))
def _check_lines_wrapping(self, tpl, raw):
for i, line in enumerate(raw.split("\n")):
if "http://" in line or "https://" in line:
continue
self.assertTrue(
len(line) < 80,
msg="%s:%d: Line limited to a maximum of 79 characters." %
(tpl, i+1))
def _check_no_cr(self, tpl, raw):
matches = re.findall("\r", raw)
self.assertEqual(
len(matches), 0,
"Found %s literal carriage returns in file %s" %
(len(matches), tpl))
def _check_trailing_spaces(self, tpl, raw):
for i, line in enumerate(raw.split("\n")):
trailing_spaces = re.findall(" +$", line)
self.assertEqual(
len(trailing_spaces), 0,
"Found trailing spaces on line %s of %s" % (i+1, tpl))
def test_template(self):
with open(os.path.join(self.specs_path, "template.rst")) as f:
template = f.read()
spec = docutils.core.publish_doctree(template)
template_titles = self._get_titles(spec)
for d in ["implemented", "in-progress"]:
spec_dir = "%s/%s" % (self.specs_path, d)
self.assertTrue(os.path.isdir(spec_dir),
"%s is not a directory" % spec_dir)
for filename in glob.glob(spec_dir + "/*"):
if filename.endswith("README.rst"):
continue
self.assertTrue(
filename.endswith(".rst"),
"spec's file must have .rst ext. Found: %s" % filename)
with open(filename) as f:
data = f.read()
titles = self._get_titles(docutils.core.publish_doctree(data))
self._check_titles(filename, template_titles, titles)
self._check_lines_wrapping(filename, data)
self._check_no_cr(filename, data)
self._check_trailing_spaces(filename, data)