Skip to content

Commit d863711

Browse files
Feature flag: remove DONT_CREATE_INDEX (#10471)
* Feature flag: remove `DONT_CREATE_INDEX` Remove the usage of `DONT_CREATE_INDEX` feature flag that only 1 project is currently using. Besides, this commit removes the auto-creation of the `index.html` file when building with MkDocs or Sphinx. We will be checking at "Uploading" status if there is no `index.html` file and we will fail the build in that case. * Build: fail the build if HTML output does not contain an `index.html` Fail the build when there is no `index.html` at its root directory. * Tests: remove mock for `create_index` * Update readthedocs/doc_builder/exceptions.py Co-authored-by: Eric Holscher <[email protected]> * Do not fail the build for now Only collect data of projects without index.html or README.html at the root. Once we have that data will be contacting those projects to let them know this is deprecated and will make the builds to fail. * Keep the generation of `conf.py` in its place We cannot remove this yet. --------- Co-authored-by: Eric Holscher <[email protected]>
1 parent 8a7586b commit d863711

File tree

8 files changed

+58
-77
lines changed

8 files changed

+58
-77
lines changed

docs/user/feature-flags.rst

-8
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,3 @@ Available flags
1616

1717
Makes Read the Docs to install all the requirements at once on ``conda create`` step.
1818
This helps users to pin dependencies on conda and to improve build time.
19-
20-
``DONT_CREATE_INDEX``: Do not create index.md or README.rst if the project does not have one.
21-
22-
When Read the Docs detects that your project doesn't have an ``index.md`` or ``README.rst``,
23-
it auto-generate one for you with instructions about how to proceed.
24-
25-
In case you are using a static HTML page as index or an generated index from code,
26-
this behavior could be a problem. With this feature flag you can disable that.

readthedocs/doc_builder/backends/mkdocs.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def load_yaml_config(self):
138138
raise MkDocsYAMLParseError(
139139
'Your mkdocs.yml could not be loaded, '
140140
'possibly due to a syntax error{note}'.format(note=note),
141-
)
141+
) from exc
142142

143143
def append_conf(self):
144144
"""
@@ -156,7 +156,6 @@ def append_conf(self):
156156
MkDocsYAMLParseError.INVALID_DOCS_DIR_CONFIG,
157157
)
158158

159-
self.create_index(extension='md')
160159
user_config['docs_dir'] = docs_dir
161160

162161
# MkDocs <=0.17.x doesn't support absolute paths,
@@ -215,7 +214,9 @@ def append_conf(self):
215214
docs_dir=os.path.relpath(docs_path, self.project_path),
216215
mkdocs_config=user_config,
217216
)
218-
with open(os.path.join(docs_path, 'readthedocs-data.js'), 'w') as f:
217+
with open(
218+
os.path.join(docs_path, "readthedocs-data.js"), "w", encoding="utf-8"
219+
) as f:
219220
f.write(rtd_data)
220221

221222
# Use Read the Docs' analytics setup rather than mkdocs'
@@ -230,10 +231,11 @@ def append_conf(self):
230231
user_config['theme'] = self.DEFAULT_THEME_NAME
231232

232233
# Write the modified mkdocs configuration
233-
yaml_dump_safely(
234-
user_config,
235-
open(self.yaml_file, 'w'),
236-
)
234+
with open(self.yaml_file, "w", encoding="utf-8") as f:
235+
yaml_dump_safely(
236+
user_config,
237+
f,
238+
)
237239

238240
# Write the mkdocs.yml to the build logs
239241
self.run(
@@ -369,10 +371,10 @@ class SafeLoader(yaml.SafeLoader): # pylint: disable=too-many-ancestors
369371
Issue https://github.com/readthedocs/readthedocs.org/issues/7461
370372
"""
371373

372-
def ignore_unknown(self, node): # pylint: disable=no-self-use, unused-argument
374+
def ignore_unknown(self, node): # pylint: disable=unused-argument
373375
return None
374376

375-
def construct_python_name(self, suffix, node): # pylint: disable=no-self-use, unused-argument
377+
def construct_python_name(self, suffix, node): # pylint: disable=unused-argument
376378
return ProxyPythonName(suffix)
377379

378380

readthedocs/doc_builder/backends/sphinx.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,13 @@ def append_conf(self):
276276
277277
The default content is rendered from ``doc_builder/conf.py.tmpl``.
278278
"""
279-
if self.config_file is None:
280-
master_doc = self.create_index(extension='rst')
281-
self._write_config(master_doc=master_doc)
279+
280+
# Generate a `conf.py` from a template
281+
#
282+
# TODO: we should remove this feature at some point to move forward
283+
# with the idea of remove magic from the builders.
284+
if not self.config_file:
285+
self._write_config()
282286

283287
try:
284288
self.config_file = (

readthedocs/doc_builder/base.py

+1-41
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
import structlog
77

8-
from readthedocs.core.utils.filesystem import safe_open
9-
from readthedocs.projects.models import Feature
108

119
log = structlog.get_logger(__name__)
1210

@@ -15,8 +13,8 @@ def restoring_chdir(fn):
1513
# XXX:dc: This would be better off in a neutral module
1614
@wraps(fn)
1715
def decorator(*args, **kw):
16+
path = os.getcwd()
1817
try:
19-
path = os.getcwd()
2018
return fn(*args, **kw)
2119
finally:
2220
os.chdir(path)
@@ -62,44 +60,6 @@ def docs_dir(self):
6260

6361
return self.project_path
6462

65-
def create_index(self, extension='md', **__):
66-
"""Create an index file if it needs it."""
67-
docs_dir = self.docs_dir()
68-
69-
index_filename = os.path.join(
70-
docs_dir,
71-
'index.{ext}'.format(ext=extension),
72-
)
73-
if not os.path.exists(index_filename):
74-
readme_filename = os.path.join(
75-
docs_dir,
76-
'README.{ext}'.format(ext=extension),
77-
)
78-
if os.path.exists(readme_filename):
79-
return 'README'
80-
81-
if not self.project.has_feature(Feature.DONT_CREATE_INDEX):
82-
index_text = """
83-
84-
Welcome to Read the Docs
85-
------------------------
86-
87-
This is an autogenerated index file.
88-
89-
Please create an ``index.{ext}`` or ``README.{ext}`` file with your own content
90-
under the root (or ``/docs``) directory in your repository.
91-
92-
If you want to use another markup, choose a different builder in your settings.
93-
Check out our `Getting Started Guide
94-
<https://docs.readthedocs.io/en/latest/getting_started.html>`_ to become more
95-
familiar with Read the Docs.
96-
"""
97-
98-
with safe_open(index_filename, "w+") as index_file:
99-
index_file.write(index_text.format(dir=docs_dir, ext=extension))
100-
101-
return 'index'
102-
10363
def run(self, *args, **kwargs):
10464
"""Proxy run to build environment."""
10565
return self.build_env.run(*args, **kwargs)

readthedocs/doc_builder/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class BuildUserError(BuildBaseException):
5252
"and it is not currently supported. "
5353
'Please, remove all the files but the "{artifact_type}" you want to upload.'
5454
)
55+
BUILD_OUTPUT_HTML_NO_INDEX_FILE = gettext_noop(
56+
"Your documentation did not generate an 'index.html' at its root directory. "
57+
"This is required for documentation serving at the root URL for this version."
58+
)
5559
BUILD_OUTPUT_OLD_DIRECTORY_USED = gettext_noop(
5660
"Some files were detected in an unsupported output path, '_build/html'. "
5761
"Ensure your project is configured to use the output path "

readthedocs/projects/models.py

-8
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,6 @@ def add_features(sender, **kwargs):
19371937
INDEX_FROM_HTML_FILES = 'index_from_html_files'
19381938

19391939
# Build related features
1940-
DONT_CREATE_INDEX = "dont_create_index"
19411940
HOSTING_INTEGRATIONS = "hosting_integrations"
19421941
NO_CONFIG_FILE_DEPRECATED = "no_config_file"
19431942

@@ -2061,13 +2060,6 @@ def add_features(sender, **kwargs):
20612060
"sources"
20622061
),
20632062
),
2064-
2065-
(
2066-
DONT_CREATE_INDEX,
2067-
_(
2068-
"Sphinx: Do not create index.md or README.rst if the project does not have one."
2069-
),
2070-
),
20712063
(
20722064
HOSTING_INTEGRATIONS,
20732065
_(

readthedocs/projects/tasks/builds.py

+23
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ def get_valid_artifact_types(self):
543543
- it exists
544544
- it is a directory
545545
- does not contains more than 1 files (only PDF, HTMLZip, ePUB)
546+
- it contains an "index.html" file at its root directory (only HTML)
546547
547548
TODO: remove the limitation of only 1 file.
548549
Add support for multiple PDF files in the output directory and
@@ -554,6 +555,28 @@ def get_valid_artifact_types(self):
554555
version=self.data.version.slug,
555556
type_=artifact_type,
556557
)
558+
559+
if artifact_type == "html":
560+
index_html_filepath = os.path.join(artifact_directory, "index.html")
561+
readme_html_filepath = os.path.join(artifact_directory, "README.html")
562+
if not os.path.exists(index_html_filepath) and not os.path.exists(
563+
readme_html_filepath
564+
):
565+
log.warning(
566+
"Failing the build. "
567+
"HTML output does not contain an 'index.html' at its root directory.",
568+
index_html=index_html_filepath,
569+
readme_html=readme_html_filepath,
570+
)
571+
# TODO: uncomment this line to fail the build once we have
572+
# communicated with projects without an index.html or
573+
# README.html
574+
#
575+
# NOTE: we want to deprecate serving README.html as an
576+
# index.html file as well.
577+
#
578+
# raise BuildUserError(BuildUserError.BUILD_OUTPUT_HTML_NO_INDEX_FILE)
579+
557580
if not os.path.exists(artifact_directory):
558581
# There is no output directory.
559582
# Skip this format.

readthedocs/rtd_tests/tests/test_doc_builder.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,17 @@ def test_html_context_only_has_public_versions(
166166
self.assertEqual(versions, {'v1', 'v2'})
167167

168168
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.docs_dir')
169-
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.create_index')
170169
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.get_config_params')
171170
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.run')
172171
@patch('readthedocs.builds.models.Version.get_conf_py_path')
173172
@patch('readthedocs.projects.models.Project.checkout_path')
174173
def test_create_conf_py(
175-
self, checkout_path, get_conf_py_path, _,
176-
get_config_params, create_index, docs_dir,
174+
self,
175+
checkout_path,
176+
get_conf_py_path,
177+
_,
178+
get_config_params,
179+
docs_dir,
177180
):
178181
"""
179182
Test for a project without ``conf.py`` file.
@@ -189,7 +192,6 @@ def test_create_conf_py(
189192
tmp_dir = tempfile.mkdtemp()
190193
checkout_path.return_value = tmp_dir
191194
docs_dir.return_value = tmp_dir
192-
create_index.return_value = 'README.rst'
193195
get_config_params.return_value = {}
194196
get_conf_py_path.side_effect = ProjectConfigurationError
195197
python_env = Virtualenv(
@@ -224,14 +226,17 @@ def test_create_conf_py(
224226
)
225227

226228
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.docs_dir')
227-
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.create_index')
228229
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.get_config_params')
229230
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.run')
230231
@patch('readthedocs.builds.models.Version.get_conf_py_path')
231232
@patch('readthedocs.projects.models.Project.checkout_path')
232233
def test_multiple_conf_py(
233-
self, checkout_path, get_conf_py_path, _, get_config_params,
234-
create_index, docs_dir,
234+
self,
235+
checkout_path,
236+
get_conf_py_path,
237+
_,
238+
get_config_params,
239+
docs_dir,
235240
):
236241
"""
237242
Test for a project with multiple ``conf.py`` files.
@@ -245,7 +250,6 @@ def test_multiple_conf_py(
245250
tmp_docs_dir.join('test').mkdir().join('conf.py').write('')
246251
docs_dir.return_value = str(tmp_docs_dir)
247252
checkout_path.return_value = str(tmp_docs_dir)
248-
create_index.return_value = 'README.rst'
249253
get_config_params.return_value = {}
250254
get_conf_py_path.side_effect = ProjectConfigurationError
251255
python_env = Virtualenv(

0 commit comments

Comments
 (0)