pw_env_setup: Fix batch 'if' statements

Batch doesn't support multi-line "if" statements in the way basically
every other language does. This makes me sad.

On a positive note, it was funny to see how much of this script was
non-deterministic.

Change-Id: I81dfae126bba8ba48c636832a4e4c30456319e52
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/23840
Commit-Queue: Armando Montanez <amontanez@google.com>
Reviewed-by: Rob Mohr <mohrr@google.com>
Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
diff --git a/bootstrap.bat b/bootstrap.bat
index 41d3833..ca68f5d 100644
--- a/bootstrap.bat
+++ b/bootstrap.bat
@@ -23,77 +23,106 @@
 
 :: Pigweed Windows environment setup.
 
+:: WARNING: Multi-line "if" statements can be dangerous!
+::
+:: Example:
+::  call do_foo
+::  if [expression] (
+::    call cmd_a
+::    set my_var = %ERRORLEVEL%
+::    call final_script --flag %my_var%
+::  )
+:: Batch evaluates these expressions in a way that will produce unexpected
+:: behavior. It appears that when each line is executed, it does not affect
+:: local context until the entire expression is complete. In this example,
+:: ERRORLEVEL does not reflect `call cmd_a`, but whatever residual state was
+:: present from `do_foo`. Similarly, in the call to `final_script`, `my_var`
+:: will NOT be valid as the variable `set` doesn't apply until the entire `if`
+:: expression completes.
+:: This script only uses multi-line if statements to `goto` after an operation.
+
 :: If PW_CHECKOUT_ROOT is set, use it. Users should not set this variable.
 :: It's used because when one batch script invokes another the Powershell magic
 :: below doesn't work. To reinforce that users should not be using
 :: PW_CHECKOUT_ROOT, it is cleared here after it is used, and other pw tools
 :: will complain if they see that variable set.
 :: TODO(mohrr) find out a way to do this without PW_CHECKOUT_ROOT.
-if "%PW_CHECKOUT_ROOT%"=="" (
-  :: ~dp0 is the batchism for the directory in which a .bat file resides.
-  set "PW_ROOT=%~dp0"
-) else (
-  set "PW_ROOT=%PW_CHECKOUT_ROOT%"
-  set PW_CHECKOUT_ROOT=
-)
 
+:: ~dp0 is the batchism for the directory in which a .bat file resides.
+if "%PW_CHECKOUT_ROOT%"=="" ^
+set "PW_ROOT=%~dp0" &^
+goto select_python
+
+:: Since PW_CHECKOUT_ROOT is set, use it.
+set "PW_ROOT=%PW_CHECKOUT_ROOT%"
+set "PW_CHECKOUT_ROOT="
+
+:select_python
 :: Allow forcing a specific Python version through the environment variable
 :: PW_BOOTSTRAP_PYTHON. Otherwise, use the system Python if one exists.
 if not "%PW_BOOTSTRAP_PYTHON%" == "" (
   set "python=%PW_BOOTSTRAP_PYTHON%"
-) else (
-  where python >NUL 2>&1
-  if %ERRORLEVEL% EQU 0 (
-    set python=python
-  ) else (
-    echo.
-    echo Error: no system Python present
-    echo.
-    echo   Pigweed's bootstrap process requires a local system Python.
-    echo   Please install Python on your system, add it to your PATH
-    echo   and re-try running bootstrap.
-    goto finish
-  )
+  goto find_environment_root
 )
 
-:: PW_ENVIRONMENT_ROOT allows developers to specify where the environment should
-:: be installed. _PW_ACTUAL_ENVIRONMENT_ROOT is where Pigweed keeps that 
-:: information. This separation allows Pigweed to assume PW_ENVIRONMENT_ROOT 
-:: came from the developer and not from a previous bootstrap possibly from 
-:: another workspace.
-if "%PW_ENVIRONMENT_ROOT%"=="" (
-   :: Not prefixing environment with "." since that doesn't hide it anyway.
-   set "_PW_ACTUAL_ENVIRONMENT_ROOT=%PW_ROOT%\environment"
-) else (
-   set "_PW_ACTUAL_ENVIRONMENT_ROOT=%PW_ENVIRONMENT_ROOT%"
+:: Detect python installation.
+where python >NUL 2>&1
+if %ERRORLEVEL% EQU 0 (
+  set "python=python"
+  goto find_environment_root
 )
+
+echo.
+echo Error: no system Python present
+echo.
+echo   Pigweed's bootstrap process requires a local system Python.
+echo   Please install Python on your system, add it to your PATH
+echo   and re-try running bootstrap.
+goto finish
+
+
+:find_environment_root
+:: PW_ENVIRONMENT_ROOT allows developers to specify where the environment should
+:: be installed. _PW_ACTUAL_ENVIRONMENT_ROOT is where Pigweed keeps that
+:: information. This separation allows Pigweed to assume PW_ENVIRONMENT_ROOT
+:: came from the developer and not from a previous bootstrap possibly from
+:: another workspace.
+
+:: Not prefixing environment with "." since that doesn't hide it anyway.
+if "%PW_ENVIRONMENT_ROOT%"=="" (
+  set "_PW_ACTUAL_ENVIRONMENT_ROOT=%PW_ROOT%\environment"
+) else (
+  set "_PW_ACTUAL_ENVIRONMENT_ROOT=%PW_ENVIRONMENT_ROOT%"
+)
+
 set "shell_file=%_PW_ACTUAL_ENVIRONMENT_ROOT%\activate.bat"
 
 set "_pw_start_script=%PW_ROOT%\pw_env_setup\py\pw_env_setup\windows_env_start.py"
 
-if "%PW_PROJECT_ROOT%"=="" (
-   set "PW_PROJECT_ROOT=%PW_ROOT%"
-)
+if "%PW_PROJECT_ROOT%"=="" set "PW_PROJECT_ROOT=%PW_ROOT%"
 
 :: If PW_SKIP_BOOTSTRAP is set, only run the activation stage instead of the
 :: complete env_setup.
-if "%PW_SKIP_BOOTSTRAP%" == "" (
-  :: Without the trailing slash in %PW_ROOT%/, batch combines that token with
-  :: the --shell-file argument.
-  call "%python%" "%PW_ROOT%\pw_env_setup\py\pw_env_setup\env_setup.py" ^
-      --pw-root "%PW_ROOT%/" ^
-      --shell-file "%shell_file%" ^
-      --install-dir "%_PW_ACTUAL_ENVIRONMENT_ROOT%" ^
-      --use-pigweed-defaults
+if not "%PW_SKIP_BOOTSTRAP%" == "" goto skip_bootstrap
+
+:: Without the trailing slash in %PW_ROOT%/, batch combines that token with
+:: the --shell-file argument.
+call "%python%" "%PW_ROOT%\pw_env_setup\py\pw_env_setup\env_setup.py" ^
+    --pw-root "%PW_ROOT%/" ^
+    --shell-file "%shell_file%" ^
+    --install-dir "%_PW_ACTUAL_ENVIRONMENT_ROOT%" ^
+    --use-pigweed-defaults
+goto activate_shell
+
+:skip_bootstrap
+if exist "%shell_file%" (
+  call "%python%" "%_pw_start_script%"
 ) else (
-  if exist "%shell_file%" (
-    call "%python%" "%_pw_start_script%"
-  ) else (
-    call "%python%" "%_pw_start_script%" --no-shell-file
-    goto finish
-  )
+  call "%python%" "%_pw_start_script%" --no-shell-file
+  goto finish
 )
 
+:activate_shell
 call "%shell_file%"
 
 :finish