Skip to content

Commit 97b3b25

Browse files
saadmk11humitos
andauthored
Stop creating a conf.py automatically and doing magic around README handling (#5609)
* Stop creating a conf.py file automatically for users and doing magic around README handling * remove readme text * Auto generating mkdocs.yaml removed * create_index added * fixed error msg * tests updated * Updated Error msg * Lint * Test: remove old test * Lint * Delete `conf.py` template * Build: fail the build if `docs/conf.py` doesn't exist * Build: raise exception if no config file --------- Co-authored-by: Manuel Kaufmann <[email protected]>
1 parent 040a8cb commit 97b3b25

File tree

6 files changed

+141
-365
lines changed

6 files changed

+141
-365
lines changed

readthedocs/doc_builder/backends/mkdocs.py

+40-54
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __init__(self, *args, **kwargs):
5959
if self.project.has_feature(Feature.MKDOCS_THEME_RTD):
6060
self.DEFAULT_THEME_NAME = 'readthedocs'
6161
log.warning(
62-
'Project using readthedocs theme as default for MkDocs.',
62+
"Project using readthedocs theme as default for MkDocs.",
6363
project_slug=self.project.slug,
6464
)
6565
else:
@@ -76,14 +76,14 @@ def get_final_doctype(self):
7676
self.yaml_file, "r", allow_symlinks=True, base_path=self.project_path
7777
) as fh:
7878
config = yaml_load_safely(fh)
79-
use_directory_urls = config.get('use_directory_urls', True)
79+
use_directory_urls = config.get("use_directory_urls", True)
8080
return MKDOCS if use_directory_urls else MKDOCS_HTML
8181

8282
def get_yaml_config(self):
8383
"""Find the ``mkdocs.yml`` file in the project root."""
8484
mkdocs_path = self.config.mkdocs.configuration
8585
if not mkdocs_path:
86-
mkdocs_path = 'mkdocs.yml'
86+
mkdocs_path = "mkdocs.yml"
8787
return os.path.join(
8888
self.project_path,
8989
mkdocs_path,
@@ -108,25 +108,13 @@ def load_yaml_config(self):
108108
config = yaml_load_safely(result)
109109

110110
if not config:
111-
raise MkDocsYAMLParseError(
112-
MkDocsYAMLParseError.EMPTY_CONFIG
113-
)
111+
raise MkDocsYAMLParseError(MkDocsYAMLParseError.EMPTY_CONFIG)
114112
if not isinstance(config, dict):
115-
raise MkDocsYAMLParseError(
116-
MkDocsYAMLParseError.CONFIG_NOT_DICT
117-
)
113+
raise MkDocsYAMLParseError(MkDocsYAMLParseError.CONFIG_NOT_DICT)
118114
return config
119115

120116
except IOError:
121-
log.info(
122-
'Creating default MkDocs config file for project.',
123-
project_slug=self.project.slug,
124-
version_slug=self.version.slug,
125-
)
126-
return {
127-
'site_name': self.version.project.name,
128-
'docs_dir': self.docs_dir(),
129-
}
117+
raise MkDocsYAMLParseError(MkDocsYAMLParseError.NOT_FOUND)
130118
except yaml.YAMLError as exc:
131119
note = ''
132120
if hasattr(exc, 'problem_mark'):
@@ -150,7 +138,7 @@ def append_conf(self):
150138
user_config = self.load_yaml_config()
151139

152140
# Handle custom docs dirs
153-
docs_dir = user_config.get('docs_dir', 'docs')
141+
docs_dir = user_config.get("docs_dir", "docs")
154142
if not isinstance(docs_dir, (type(None), str)):
155143
raise MkDocsYAMLParseError(
156144
MkDocsYAMLParseError.INVALID_DOCS_DIR_CONFIG,
@@ -167,14 +155,14 @@ def append_conf(self):
167155

168156
# Set mkdocs config values.
169157
extra_assets = {
170-
'extra_javascript': [
171-
'readthedocs-data.js',
172-
f'{static_url}core/js/readthedocs-doc-embed.js',
173-
f'{static_url}javascript/readthedocs-analytics.js',
158+
"extra_javascript": [
159+
"readthedocs-data.js",
160+
f"{static_url}core/js/readthedocs-doc-embed.js",
161+
f"{static_url}javascript/readthedocs-analytics.js",
174162
],
175-
'extra_css': [
176-
f'{static_url}css/badge_only.css',
177-
f'{static_url}css/readthedocs-doc-embed.css',
163+
"extra_css": [
164+
f"{static_url}css/badge_only.css",
165+
f"{static_url}css/readthedocs-doc-embed.css",
178166
],
179167
}
180168

@@ -189,11 +177,7 @@ def append_conf(self):
189177
),
190178
)
191179
# Add the static file only if isn't already in the list.
192-
value.extend([
193-
extra
194-
for extra in extras
195-
if extra not in value
196-
])
180+
value.extend([extra for extra in extras if extra not in value])
197181
user_config[config] = value
198182

199183
# The docs path is relative to the location
@@ -257,38 +241,39 @@ def generate_rtd_data(self, docs_dir, mkdocs_config):
257241
self.version.project.vcs_repo(
258242
version=self.version.slug,
259243
environment=self.build_env,
260-
)
261-
.commit,
244+
).commit,
262245
)
263246

264247
# Will be available in the JavaScript as READTHEDOCS_DATA.
265248
readthedocs_data = {
266-
'project': self.version.project.slug,
267-
'version': self.version.slug,
268-
'language': self.version.project.language,
269-
'programming_language': self.version.project.programming_language,
270-
'page': None,
271-
'theme': self.get_theme_name(mkdocs_config),
272-
'builder': 'mkdocs',
273-
'docroot': docs_dir,
274-
'source_suffix': '.md',
275-
'api_host': settings.PUBLIC_API_URL,
276-
'ad_free': not self.project.show_advertising,
277-
'commit': commit,
278-
'global_analytics_code': (
279-
None if self.project.analytics_disabled else settings.GLOBAL_ANALYTICS_CODE
249+
"project": self.version.project.slug,
250+
"version": self.version.slug,
251+
"language": self.version.project.language,
252+
"programming_language": self.version.project.programming_language,
253+
"page": None,
254+
"theme": self.get_theme_name(mkdocs_config),
255+
"builder": "mkdocs",
256+
"docroot": docs_dir,
257+
"source_suffix": ".md",
258+
"api_host": settings.PUBLIC_API_URL,
259+
"ad_free": not self.project.show_advertising,
260+
"commit": commit,
261+
"global_analytics_code": (
262+
None
263+
if self.project.analytics_disabled
264+
else settings.GLOBAL_ANALYTICS_CODE
280265
),
281266
"user_analytics_code": analytics_code,
282267
"proxied_static_path": self.project.proxied_static_path,
283268
"proxied_api_host": self.project.proxied_api_host,
284269
}
285270

286271
data_ctx = {
287-
'readthedocs_data': readthedocs_data,
288-
'current_version': readthedocs_data['version'],
289-
'slug': readthedocs_data['project'],
290-
'html_theme': readthedocs_data['theme'],
291-
'pagename': None,
272+
"readthedocs_data": readthedocs_data,
273+
"current_version": readthedocs_data["version"],
274+
"slug": readthedocs_data["project"],
275+
"html_theme": readthedocs_data["theme"],
276+
"pagename": None,
292277
}
293278
tmpl = template_loader.get_template('doc_builder/data.js.tmpl')
294279
return tmpl.render(data_ctx)
@@ -342,7 +327,6 @@ def get_theme_name(self, mkdocs_config):
342327

343328

344329
class MkdocsHTML(BaseMkdocs):
345-
346330
builder = "build"
347331
build_dir = "_readthedocs/html"
348332

@@ -391,7 +375,9 @@ def represent_name(self, data):
391375
return self.represent_scalar("tag:yaml.org,2002:python/name:" + data.value, "")
392376

393377

394-
SafeLoader.add_multi_constructor("tag:yaml.org,2002:python/name:", SafeLoader.construct_python_name)
378+
SafeLoader.add_multi_constructor(
379+
"tag:yaml.org,2002:python/name:", SafeLoader.construct_python_name
380+
)
395381
SafeLoader.add_constructor(None, SafeLoader.ignore_unknown)
396382
SafeDumper.add_representer(ProxyPythonName, SafeDumper.represent_name)
397383

readthedocs/doc_builder/backends/sphinx.py

+37-68
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import structlog
1313
from django.conf import settings
1414
from django.template import loader as template_loader
15-
from django.template.loader import render_to_string
1615
from django.urls import reverse
1716
from requests.exceptions import ConnectionError
1817

@@ -24,7 +23,6 @@
2423
from readthedocs.projects.exceptions import ProjectConfigurationError, UserFileNotFound
2524
from readthedocs.projects.models import Feature
2625
from readthedocs.projects.templatetags.projects_tags import sort_version_aware
27-
from readthedocs.projects.utils import safe_write
2826

2927
from ..base import BaseBuilder
3028
from ..constants import PDF_RE
@@ -113,24 +111,6 @@ def __init__(self, *args, **kwargs):
113111
# because Read the Docs will automatically create one for it.
114112
pass
115113

116-
def _write_config(self, master_doc='index'):
117-
"""Create ``conf.py`` if it doesn't exist."""
118-
log.info(
119-
'Creating default Sphinx config file for project.',
120-
project_slug=self.project.slug,
121-
version_slug=self.version.slug,
122-
)
123-
docs_dir = self.docs_dir()
124-
conf_template = render_to_string(
125-
'sphinx/conf.py.conf',
126-
{
127-
'project': self.project,
128-
'version': self.version,
129-
'master_doc': master_doc,
130-
},
131-
)
132-
conf_file = os.path.join(docs_dir, 'conf.py')
133-
safe_write(conf_file, conf_template)
134114

135115
def get_config_params(self):
136116
"""Get configuration parameters to be rendered into the conf file."""
@@ -191,30 +171,27 @@ def get_config_params(self):
191171
version_slug=self.version.slug,
192172
)
193173

194-
build_id = self.build_env.build.get('id')
174+
build_id = self.build_env.build.get("id")
195175
build_url = None
196176
if build_id:
197177
build_url = reverse(
198-
'builds_detail',
178+
"builds_detail",
199179
kwargs={
200-
'project_slug': self.project.slug,
201-
'build_pk': build_id,
180+
"project_slug": self.project.slug,
181+
"build_pk": build_id,
202182
},
203183
)
204-
protocol = 'http' if settings.DEBUG else 'https'
205-
build_url = f'{protocol}://{settings.PRODUCTION_DOMAIN}{build_url}'
184+
protocol = "http" if settings.DEBUG else "https"
185+
build_url = f"{protocol}://{settings.PRODUCTION_DOMAIN}{build_url}"
206186

207187
vcs_url = None
208188
if self.version.is_external:
209189
vcs_url = self.version.vcs_url
210190

211-
commit = (
212-
self.project.vcs_repo(
213-
version=self.version.slug,
214-
environment=self.build_env,
215-
)
216-
.commit
217-
)
191+
commit = self.project.vcs_repo(
192+
version=self.version.slug,
193+
environment=self.build_env,
194+
).commit
218195

219196
data = {
220197
"current_version": self.version.verbose_name,
@@ -267,34 +244,26 @@ def get_config_params(self):
267244

268245
def append_conf(self):
269246
"""
270-
Find or create a ``conf.py`` and appends default content.
247+
Find a ``conf.py`` and appends default content.
271248
272249
The default content is rendered from ``doc_builder/conf.py.tmpl``.
273250
"""
251+
if self.config_file is None:
252+
raise ProjectConfigurationError(ProjectConfigurationError.NOT_FOUND)
274253

275-
# Generate a `conf.py` from a template
276-
#
277-
# TODO: we should remove this feature at some point to move forward
278-
# with the idea of remove magic from the builders.
279-
if not self.config_file:
280-
self._write_config()
254+
self.config_file = self.config_file or self.project.conf_file(self.version.slug)
281255

282-
try:
283-
self.config_file = (
284-
self.config_file or self.project.conf_file(self.version.slug)
256+
if not os.path.exists(self.config_file):
257+
raise UserFileNotFound(
258+
UserFileNotFound.FILE_NOT_FOUND.format(self.config_file)
285259
)
286-
# Allow symlinks, but only the ones that resolve inside the base directory.
287-
outfile = safe_open(
288-
self.config_file, "a", allow_symlinks=True, base_path=self.project_path
289-
)
290-
if not outfile:
291-
raise UserFileNotFound(
292-
UserFileNotFound.FILE_NOT_FOUND.format(self.config_file)
293-
)
294-
except IOError as exc:
295-
raise ProjectConfigurationError(
296-
ProjectConfigurationError.NOT_FOUND
297-
) from exc
260+
261+
# Allow symlinks, but only the ones that resolve inside the base directory.
262+
# NOTE: if something goes wrong,
263+
# `safe_open` raises an exception that's clearly communicated to the user.
264+
outfile = safe_open(
265+
self.config_file, "a", allow_symlinks=True, base_path=self.project_path
266+
)
298267

299268
# Append config to project conf file
300269
tmpl = template_loader.get_template('doc_builder/conf.py.tmpl')
@@ -319,8 +288,8 @@ def build(self):
319288
project = self.project
320289
build_command = [
321290
*self.get_sphinx_cmd(),
322-
'-T',
323-
'-E',
291+
"-T",
292+
"-E",
324293
]
325294
if self.config.sphinx.fail_on_warning:
326295
build_command.extend(["-W", "--keep-going"])
@@ -354,9 +323,9 @@ def build(self):
354323

355324
def get_sphinx_cmd(self):
356325
return (
357-
self.python_env.venv_bin(filename='python'),
358-
'-m',
359-
'sphinx',
326+
self.python_env.venv_bin(filename="python"),
327+
"-m",
328+
"sphinx",
360329
)
361330

362331

@@ -576,19 +545,19 @@ def _build_latexmk(self, cwd):
576545
latex_class = LatexBuildCommand
577546

578547
cmd = [
579-
'latexmk',
580-
'-r',
548+
"latexmk",
549+
"-r",
581550
rcfile,
582551
# FIXME: check for platex here as well
583-
'-pdfdvi' if self.project.language == 'ja' else '-pdf',
552+
"-pdfdvi" if self.project.language == "ja" else "-pdf",
584553
# When ``-f`` is used, latexmk will continue building if it
585554
# encounters errors. We still receive a failure exit code in this
586555
# case, but the correct steps should run.
587-
'-f',
588-
'-dvi-',
589-
'-ps-',
590-
f'-jobname={self.project.slug}',
591-
'-interaction=nonstopmode',
556+
"-f",
557+
"-dvi-",
558+
"-ps-",
559+
f"-jobname={self.project.slug}",
560+
"-interaction=nonstopmode",
592561
]
593562

594563
cmd_ret = self.build_env.run_command_class(

readthedocs/doc_builder/base.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import structlog
77

8-
98
log = structlog.get_logger(__name__)
109

1110

@@ -53,7 +52,7 @@ def _post_build(self):
5352

5453
def docs_dir(self):
5554
"""Handle creating a custom docs_dir if it doesn't exist."""
56-
for doc_dir_name in ['docs', 'doc', 'Doc', 'book']:
55+
for doc_dir_name in ["docs", "doc", "Doc", "book"]:
5756
possible_path = os.path.join(self.project_path, doc_dir_name)
5857
if os.path.exists(possible_path):
5958
return possible_path

0 commit comments

Comments
 (0)