diff --git a/readthedocs/doc_builder/backends/mkdocs.py b/readthedocs/doc_builder/backends/mkdocs.py index 36f2e1e5d6f..0a750705ace 100644 --- a/readthedocs/doc_builder/backends/mkdocs.py +++ b/readthedocs/doc_builder/backends/mkdocs.py @@ -14,6 +14,8 @@ from readthedocs.doc_builder.base import BaseBuilder from readthedocs.projects.constants import MKDOCS from readthedocs.projects.constants import MKDOCS_HTML +from readthedocs.projects.exceptions import ProjectConfigurationError +from readthedocs.projects.exceptions import UserFileNotFound log = structlog.get_logger(__name__) @@ -44,7 +46,12 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # This is the *MkDocs* yaml file - self.yaml_file = self.get_yaml_config() + self.config_file = None + if self.config.mkdocs.configuration: + self.config_file = os.path.join( + self.project_path, + self.config.mkdocs.configuration, + ) def get_final_doctype(self): """ @@ -59,7 +66,7 @@ def get_final_doctype(self): # Allow symlinks, but only the ones that resolve inside the base directory. with safe_open( - self.yaml_file, + self.config_file, "r", allow_symlinks=True, base_path=self.project_path, @@ -68,22 +75,23 @@ def get_final_doctype(self): use_directory_urls = config.get("use_directory_urls", True) return MKDOCS if use_directory_urls else MKDOCS_HTML - def get_yaml_config(self): - """Find the ``mkdocs.yml`` file in the project root.""" - mkdocs_path = self.config.mkdocs.configuration - if not mkdocs_path: - mkdocs_path = "mkdocs.yml" - return os.path.join( - self.project_path, - mkdocs_path, - ) - def show_conf(self): """Show the current ``mkdocs.yaml`` being used.""" + if self.config_file is None: + raise ProjectConfigurationError(ProjectConfigurationError.MKDOCS_YAML_NOT_FOUND) + + if not os.path.exists(self.config_file): + raise UserFileNotFound( + message_id=UserFileNotFound.FILE_NOT_FOUND, + format_values={ + "filename": os.path.relpath(self.config_file, self.project_path), + }, + ) + # Write the mkdocs.yml to the build logs self.run( "cat", - os.path.relpath(self.yaml_file, self.project_path), + os.path.relpath(self.config_file, self.project_path), cwd=self.project_path, ) @@ -97,8 +105,9 @@ def build(self): "--site-dir", os.path.join("$READTHEDOCS_OUTPUT", "html"), "--config-file", - os.path.relpath(self.yaml_file, self.project_path), + os.path.relpath(self.config_file, self.project_path), ] + if self.config.mkdocs.fail_on_warning: build_command.append("--strict") cmd_ret = self.run( diff --git a/readthedocs/projects/exceptions.py b/readthedocs/projects/exceptions.py index 466d09a174d..5b9d9ce7e52 100644 --- a/readthedocs/projects/exceptions.py +++ b/readthedocs/projects/exceptions.py @@ -9,6 +9,7 @@ class ProjectConfigurationError(BuildUserError): NOT_FOUND = "project:sphinx:conf-py-not-found" MULTIPLE_CONF_FILES = "project:sphinx:multiple-conf-py-files-found" + MKDOCS_YAML_NOT_FOUND = "project:mkdocs:yaml-not-found" class UserFileNotFound(BuildUserError): diff --git a/readthedocs/projects/notifications.py b/readthedocs/projects/notifications.py index 9b9e5d43e7a..53648da7171 100644 --- a/readthedocs/projects/notifications.py +++ b/readthedocs/projects/notifications.py @@ -101,7 +101,7 @@ ), Message( id=RepositoryError.UNSUPPORTED_VCS, - header=_("Repository type not suported"), + header=_("Repository type not supported"), body=_( textwrap.dedent( """ @@ -125,6 +125,19 @@ ), type=ERROR, ), + Message( + id=ProjectConfigurationError.MKDOCS_YAML_NOT_FOUND, + header=_("MkDocs configuration file is missing"), + body=_( + textwrap.dedent( + """ + A configuration file was not found. + Make sure you have a mkdocs.yml file in your repository. + """ + ).strip(), + ), + type=ERROR, + ), Message( id=ProjectConfigurationError.MULTIPLE_CONF_FILES, header=_("Multiple Sphinx configuration files found"),