Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build: proof of concept for pre/post build commands (build.jobs) #9002

Merged
merged 12 commits into from
Mar 15, 2022
72 changes: 43 additions & 29 deletions readthedocs/doc_builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,24 @@


class DocumentationBuilder:
humitos marked this conversation as resolved.
Show resolved Hide resolved
humitos marked this conversation as resolved.
Show resolved Hide resolved
def __init__(
self,
data, # Celery task's ``data`` object
):
"""Initializer.

"""
Encapsulates all the logic to perform a build for user's documentation.

This class handles all the VCS commands, setup OS and language (e.g. only
Python for now) environment (via virtualenv or conda), installs all the
required basic and user packages, and finally execute the build commands
(e.g. Sphinx or MkDocs) to generate the artifacts.

Note that this class *is not* in charge of doing anything related to Read
the Docs, the platform, itself. These include not updating the `Build`'s
status, or uploading the artifacts to the storage, creating the search
index, among others.
humitos marked this conversation as resolved.
Show resolved Hide resolved
"""

def __init__(self, data):
"""
Initializer.

:param data: object with all the data grabbed by Celery task in
``before_start`` and used as a way to share data with this class
Expand Down Expand Up @@ -290,29 +303,28 @@ def pre_build(self):

def build_html(self):
commands = [] # self.data.config.build.jobs.build.html
for command in commands:
self.build_environment.run(command)
if commands:
for command in commands:
self.build_environment.run(command)
humitos marked this conversation as resolved.
Show resolved Hide resolved
return True

if not commands:
return self.build_docs_class(self.data.config.doctype)
return self.build_docs_class(self.data.config.doctype)

def build_pdf(self):
if "pdf" not in self.data.config.formats or self.data.version.type == EXTERNAL:
return False

# TODO: adapt all the other `build_` methods to use `if commands:`
commands = [] # self.data.config.build.jobs.build.pdf
if commands:
for command in commands:
self.build_environment.run(command)
return True

else:
# Mkdocs has no pdf generation currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_pdf")
# Mkdocs has no pdf generation currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_pdf")

return False
return False

def build_htmlzip(self):
if (
Expand All @@ -322,28 +334,30 @@ def build_htmlzip(self):
return False

commands = [] # self.data.config.build.jobs.build.htmlzip
for command in commands:
self.build_environment.run(command)
if commands:
for command in commands:
self.build_environment.run(command)
return True

if not commands:
# We don't generate a zip for mkdocs currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_singlehtmllocalmedia")
return False
# We don't generate a zip for mkdocs currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_singlehtmllocalmedia")
return False

def build_epub(self):
if "epub" not in self.data.config.formats or self.data.version.type == EXTERNAL:
return False

commands = [] # self.data.config.build.jobs.build.epub
for command in commands:
self.build_environment.run(command)
if commands:
for command in commands:
self.build_environment.run(command)
return True

if not commands:
# Mkdocs has no epub generation currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_epub")
return False
# Mkdocs has no epub generation currently.
if self.is_type_sphinx():
return self.build_docs_class("sphinx_epub")
return False

def post_build(self):
commands = [] # self.data.config.build.jobs.post_build
Expand Down
15 changes: 4 additions & 11 deletions readthedocs/projects/tasks/builds.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ class TaskData:
"""



class SyncRepositoryTask(SyncRepositoryMixin, Task):

"""
Expand Down Expand Up @@ -537,28 +536,23 @@ def update_build(self, state):
log.exception('Unable to update build')

def execute(self):
# NOTE: what about doing:
#
# (triggered)
# - self.clone()
# - self.install()
# - self.build()
# - self.upload()
# (finished)

self.data.builder = DocumentationBuilder(
data=self.data,
)

# Clonning
self.update_build(state=BUILD_STATE_CLONING)
self.data.builder.vcs()

# Sync tags/branches from VCS repository into Read the Docs' `Version`
# objects in the database
self.sync_versions(self.data.builder.vcs_repository)
humitos marked this conversation as resolved.
Show resolved Hide resolved

# Installing
self.update_build(state=BUILD_STATE_INSTALLING)
self.data.builder.setup_environment()

# Building
self.update_build(state=BUILD_STATE_BUILDING)
self.data.builder.build()

Expand Down Expand Up @@ -600,7 +594,6 @@ def set_valid_clone(self):
self.data.project.has_valid_clone = True
self.data.version.project.has_valid_clone = True


def store_build_artifacts(
self,
html=False,
Expand Down
Loading