Generate the constraints redirections from the deliverable data
Instead of statically listing the redirections move to a dynamic model. We move the existing _extras/.htaccess to _templates/htaccess so we have some control and safety of what goes in there. Connect 'build-finished' from _exts.deliverables.py to trigger generating the redirects. Doing so here avoids re-reading the data as deliverables.py ahas already done that for us. Change-Id: If6bd59fd478593a84ebcedc3a50af3720d620d3c
This commit is contained in:
parent
6b9db7e638
commit
752ce5a491
|
@ -1,13 +0,0 @@
|
|||
redirect 301 /teams/shade.html /teams/openstacksdk.html
|
||||
redirect 301 /constraints/upper/master http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
redirect 301 /constraints/upper/train http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
redirect 301 /constraints/upper/stein http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
redirect 301 /constraints/upper/rocky http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky
|
||||
redirect 301 /constraints/upper/queens http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/queens
|
||||
redirect 301 /constraints/upper/pike http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/pike
|
||||
redirect 301 /constraints/upper/ocata http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/ocata
|
||||
redirect 301 /constraints/upper/newton http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/newton
|
||||
redirect 301 /constraints/upper/mitaka http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=mitaka-eol
|
||||
redirect 301 /constraints/upper/liberty http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=liberty-eol
|
||||
redirect 301 /constraints/upper/kilo http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=kilo-eol
|
||||
redirect 301 /constraints/upper/juno http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=juno-eol
|
|
@ -28,6 +28,7 @@ from sphinx.util.nodes import nested_parse_with_titles
|
|||
from openstack_releases import deliverable
|
||||
from openstack_releases import links
|
||||
from openstack_releases import series_status
|
||||
from openstack_releases._redirections import generate_constraints_redirections
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -467,6 +468,23 @@ class HighlightsDirective(rst.Directive):
|
|||
return node.children
|
||||
|
||||
|
||||
def build_finished(app, exception):
|
||||
if exception is not None:
|
||||
return
|
||||
|
||||
rendered_output = app.builder.templates.render(
|
||||
'htaccess',
|
||||
dict(redirections=generate_constraints_redirections(_deliverables))
|
||||
)
|
||||
output_full_name = os.path.join(app.builder.outdir, '.htaccess')
|
||||
with open(output_full_name, "w") as f:
|
||||
f.write(rendered_output)
|
||||
LOG.info('Wrote Redirections to %s' % (output_full_name))
|
||||
# NOTE(tonyb): We want to output this here because we won't be able to
|
||||
# get to it via http{,s} so this helps debugging.
|
||||
LOG.debug(rendered_output)
|
||||
|
||||
|
||||
def setup(app):
|
||||
_initialize_deliverable_data()
|
||||
app.add_directive('deliverable', DeliverableDirective)
|
||||
|
@ -474,4 +492,5 @@ def setup(app):
|
|||
IndependentDeliverablesDirective)
|
||||
app.add_directive('team', TeamDirective)
|
||||
app.add_directive('serieshighlights', HighlightsDirective)
|
||||
app.connect('build-finished', build_finished)
|
||||
_generate_team_pages()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
redirect 301 /teams/shade.html /teams/openstacksdk.html
|
||||
redirect 301 /constraints/upper/master http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
{%- for redirection in redirections %}
|
||||
redirect {{ redirection.code }} /constraints/upper/{{ redirection.src }} http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h={{ redirection.dst }}
|
||||
{%- endfor %}
|
||||
|
|
@ -30,7 +30,7 @@ config_generator_config_file = 'config-generator.conf'
|
|||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
# templates_path = []
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
@ -66,8 +66,6 @@ htmlhelp_basename = '%sdoc' % project
|
|||
git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
|
||||
html_last_updated_fmt = os.popen(git_cmd).read()
|
||||
|
||||
html_extra_path = ['_extra']
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/teams/shade.html 301 /teams/openstacksdk.html
|
||||
/constraints/upper/master 301 http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
/constraints/upper/train 301 http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
/constraints/upper/stein 301 http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master
|
||||
/constraints/upper/rocky 301 http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky
|
||||
/constraints/upper/queens 301 http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/queens
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# 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.
|
||||
|
||||
from sphinx.util import logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def generate_constraints_redirections(_deliverables):
|
||||
redirections = []
|
||||
# Loop through all the releases for requirements
|
||||
for deliv in _deliverables.get_deliverable_history('requirements'):
|
||||
# Any open deliverables should point to master
|
||||
target = 'master'
|
||||
|
||||
# Unless there is a specific stable branch
|
||||
for branch in deliv.branches:
|
||||
if branch.name == 'stable/%s' % (deliv.series):
|
||||
target = branch.name
|
||||
break
|
||||
|
||||
# Or we have a ${series}-eol tag
|
||||
for release in deliv.releases:
|
||||
if release.is_eol:
|
||||
target = str(release.version)
|
||||
break
|
||||
|
||||
# Insert into the begining of the list so that redirections are
|
||||
# master -> juno
|
||||
redirections.insert(0, dict(code=301, src=deliv.series, dst=target))
|
||||
|
||||
return redirections
|
|
@ -0,0 +1,177 @@
|
|||
# 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.
|
||||
|
||||
import textwrap
|
||||
|
||||
from oslotest import base
|
||||
|
||||
from openstack_releases._redirections import generate_constraints_redirections
|
||||
from openstack_releases import deliverable
|
||||
from openstack_releases import yamlutils
|
||||
|
||||
|
||||
# Create a Fake Deliverables class we really only need an object with
|
||||
# get_deliverable_history that returns an iterable. Using the main real class
|
||||
# seems like overkill and would subject us to testing chnages as the actual
|
||||
# deliverables change over time.
|
||||
class FakeDeliverables(object):
|
||||
def __init__(self, deliverables=[]):
|
||||
self._deliverables = deliverables
|
||||
|
||||
def get_deliverable_history(self, name):
|
||||
return self._deliverables
|
||||
|
||||
|
||||
class TestRedirections(base.BaseTestCase):
|
||||
# Deliverable that looks like an open development series with no branches
|
||||
# or releases.
|
||||
OPEN_DEVELOPMENT = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='stein',
|
||||
name='requirements',
|
||||
data={}
|
||||
)
|
||||
# Deliverable that looks like an open development series with no branches
|
||||
# but has a single release
|
||||
DEVELOPMENT_RELEASE = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='stein',
|
||||
name='requirements',
|
||||
data=yamlutils.loads(textwrap.dedent('''
|
||||
releases:
|
||||
- projects:
|
||||
- hash: not_used
|
||||
repo: openstack/requirements
|
||||
version: 1.0.0
|
||||
'''))
|
||||
)
|
||||
# Deliverable that looks like an open stable series with no releases
|
||||
OPEN_STABLE = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='rocky',
|
||||
name='requirements',
|
||||
data=yamlutils.loads(textwrap.dedent('''
|
||||
branches:
|
||||
- name: stable/rocky
|
||||
location:
|
||||
openstack/requirements: not_used
|
||||
'''))
|
||||
)
|
||||
# Deliverable that looks like an open stable series with no releases but
|
||||
# also has an open 'feature' branch
|
||||
OPEN_UNSTABLE = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='rocky',
|
||||
name='requirements',
|
||||
data=yamlutils.loads(textwrap.dedent('''
|
||||
branches:
|
||||
- name: unstable/rocky
|
||||
location:
|
||||
openstack/requirements: not_used
|
||||
- name: stable/rocky
|
||||
location:
|
||||
openstack/requirements: not_used
|
||||
'''))
|
||||
)
|
||||
# Deliverable that looks like an open stable series with a release
|
||||
STABLE_RELEASE = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='rocky',
|
||||
name='requirements',
|
||||
data=yamlutils.loads(textwrap.dedent('''
|
||||
branches:
|
||||
- name: stable/rocky
|
||||
location:
|
||||
openstack/requirements: not_used
|
||||
releases:
|
||||
- projects:
|
||||
- hash: not_used
|
||||
repo: openstack/requirements
|
||||
version: 1.0.0
|
||||
'''))
|
||||
)
|
||||
# Deliverable that looks like a closed stable series
|
||||
STABLE_EOL = deliverable.Deliverable(
|
||||
team='requirements',
|
||||
series='mitaka',
|
||||
name='requirements',
|
||||
data=yamlutils.loads(textwrap.dedent('''
|
||||
releases:
|
||||
- projects:
|
||||
- hash: not_used
|
||||
repo: openstack/requirements
|
||||
version: mitaka-eol
|
||||
'''))
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def test_open_development(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.OPEN_DEVELOPMENT,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='stein', dst='master')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_development_release(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.DEVELOPMENT_RELEASE,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='stein', dst='master')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_open_stable(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.OPEN_STABLE,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='rocky', dst='stable/rocky')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_open_unstable(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.OPEN_UNSTABLE,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='rocky', dst='stable/rocky')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_stable_release(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.STABLE_RELEASE,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='rocky', dst='stable/rocky')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_stable_eol(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.STABLE_EOL,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='mitaka', dst='mitaka-eol')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_all(self):
|
||||
deliverables = FakeDeliverables([
|
||||
self.STABLE_EOL,
|
||||
self.STABLE_RELEASE,
|
||||
self.DEVELOPMENT_RELEASE,
|
||||
])
|
||||
self.assertEqual([dict(code=301, src='stein', dst='master'),
|
||||
dict(code=301, src='rocky', dst='stable/rocky'),
|
||||
dict(code=301, src='mitaka', dst='mitaka-eol')],
|
||||
generate_constraints_redirections(deliverables))
|
||||
|
||||
def test_empty(self):
|
||||
deliverables = FakeDeliverables([])
|
||||
self.assertEqual([],
|
||||
generate_constraints_redirections(deliverables))
|
2
tox.ini
2
tox.ini
|
@ -74,7 +74,7 @@ deps =
|
|||
-r{toxinidir}/doc/requirements.txt
|
||||
commands =
|
||||
sphinx-build -v -a -E -W -d doc/build/doctrees -b html doc/source doc/build/html
|
||||
whereto {toxinidir}/doc/source/_extra/.htaccess {toxinidir}/doc/test/redirect-tests.txt
|
||||
whereto {toxinidir}/doc/build/html/.htaccess {toxinidir}/doc/test/redirect-tests.txt
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
|
|
Loading…
Reference in New Issue