Skip to content

Commit acb8ea5

Browse files
committed
Adding retry logic (recursive) to run_command().
When setting remote URL on slow hosts such as AppVeyor, sometimes test_bad_git_config() runs into a race condition. Adding retry. Handling git remote set-url errors.
1 parent fec88fa commit acb8ea5

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

sphinxcontrib/versioning/git.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import re
88
import sys
99
import tarfile
10+
import time
1011
from datetime import datetime
1112
from subprocess import CalledProcessError, PIPE, Popen, STDOUT
1213

@@ -111,7 +112,7 @@ def chunk(iterator, max_size):
111112
yield chunked
112113

113114

114-
def run_command(local_root, command, env_var=True, pipeto=None):
115+
def run_command(local_root, command, env_var=True, pipeto=None, retry=0):
115116
"""Run a command and return the output.
116117
117118
:raise CalledProcessError: Command exits non-zero.
@@ -120,6 +121,7 @@ def run_command(local_root, command, env_var=True, pipeto=None):
120121
:param iter command: Command to run.
121122
:param bool env_var: Define GIT_DIR environment variable (on non-Windows).
122123
:param function pipeto: Pipe `command`'s stdout to this function (only parameter given).
124+
:param int retry: Retry this many times on CalledProcessError after 0.1 seconds.
123125
124126
:return: Command output.
125127
:rtype: str
@@ -145,7 +147,10 @@ def run_command(local_root, command, env_var=True, pipeto=None):
145147

146148
# Verify success.
147149
if main.poll() != 0:
148-
raise CalledProcessError(main.poll(), command, output=main_output)
150+
if retry < 1:
151+
raise CalledProcessError(main.poll(), command, output=main_output)
152+
time.sleep(0.1)
153+
return run_command(local_root, command, env_var, pipeto, retry - 1)
149154

150155
return main_output
151156

@@ -345,8 +350,11 @@ def clone(local_root, new_root, remote, branch, rel_dest, exclude):
345350

346351
# Copy all remotes from original repo.
347352
for name, (fetch, push) in remotes.items():
348-
run_command(new_root, ['git', 'remote', 'set-url' if name == 'origin' else 'add', name, fetch])
349-
run_command(new_root, ['git', 'remote', 'set-url', '--push', name, push])
353+
try:
354+
run_command(new_root, ['git', 'remote', 'set-url' if name == 'origin' else 'add', name, fetch], retry=3)
355+
run_command(new_root, ['git', 'remote', 'set-url', '--push', name, push], retry=3)
356+
except CalledProcessError as exc:
357+
raise GitError('Failed to set git remote URL.', exc.output)
350358

351359
# Done if no exclude.
352360
if not exclude:

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def config(monkeypatch):
2929
@pytest.fixture
3030
def run():
3131
"""run_command() wrapper returned from a pytest fixture."""
32-
return lambda d, c: run_command(str(d), [str(i) for i in c])
32+
return lambda d, c, *args, **kwargs: run_command(str(d), [str(i) for i in c], *args, **kwargs)
3333

3434

3535
@pytest.fixture

tests/test__main__/test_main_push_scenarios.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,8 @@ def test_bad_git_config(local_docs_ghp, run):
332332
# Invalidate lock file.
333333
tmp_repo = py.path.local(re.findall(r'"cwd": "([^"]+)"', line.decode('utf-8'))[0])
334334
assert tmp_repo.check(dir=True)
335-
for _ in range(3):
336-
try:
337-
run(tmp_repo, ['git', 'config', 'user.useConfigOnly', 'true'])
338-
run(tmp_repo, ['git', 'config', 'user.email', '(none)'])
339-
except CalledProcessError:
340-
continue
341-
break
335+
run(tmp_repo, ['git', 'config', 'user.useConfigOnly', 'true'], retry=3)
336+
run(tmp_repo, ['git', 'config', 'user.email', '(none)'], retry=3)
342337
caused = True
343338
output_lines.append(proc.communicate()[0])
344339
output = b''.join(output_lines).decode('utf-8')
@@ -348,4 +343,4 @@ def test_bad_git_config(local_docs_ghp, run):
348343
# Verify.
349344
assert 'Traceback' not in output
350345
assert 'Failed to commit locally.' in output
351-
assert 'Please tell me who you are.' in output
346+
assert 'Please tell me who you are.' in output or 'user.useConfigOnly set but no name given' in output

0 commit comments

Comments
 (0)