Skip to content

Commit f54d78b

Browse files
committed
Merge pull request #1559 from rtfd/build-command-shebang
Call python scripts as argument to virtualenv python command
2 parents 8871446 + 9dfa0de commit f54d78b

File tree

6 files changed

+50
-16
lines changed

6 files changed

+50
-16
lines changed

readthedocs/doc_builder/backends/mkdocs.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,19 @@ def append_conf(self, **kwargs):
130130
def build(self, **kwargs):
131131
checkout_path = self.project.checkout_path(self.version.slug)
132132
build_command = [
133+
'python',
133134
self.project.venv_bin(version=self.version.slug, bin='mkdocs'),
134135
self.builder,
135136
'--clean',
136137
'--site-dir', self.build_dir,
137138
]
138139
if self.use_theme:
139140
build_command.extend(['--theme', 'readthedocs'])
140-
cmd_ret = self.run(*build_command, cwd=checkout_path)
141+
cmd_ret = self.run(
142+
*build_command,
143+
cwd=checkout_path,
144+
bin_path=self.project.venv_bin(version=self.version.slug)
145+
)
141146
return cmd_ret.successful
142147

143148

readthedocs/doc_builder/backends/sphinx.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def build(self, **kwargs):
126126
self.clean()
127127
project = self.project
128128
build_command = [
129+
'python',
129130
project.venv_bin(version=self.version.slug, bin='sphinx-build'),
130131
'-T'
131132
]
@@ -138,8 +139,11 @@ def build(self, **kwargs):
138139
'.',
139140
self.sphinx_build_dir
140141
])
141-
cmd_ret = self.run(*build_command,
142-
cwd=project.conf_dir(self.version.slug))
142+
cmd_ret = self.run(
143+
*build_command,
144+
cwd=project.conf_dir(self.version.slug),
145+
bin_path=project.venv_bin(version=self.version.slug)
146+
)
143147
return cmd_ret.successful
144148

145149

@@ -232,13 +236,15 @@ def build(self, **kwargs):
232236

233237
# Default to this so we can return it always.
234238
self.run(
239+
'python',
235240
self.project.venv_bin(version=self.version.slug, bin='sphinx-build'),
236241
'-b', 'latex',
237242
'-D', 'language={lang}'.format(lang=self.project.language),
238243
'-d', '_build/doctrees',
239244
'.',
240245
'_build/latex',
241-
cwd=cwd
246+
cwd=cwd,
247+
bin_path=self.project.venv_bin(version=self.version.slug)
242248
)
243249
latex_cwd = os.path.join(cwd, '_build', 'latex')
244250
tex_files = glob(os.path.join(latex_cwd, '*.tex'))

readthedocs/doc_builder/environments.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class BuildCommand(object):
4444

4545
# TODO add short name here for reporting
4646
def __init__(self, command, cwd=None, shell=False, environment=None,
47-
combine_output=True, input_data=None, build_env=None):
47+
combine_output=True, input_data=None, build_env=None,
48+
bin_path=None):
4849
self.command = command
4950
self.shell = shell
5051
if cwd is None:
@@ -55,6 +56,7 @@ def __init__(self, command, cwd=None, shell=False, environment=None,
5556
self.environment.update(environment)
5657
self.combine_output = combine_output
5758
self.build_env = build_env
59+
self.bin_path = bin_path
5860
self.status = None
5961
self.input_data = input_data
6062
self.output = None
@@ -91,6 +93,10 @@ def run(self):
9193
del environment['DJANGO_SETTINGS_MODULE']
9294
if 'PYTHONPATH' in environment:
9395
del environment['PYTHONPATH']
96+
if self.bin_path is not None:
97+
env_paths = environment.get('PATH', '').split(':')
98+
env_paths.insert(0, self.bin_path)
99+
environment['PATH'] = ':'.join(env_paths)
94100

95101
try:
96102
proc = subprocess.Popen(

readthedocs/projects/models.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,17 @@ def single_version_symlink_path(self):
484484
# End symlink paths
485485
#
486486

487-
def venv_bin(self, version=LATEST, bin='python'):
488-
return os.path.join(self.venv_path(version), 'bin', bin)
487+
def venv_bin(self, version=LATEST, bin=None):
488+
"""Return path to the virtualenv bin path, or a specific binary
489+
490+
If ``bin`` is :py:data:`None`, then return the path to the virtual env
491+
path, otherwise, return the path to the executable ``bin`` in the
492+
virtual env ``bin`` path
493+
"""
494+
parts = [self.venv_path(version), 'bin']
495+
if bin is not None:
496+
parts.append(bin)
497+
return os.path.join(*parts)
489498

490499
def full_doc_path(self, version=LATEST):
491500
"""

readthedocs/projects/tasks.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ def setup_environment(self):
262262
]
263263

264264
cmd = [
265+
'python',
265266
self.project.venv_bin(version=self.version.slug, bin='pip'),
266267
'install',
267268
'--use-wheel',
@@ -275,7 +276,10 @@ def setup_environment(self):
275276
# --system-site-packages is used)
276277
cmd.append('-I')
277278
cmd.extend(requirements)
278-
self.build_env.run(*cmd)
279+
self.build_env.run(
280+
*cmd,
281+
bin_path=self.project.venv_bin(version=self.version.slug)
282+
)
279283

280284
# Handle requirements
281285
requirements_file_path = self.project.requirements_file
@@ -293,11 +297,13 @@ def setup_environment(self):
293297

294298
if requirements_file_path:
295299
self.build_env.run(
300+
'python',
296301
self.project.venv_bin(version=self.version.slug, bin='pip'),
297302
'install',
298303
'--exists-action=w',
299304
'-r{0}'.format(requirements_file_path),
300-
cwd=checkout_path
305+
cwd=checkout_path,
306+
bin_path=self.project.venv_bin(version=self.version.slug)
301307
)
302308

303309
# Handle setup.py
@@ -306,21 +312,22 @@ def setup_environment(self):
306312
if os.path.isfile(setup_path):
307313
if getattr(settings, 'USE_PIP_INSTALL', False):
308314
self.build_env.run(
309-
self.project.venv_bin(version=self.version.slug,
310-
bin='pip'),
315+
'python',
316+
self.project.venv_bin(version=self.version.slug, bin='pip'),
311317
'install',
312318
'--ignore-installed',
313319
'.',
314-
cwd=checkout_path
320+
cwd=checkout_path,
321+
bin_path=self.project.venv_bin(version=self.version.slug)
315322
)
316323
else:
317324
self.build_env.run(
318-
self.project.venv_bin(version=self.version.slug,
319-
bin='python'),
325+
'python',
320326
'setup.py',
321327
'install',
322328
'--force',
323-
cwd=checkout_path
329+
cwd=checkout_path,
330+
bin_path=self.project.venv_bin(version=self.version.slug)
324331
)
325332

326333
def build_docs(self):

readthedocs/rtd_tests/tests/test_builds.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ def test_build(self):
4646
# Get command and check first part of command list is a call to sphinx
4747
self.assertEqual(self.mocks.popen.call_count, 1)
4848
cmd = self.mocks.popen.call_args_list[0][0]
49-
self.assertRegexpMatches(cmd[0][0], r'sphinx-build')
49+
self.assertRegexpMatches(cmd[0][0], r'python')
50+
self.assertRegexpMatches(cmd[0][1], r'sphinx-build')
5051

5152
def test_build_respects_pdf_flag(self):
5253
'''Build output format control'''

0 commit comments

Comments
 (0)