Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1251)

Unified Diff: recipe_engine/step_runner.py

Issue 2727553005: [step_runner] add logic to resolve absolute path of argv[0] on windows. (Closed)
Patch Set: fix comment Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: recipe_engine/step_runner.py
diff --git a/recipe_engine/step_runner.py b/recipe_engine/step_runner.py
index 2dc2f3a25182d5be75ce92626ec5021fe6e8171b..a3cc100fb868a7fd5fb572ddfc79062d96b4fc7d 100644
--- a/recipe_engine/step_runner.py
+++ b/recipe_engine/step_runner.py
@@ -6,6 +6,7 @@ import calendar
import collections
import contextlib
import datetime
+import itertools
import json
import os
import re
@@ -176,13 +177,10 @@ class SubprocessStepRunner(StepRunner):
)
step_config = None # Make sure we use rendered step config.
- rendered_step = rendered_step._replace(
- config=rendered_step.config._replace(
- cmd=map(str, rendered_step.config.cmd),
- ),
- )
-
step_env = _merge_envs(os.environ, (rendered_step.config.env or {}))
+ # Now that the step's environment is all sorted, evaluate PATH on windows
+ # to find the actual intended executable.
+ rendered_step = _hunt_path(rendered_step, step_env)
self._print_step(step_stream, rendered_step, step_env)
class ReturnOpenStep(OpenStep):
@@ -540,7 +538,7 @@ def render_step(step_config, step_test):
output_phs[module_name][placeholder_name][item.name] = (item, tdata)
else:
new_cmd.append(item)
- step_config = step_config._replace(cmd=new_cmd)
+ step_config = step_config._replace(cmd=map(str, new_cmd))
# Process 'stdout', 'stderr' and 'stdin' placeholders, if given.
stdio_placeholders = {}
@@ -651,6 +649,55 @@ def _merge_envs(original, override):
return result
+if sys.platform == "win32":
+ _hunt_path_exts = ('.exe', '.bat')
+ def _hunt_path(rendered_step, step_env):
+ """This takes the lazy cross-product of PATH and ('.exe', '.bat') to find
+ what cmd.exe would have found for the command if we used shell=True.
+
+ This must be called on the render_step AFTER _merge_envs has produced
+ step_env to pick up any changes to PATH.
+
+ If it succeeds, it returns a new rendered_step. If it fails, it returns the
+ same rendered_step, and subprocess will run as normal (and likely fail).
+
+ This will not attempt to do any evaluations for commands where the program
+ already has an explicit extension (.exe, .bat, etc.), and it will not
+ attempt to do any evaluations for commands where the program is an absolute
+ path.
+
+ This DOES NOT use PATHEXT to keep the recipe engine's behavior as
+ predictable as possible. We don't currently rely on any other runnable
+ extensions besides these two, and when we could, we choose to explicitly
+ invoke the interpreter (e.g. python.exe, cscript.exe, etc.).
+ """
+ cmd = rendered_step.config.cmd
+ cmd0 = cmd[0]
+ if '.' in cmd0: # something.ext will work fine with subprocess.
+ return rendered_step
+ if os.path.isabs(cmd0): # PATH isn't even used
+ return rendered_step
+
+ # begin the hunt
+ paths = step_env.get('PATH', '').split(os.pathsep)
+ if not paths:
+ return rendered_step
+
+ # try every extension for each path
+ for path, ext in itertools.product(paths, _hunt_path_exts):
+ candidate = os.path.join(path, cmd0+ext)
+ if os.path.isfile(candidate):
+ return rendered_step._replace(
+ config=rendered_step.config._replace(
+ cmd=[candidate]+cmd[1:],
+ ),
+ )
+ return rendered_step
+else:
+ def _hunt_path(rendered_step, _step_env):
+ return rendered_step
+
+
def _shell_quote(arg):
"""Shell-quotes a string with minimal noise.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698