Handle an empty interpreter_path in exec_script

If the interpreter_path is the empty string, exec_script() attempts to
construct a command line with the first argument being the empty string
and the second being the name of the program. This fails, where the
user likely expected their script to execute directly.

Change-Id: I70a9f28a3e256753666016c951daafa00882142b
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/7460
Commit-Queue: Brett Wilson <brettw@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/docs/reference.md b/docs/reference.md
index 5222fb8..cbf9db1 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -68,6 +68,7 @@
     *   [current_os: [string] The operating system of the current toolchain.](#var_current_os)
     *   [current_toolchain: [string] Label of the current toolchain.](#var_current_toolchain)
     *   [default_toolchain: [string] Label of the default toolchain.](#var_default_toolchain)
+    *   [gn_version: [number] The version of gn.](#var_gn_version)
     *   [host_cpu: [string] The processor architecture that GN is running on.](#var_host_cpu)
     *   [host_os: [string] The operating system that GN is running on.](#var_host_os)
     *   [invoker: [string] The invoking scope inside a template.](#var_invoker)
@@ -4036,6 +4037,17 @@
   A fully-qualified label representing the default toolchain, which may not
   necessarily be the current one (see "current_toolchain").
 ```
+### <a name="var_gn_version"></a>**gn_version**: [number] The version of gn.
+
+```
+  Corresponds to the number printed by `gn --version`.
+```
+
+#### **Example**
+
+```
+  assert(gn_version >= 1700, "need GN version 1700 for the frobulate feature")
+```
 ### <a name="var_host_cpu"></a>**host_cpu**: The processor architecture that GN is running on.
 
 ```
@@ -6482,9 +6494,12 @@
       cause the file //BUILD.gn to be loaded.
 
   script_executable [optional]
-      Path to specific Python executable or potentially a different language
-      interpreter that is used to execute scripts in action targets and
-      exec_script calls.
+      Path to specific Python executable or other interpreter to use in
+      action targets and exec_script calls. By default GN searches the
+      PATH for Python to execute these scripts.
+
+      If set to the empty string, the path specified in action targets
+      and exec_script calls will be executed directly.
 
   secondary_source [optional]
       Label of an alternate directory tree to find input files. When searching
diff --git a/src/gn/function_exec_script.cc b/src/gn/function_exec_script.cc
index 20bd815..f5f24aa 100644
--- a/src/gn/function_exec_script.cc
+++ b/src/gn/function_exec_script.cc
@@ -176,14 +176,22 @@
   }
 
   // Make the command line.
-  const base::FilePath& interpreter_path = build_settings->python_path();
-  base::CommandLine cmdline(interpreter_path);
+  base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
 
   // CommandLine tries to interpret arguments by default.  Disable that so
   // that the arguments will be passed through exactly as specified.
   cmdline.SetParseSwitches(false);
 
-  cmdline.AppendArgPath(script_path);
+  // If an interpreter path is set, initialize it as the first entry and
+  // pass script_path as the first argument. Otherwise, set the
+  // program to script_path directly.
+  const base::FilePath& interpreter_path = build_settings->python_path();
+  if (!interpreter_path.empty()) {
+    cmdline.SetProgram(interpreter_path);
+    cmdline.AppendArgPath(script_path);
+  } else {
+    cmdline.SetProgram(script_path);
+  }
 
   if (args.size() >= 2) {
     // Optional command-line arguments to the script.
diff --git a/src/gn/setup.cc b/src/gn/setup.cc
index 5d7bc8a..cbaa958 100644
--- a/src/gn/setup.cc
+++ b/src/gn/setup.cc
@@ -110,9 +110,12 @@
       cause the file //BUILD.gn to be loaded.
 
   script_executable [optional]
-      Path to specific Python executable or potentially a different language
-      interpreter that is used to execute scripts in action targets and
-      exec_script calls.
+      Path to specific Python executable or other interpreter to use in
+      action targets and exec_script calls. By default GN searches the
+      PATH for Python to execute these scripts.
+
+      If set to the empty string, the path specified in action targets
+      and exec_script calls will be executed directly.
 
   secondary_source [optional]
       Label of an alternate directory tree to find input files. When searching
diff --git a/src/gn/switches.cc b/src/gn/switches.cc
index fe4696d..dea73c6 100644
--- a/src/gn/switches.cc
+++ b/src/gn/switches.cc
@@ -105,10 +105,12 @@
 const char kScriptExecutable_Help[] =
     R"(--script-executable: Set the executable used to execute scripts.
 
-  By default GN searches the PATH for Python to execute scripts in action
-  targets and exec_script calls. This flag allows the specification of a
-  specific Python executable or potentially a different language
-  interpreter.
+  Path to specific Python executable or other interpreter to use in
+  action targets and exec_script calls. By default GN searches the
+  PATH for Python to execute these scripts.
+
+  If set to the empty string, the path specified in action targets
+  and exec_script calls will be executed directly.
 )";
 
 const char kMetaDataKeys[] = "data";