From 01489553a0ae19cbf91582669ccef3402364782c Mon Sep 17 00:00:00 2001 From: Sergiy Byelozyorov Date: Fri, 29 Jun 2018 18:13:15 +0000 Subject: [PATCH] Prune VirtualEnv's python from environment before running GN This is neccessary to ensure that generated ninja commands invoke python from PATH instead of the one from VPython's VirtualEnv. On LUCI builders that replace system python with VPython using vpython:native-python-wrapper swarming tag, a new VPython VirtualEnv bubble will be created for each script and contain that script's individual dependencies. Based on https://cs.chromium.org/chromium/infra/recipes-py/recipes.py?l=88&rcl=66d9d8c66f10ca37dffa4b6d374c3d802a061b01. R=iannucci@chromium.org Bug: 793687 Change-Id: I633d2e0dfeda0097072daba102fb013656aaafa2 Reviewed-on: https://chromium-review.googlesource.com/1120817 Commit-Queue: Sergiy Byelozyorov Reviewed-by: Robbie Iannucci --- gn.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/gn.py b/gn.py index cca57f95bb..e8a1f3a5c7 100755 --- a/gn.py +++ b/gn.py @@ -18,7 +18,31 @@ import subprocess import sys +def PruneVirtualEnv(): + # Set by VirtualEnv, no need to keep it. + os.environ.pop('VIRTUAL_ENV', None) + + # Set by VPython, if scripts want it back they have to set it explicitly. + os.environ.pop('PYTHONNOUSERSITE', None) + + # Look for "activate_this.py" in this path, which is installed by VirtualEnv. + # This mechanism is used by vpython as well to sanitize VirtualEnvs from + # $PATH. + os.environ['PATH'] = os.pathsep.join([ + p for p in os.environ.get('PATH', '').split(os.pathsep) + if not os.path.isfile(os.path.join(p, 'activate_this.py')) + ]) + + def main(args): + # Prune all evidence of VPython/VirtualEnv out of the environment. This means + # that we 'unwrap' vpython VirtualEnv path/env manipulation. Invocations of + # `python` from GN should never inherit the gn.py's own VirtualEnv. This also + # helps to ensure that generated ninja files do not reference python.exe from + # the VirtualEnv generated from depot_tools' own .vpython file (or lack + # thereof), but instead reference the default python from the PATH. + PruneVirtualEnv() + # Try in primary solution location first, with the gn binary having been # downloaded by cipd in the projects DEPS. gn_path = os.path.join(gclient_utils.GetPrimarySolutionPath(), 'third_party',