-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Use latexmk if Sphinx > 1.6 #5656
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
Changes from 6 commits
ec7050b
699cba9
dc843ce
fd13ee5
0f5080e
3de6972
ebb1325
9d3a71a
f9e24c6
3272a0c
65b44e0
204c020
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,14 +10,14 @@ | |
import logging | ||
import os | ||
import shutil | ||
import sys | ||
import zipfile | ||
from glob import glob | ||
from pathlib import Path | ||
|
||
from django.conf import settings | ||
from django.template import loader as template_loader | ||
from django.template.loader import render_to_string | ||
from packaging.version import Version | ||
|
||
from readthedocs.builds import utils as version_utils | ||
from readthedocs.projects.exceptions import ProjectConfigurationError | ||
|
@@ -149,9 +149,6 @@ def get_config_params(self): | |
'dont_overwrite_sphinx_context': self.project.has_feature( | ||
Feature.DONT_OVERWRITE_SPHINX_CONTEXT, | ||
), | ||
'use_pdf_latexmk': self.project.has_feature( | ||
Feature.USE_PDF_LATEXMK, | ||
), | ||
} | ||
|
||
finalize_sphinx_context_data.send( | ||
|
@@ -232,6 +229,34 @@ def build(self): | |
) | ||
return cmd_ret.successful | ||
|
||
def venv_sphinx_version(self): | ||
""" | ||
Execute Python from the venv to query the ``sphinx`` version. | ||
|
||
Example, | ||
|
||
>>> import sphinx | ||
>>> print(sphinx.__version__) | ||
'2.0.0' | ||
|
||
In this case, the output will be ``2.0.0``. | ||
""" | ||
|
||
command = [ | ||
self.python_env.venv_bin(filename='python'), | ||
'-c' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are missing a comma here |
||
'"import sphinx; print(sphinx.__version__)"', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when >>> proc = subprocess.Popen(['python3', '-c', 'import sphinx; print(sphinx.__version__)'], stdou
t=subprocess.PIPE)
>>> proc.communicate()
(b'1.8.5\n', None)
>>> proc = subprocess.Popen(['python3', '-c', '"import sphinx; print(sphinx.__version__)"'], std
out=subprocess.PIPE)
>>> proc.communicate()
(b'', None) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for raising this. I made it work by using I like how the ended now. On It works in both builder backends. |
||
] | ||
|
||
cmd_ret = self.run( | ||
*command, | ||
bin_path=self.python_env.venv_bin(), | ||
cwd=self.project.checkout_path(self.version.slug), | ||
escape_command=False, | ||
record=False, | ||
) | ||
return cmd_ret.output | ||
|
||
|
||
class HtmlBuilder(BaseSphinx): | ||
type = 'sphinx' | ||
|
@@ -395,7 +420,10 @@ def build(self): | |
raise BuildEnvironmentError('No TeX files were found') | ||
|
||
# Run LaTeX -> PDF conversions | ||
if self.project.has_feature(Feature.USE_PDF_LATEXMK): | ||
# Build PDF with ``latexmk`` if Sphinx > 1.6, otherwise fallback to | ||
# ``pdflatex`` to support old versions | ||
sphinx_version = Version(self.venv_sphinx_version()) | ||
if sphinx_version > Version('1.6'): | ||
return self._build_latexmk(cwd, latex_cwd) | ||
|
||
return self._build_pdflatex(tex_files, latex_cwd) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,6 +83,7 @@ class BuildCommand(BuildCommandResultMixin): | |
:param build_env: build environment to use to execute commands | ||
:param bin_path: binary path to add to PATH resolution | ||
:param description: a more grokable description of the command being run | ||
:param kwargs: allow to subclass this class and extend it | ||
""" | ||
|
||
def __init__( | ||
|
@@ -97,6 +98,7 @@ def __init__( | |
bin_path=None, | ||
description=None, | ||
record_as_success=False, | ||
**kwargs, | ||
): | ||
self.command = command | ||
self.shell = shell | ||
|
@@ -296,14 +298,20 @@ class DockerBuildCommand(BuildCommand): | |
Build command to execute in docker container | ||
""" | ||
|
||
def run(self): | ||
def __init__(self, *args, escape_command=True, **kwargs): | ||
""" | ||
Execute command in existing Docker container. | ||
Override default to extend behavior. | ||
|
||
:param cmd_input: input to pass to command in STDIN | ||
:type cmd_input: str | ||
:param combine_output: combine STDERR into STDOUT | ||
:param escape_command: whether escape special chars the command before | ||
executing it in the container. This should only be disabled on | ||
trusted or internal commands. | ||
:type escape_command: bool | ||
""" | ||
self.escape_command = escape_command | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels like something that can be moved to the parent class. I think (not sure) that the same behavior for this in local command is https://docs.python.org/3.6/library/subprocess.html
|
||
super(DockerBuildCommand, self).__init__(*args, **kwargs) | ||
|
||
def run(self): | ||
"""Execute command in existing Docker container.""" | ||
log.info( | ||
"Running in container %s: '%s' [%s]", | ||
self.build_env.container_id, | ||
|
@@ -352,13 +360,15 @@ def run(self): | |
|
||
def get_wrapped_command(self): | ||
""" | ||
Escape special bash characters in command to wrap in shell. | ||
Wrap command in a shell and optionally escape special bash characters. | ||
|
||
In order to set the current working path inside a docker container, we | ||
need to wrap the command in a shell call manually. Some characters will | ||
be interpreted as shell characters without escaping, such as: ``pip | ||
install requests<0.8``. This escapes a good majority of those | ||
characters. | ||
need to wrap the command in a shell call manually. | ||
|
||
Some characters will be interpreted as shell characters without | ||
escaping, such as: ``pip install requests<0.8``. When passing | ||
``escape_command=True`` in the init method this escapes a good majority | ||
of those characters. | ||
""" | ||
bash_escape_re = re.compile( | ||
r"([\t\ \!\"\#\$\&\'\(\)\*\:\;\<\>\?\@" | ||
|
@@ -367,16 +377,18 @@ def get_wrapped_command(self): | |
prefix = '' | ||
if self.bin_path: | ||
prefix += 'PATH={}:$PATH '.format(self.bin_path) | ||
|
||
command = ( | ||
' '.join([ | ||
bash_escape_re.sub(r'\\\1', part) if self.escape_command else part | ||
for part in self.command | ||
]) | ||
) | ||
return ( | ||
"/bin/sh -c 'cd {cwd} && {prefix}{cmd}'".format( | ||
cwd=self.cwd, | ||
prefix=prefix, | ||
cmd=( | ||
' '.join([ | ||
bash_escape_re.sub(r'\\\1', part) | ||
for part in self.command | ||
]) | ||
), | ||
cmd=command, | ||
) | ||
) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks unused now.