Commit 7b294392 authored by Elly Fong-Jones's avatar Elly Fong-Jones Committed by Commit Bot

depot_tools: bail out if $PATH contains tildes

Bash and its descendants allow having $PATH entries containing literal tildes,
like:
  ...:~/depot_tools:...
If the user has their shell configured this way, their shell will be able to
invoke `fetch` and other depot_tools commands, but depot_tools will not in turn
be able to invoke subcommands via popen because popen does not have this
bash-specific behavior when not in shell mode.

This change has gclient detect this configuration problem and error out with a
descriptive error message. Not doing so leads to a puzzling condition where
gclient complains about being unable to find a program that (from the user's
perspective) is in their $PATH and invokable interactively.

It also has 'fetch' suppress its own failure stack trace if it runs gclient and
gclient fails; the 'fetch' stack trace pushes the messages from gclient (which
are actually diagnostic) off the screen.

Bug: chromium:952865
Change-Id: Ibba4d2fccee405aa68392ce141493f1de21ec018
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1573204
Commit-Queue: Elly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: 's avatarAaron Gable <agable@chromium.org>
parent ac9b0f37
......@@ -70,7 +70,16 @@ class Checkout(object):
if return_stdout:
return subprocess.check_output(cmd, **kwargs)
else:
subprocess.check_call(cmd, **kwargs)
try:
subprocess.check_call(cmd, **kwargs)
except subprocess.CalledProcessError as e:
# If the subprocess failed, it likely emitted its own distress message
# already - don't scroll that message off the screen with a stack trace
# from this program as well. Emit a terse message and bail out here;
# otherwise a later step will try doing more work and may hide the
# subprocess message.
print('Subprocess failed with return code %d.' % e.returncode)
sys.exit(e.returncode)
return ''
......
......@@ -3098,19 +3098,40 @@ def disable_buffering():
sys.stdout = gclient_utils.MakeFileAnnotated(sys.stdout)
def main(argv):
"""Doesn't parse the arguments here, just find the right subcommand to
execute."""
def path_contains_tilde():
for element in os.environ['PATH'].split(os.pathsep):
if element.startswith('~/'):
return True
return False
def can_run_gclient_and_helpers():
if sys.hexversion < 0x02060000:
print(
'\nYour python version %s is unsupported, please upgrade.\n' %
sys.version.split(' ', 1)[0],
file=sys.stderr)
return 2
return False
if not sys.executable:
print(
'\nPython cannot find the location of it\'s own executable.\n',
file=sys.stderr)
return False
if path_contains_tilde():
print(
'\nYour PATH contains a literal "~", which works in some shells ' +
'but will break when python tries to run subprocesses. ' +
'Replace the "~" with $HOME.\n' +
'See https://crbug.com/952865.\n',
file=sys.stderr)
return False
return True
def main(argv):
"""Doesn't parse the arguments here, just find the right subcommand to
execute."""
if not can_run_gclient_and_helpers():
return 2
fix_encoding.fix_encoding()
disable_buffering()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment