From 3371482c76a4f9956713ddd1047d44ba0b6b7996 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 25 Jan 2023 12:23:02 +0100 Subject: [PATCH] Build: check if the output directory is a directory It checks for `_readthedocs/` output directory to be a directory. If it's not a directory, it silently skip that format for now. This behavior will change once we move out `store_build_artifacts` from `on_success` and we can communicate errors easily to the user. Related https://github.com/readthedocs/readthedocs.org/issues/9931 --- readthedocs/doc_builder/exceptions.py | 3 +++ readthedocs/projects/tasks/builds.py | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/readthedocs/doc_builder/exceptions.py b/readthedocs/doc_builder/exceptions.py index d3730baa617..50f502cc3cd 100644 --- a/readthedocs/doc_builder/exceptions.py +++ b/readthedocs/doc_builder/exceptions.py @@ -40,6 +40,9 @@ class BuildUserError(BuildBaseException): BUILD_COMMANDS_WITHOUT_OUTPUT = gettext_noop( f'No "{BUILD_COMMANDS_OUTPUT_PATH_HTML}" folder was created during this build.' ) + BUILD_OUTPUT_IS_NOT_A_DIRECTORY = gettext_noop( + 'Build output directory for format "{format}" is not a directory.', + ) class BuildUserSkip(BuildUserError): diff --git a/readthedocs/projects/tasks/builds.py b/readthedocs/projects/tasks/builds.py index ed4707f16ae..6e3b7210a17 100644 --- a/readthedocs/projects/tasks/builds.py +++ b/readthedocs/projects/tasks/builds.py @@ -796,12 +796,22 @@ def store_build_artifacts(self): types_to_delete = [] for artifact_type in ARTIFACT_TYPES: - if os.path.exists( - self.data.project.artifact_path( - version=self.data.version.slug, - type_=artifact_type, + artifact_directory = self.data.project.artifact_path( + version=self.data.version.slug, + type_=artifact_type, + ) + if os.path.isdir(artifact_directory): + log.exception( + "Multiple files are not supported for this format. " + "Skipping this output format.", + output_format=media_type, ) - ): + # TODO: we should raise an exception here, fail the build, + # and communicate the error to the user. + # + # raise BuildUserError(BuildUserError.BUILD_OUTPUT_IS_NOT_A_DIRECTORY.format(artifact_type)) + continue + if os.path.exists(artifact_directory): types_to_copy.append(artifact_type) # Never delete HTML nor JSON (search index) elif artifact_type not in UNDELETABLE_ARTIFACT_TYPES: