Feature flag to make `readthedocs` theme default on MkDocs docs
Historically, we were using `readthedocs` as default theme for MkDocs but in https://github.com/rtfd/readthedocs.org/pull/4556 we decided to change it to get the same behavior when building locally than in Read the Docs. This commit adds a Feature flag to keep having the old behavior for some particular projects so we can add these project and do not break their documentation (change the theme without asking/reason).hotfix/featureflag-mkdocs-theme
parent
b78d1f390c
commit
880a3508ba
|
@ -16,6 +16,7 @@ from django.template import loader as template_loader
|
|||
|
||||
from readthedocs.doc_builder.base import BaseBuilder
|
||||
from readthedocs.doc_builder.exceptions import BuildEnvironmentError
|
||||
from readthedocs.projects.models import Feature
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -50,6 +51,23 @@ class BaseMkdocs(BaseBuilder):
|
|||
self.root_path = self.version.project.checkout_path(self.version.slug)
|
||||
self.yaml_file = self.get_yaml_config()
|
||||
|
||||
# README: historically, the default theme was ``readthedocs`` but in
|
||||
# https://github.com/rtfd/readthedocs.org/pull/4556 we change it to
|
||||
# ``mkdocs`` to maintain the same behavior in Read the Docs than
|
||||
# building locally. Although, we can't apply the this into the Corporate
|
||||
# site. To keep the same default theme there, we created a Feature flag
|
||||
# for these project that were building with MkDocs in the Corporate
|
||||
# site.
|
||||
if self.project.has_feature(Feature.MKDOCS_THEME_RTD):
|
||||
self.DEFAULT_THEME_NAME = 'readthedocs'
|
||||
log.warning(
|
||||
'Project using readthedocs theme as default for MkDocs: slug=%s',
|
||||
self.project.slug,
|
||||
)
|
||||
else:
|
||||
self.DEFAULT_THEME_NAME = 'mkdocs'
|
||||
|
||||
|
||||
def get_yaml_config(self):
|
||||
"""Find the ``mkdocs.yml`` file in the project root."""
|
||||
mkdoc_path = self.config.mkdocs.configuration
|
||||
|
@ -130,6 +148,13 @@ class BaseMkdocs(BaseBuilder):
|
|||
# This supports using RTD's privacy improvements around analytics
|
||||
user_config['google_analytics'] = None
|
||||
|
||||
# README: make MkDocs to use ``readthedocs`` theme as default if the
|
||||
# user didn't specify a specific theme manually
|
||||
if self.project.has_feature(Feature.MKDOCS_THEME_RTD):
|
||||
if 'theme' not in user_config:
|
||||
# mkdocs<0.17 syntax
|
||||
user_config['theme'] = self.DEFAULT_THEME_NAME
|
||||
|
||||
# Write the modified mkdocs configuration
|
||||
yaml.safe_dump(
|
||||
user_config,
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.16 on 2018-10-24 07:43
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
FEATURE_ID = 'mkdocs_theme_rtd'
|
||||
|
||||
|
||||
def forward_add_feature(apps, schema_editor):
|
||||
Feature = apps.get_model('projects', 'Feature')
|
||||
Feature.objects.create(
|
||||
feature_id=FEATURE_ID,
|
||||
# Not using ``default_true=True`` because we will do this manually in
|
||||
# the database from the Corporate site only, since this is not required
|
||||
# in the Community site
|
||||
# default_true=True,
|
||||
)
|
||||
|
||||
|
||||
def reverse_add_feature(apps, schema_editor):
|
||||
Feature = apps.get_model('projects', 'Feature')
|
||||
Feature.objects.filter(feature_id=FEATURE_ID).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('projects', '0027_remove_json_with_html_feature'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(forward_add_feature, reverse_add_feature),
|
||||
]
|
|
@ -1060,6 +1060,7 @@ class Feature(models.Model):
|
|||
SKIP_SUBMODULES = 'skip_submodules'
|
||||
DONT_OVERWRITE_SPHINX_CONTEXT = 'dont_overwrite_sphinx_context'
|
||||
ALLOW_V2_CONFIG_FILE = 'allow_v2_config_file'
|
||||
MKDOCS_THEME_RTD = 'mkdocs_theme_rtd'
|
||||
|
||||
FEATURES = (
|
||||
(USE_SPHINX_LATEST, _('Use latest version of Sphinx')),
|
||||
|
@ -1071,6 +1072,7 @@ class Feature(models.Model):
|
|||
'Do not overwrite context vars in conf.py with Read the Docs context',)),
|
||||
(ALLOW_V2_CONFIG_FILE, _(
|
||||
'Allow to use the v2 of the configuration file')),
|
||||
(MKDOCS_THEME_RTD, _('Use Read the Docs theme for MkDocs as default theme')),
|
||||
)
|
||||
|
||||
projects = models.ManyToManyField(
|
||||
|
|
|
@ -20,7 +20,7 @@ from readthedocs.doc_builder.backends.mkdocs import MkdocsHTML
|
|||
from readthedocs.doc_builder.backends.sphinx import BaseSphinx
|
||||
from readthedocs.doc_builder.python_environments import Virtualenv
|
||||
from readthedocs.projects.exceptions import ProjectConfigurationError
|
||||
from readthedocs.projects.models import Project
|
||||
from readthedocs.projects.models import Feature, Project
|
||||
|
||||
|
||||
class SphinxBuilderTest(TestCase):
|
||||
|
@ -224,6 +224,67 @@ class MkdocsBuilderTest(TestCase):
|
|||
}
|
||||
self.assertEqual(builder.get_theme_name(config), 'mydir')
|
||||
|
||||
@patch('readthedocs.doc_builder.base.BaseBuilder.run')
|
||||
@patch('readthedocs.projects.models.Project.checkout_path')
|
||||
def test_get_theme_name_with_feature_flag(self, checkout_path, run):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
checkout_path.return_value = tmpdir
|
||||
Feature.objects.get(
|
||||
feature_id=Feature.MKDOCS_THEME_RTD,
|
||||
).projects.add(self.project)
|
||||
|
||||
python_env = Virtualenv(
|
||||
version=self.version,
|
||||
build_env=self.build_env,
|
||||
config=None,
|
||||
)
|
||||
builder = MkdocsHTML(
|
||||
build_env=self.build_env,
|
||||
python_env=python_env,
|
||||
)
|
||||
self.assertEqual(builder.get_theme_name({}), 'readthedocs')
|
||||
with patch('readthedocs.doc_builder.backends.mkdocs.yaml') as mock_yaml:
|
||||
with patch('readthedocs.doc_builder.backends.mkdocs.MkdocsHTML.load_yaml_config') as mock_load_yaml_config:
|
||||
mock_load_yaml_config.return_value = {'site_name': self.project.name}
|
||||
builder.append_conf()
|
||||
|
||||
mock_yaml.safe_dump.assert_called_once_with(
|
||||
{
|
||||
'site_name': mock.ANY,
|
||||
'docs_dir': mock.ANY,
|
||||
'extra_javascript': mock.ANY,
|
||||
'extra_css': mock.ANY,
|
||||
'google_analytics': mock.ANY,
|
||||
'theme': 'readthedocs',
|
||||
},
|
||||
mock.ANY,
|
||||
)
|
||||
mock_yaml.reset_mock()
|
||||
|
||||
config = {
|
||||
'theme': 'customtheme',
|
||||
}
|
||||
self.assertEqual(builder.get_theme_name(config), 'customtheme')
|
||||
with patch('readthedocs.doc_builder.backends.mkdocs.MkdocsHTML.load_yaml_config') as mock_load_yaml_config:
|
||||
mock_load_yaml_config.return_value = {
|
||||
'site_name': self.project.name,
|
||||
'theme': 'customtheme',
|
||||
}
|
||||
builder.append_conf()
|
||||
|
||||
mock_yaml.safe_dump.assert_called_once_with(
|
||||
{
|
||||
'site_name': mock.ANY,
|
||||
'docs_dir': mock.ANY,
|
||||
'extra_javascript': mock.ANY,
|
||||
'extra_css': mock.ANY,
|
||||
'google_analytics': mock.ANY,
|
||||
'theme': 'customtheme',
|
||||
},
|
||||
mock.ANY,
|
||||
)
|
||||
|
||||
|
||||
@patch('readthedocs.doc_builder.base.BaseBuilder.run')
|
||||
@patch('readthedocs.projects.models.Project.checkout_path')
|
||||
def test_append_conf_create_yaml(self, checkout_path, run):
|
||||
|
|
Loading…
Reference in New Issue