Skip to content

Instantly share code, notes, and snippets.

@TheDistantSea
Created August 19, 2013 23:07
Show Gist options
  • Save TheDistantSea/6275258 to your computer and use it in GitHub Desktop.
Save TheDistantSea/6275258 to your computer and use it in GitHub Desktop.
Batch file that modifies the current user's environment to set up Go in Windows. The idea is to automate the setup of a portable distribution of Go which can be copied to another system or moved around. Usage: Place file at the same level as the Go root and run. Confirmation is asked before any changes are made.
@echo off
setlocal enabledelayedexpansion
if errorlevel 1 goto :nodelayedexpansion
rem *** Find Go installations
set _go_binary=go.exe
set _go_i=0
for /f "delims=" %%i in ('2^>nul dir %_go_binary% /s/b') do (
set /a _go_i=_go_i+1
set _go_path_!_go_i!=%%i
)
if %_go_i%==0 goto :notfound
if %_go_i%==1 goto :obvious
echo Multiple Go installations were detected; cannot continue.
exit /b 3
:obvious
rem *** Installation instructions say to set GOROOT to the Go installation root and add %GOROOT%\bin to the PATH
rem *** When setting variables, use delayed expansion on ANYTHING that might contain the shell escape character (caret)
rem *** First determine the Go bindir
for %%i in ("%_go_path_1%") do pushd %%~dpi..
for /f "delims=" %%i in ('cd') do set _go_root=%%i
popd
set _go_bindir=!_go_root!\bin
rem *** Now see if the bindir already exists in the PATH
rem http://stackoverflow.com/questions/141344/how-to-check-if-directory-exists-in-path
set _fixed_path=!PATH!
for /f %%i in ('echo ";!_fixed_path!;" ^| find /C /I ";!_go_bindir!;"') do set _path_already_set=%%i
rem *** Also, check if another Go bindir exists in the PATH (we 'll want to remove it)
for /f %%i in ("%_go_binary%") do 2>nul set _which_go=%%~dp$PATH:i
if not "%_which_go%"=="" set _which_go=!_which_go:~0,-1!
if not "%_which_go%"=="" if not "!_which_go!"=="!_go_bindir!" (
echo WARNING: The Go binary directory was detected as !_go_bindir!,
echo but the PATH contains a different binary directory !_which_go!
echo.
echo If you choose to proceed the latter will be removed from PATH.
echo.
set _which_go=!_which_go:^^=^^^^!
set _fixed_path=!_fixed_path:%_which_go%=!
set _fixed_path=!_fixed_path:;;=;!
)
rem *** Determine and describe what steps are going to be taken
set _counter=0
if not "!GOROOT!"=="!_go_root!" set /a _counter=_counter+1 & set _task_set_goroot=1
if "%_path_already_set%"=="0" set /a _counter=_counter+1 & set _task_set_path=1
if %_counter%==0 goto :nothingtodo
if %_counter%==1 (
if !_task_set_goroot!==1 echo I will persistently set the environment variable GOROOT to "!_go_root!".
if !_task_set_path!==1 echo I will append the directory "!_go_bindir!" to PATH.
)
if %_counter%==2 echo I will persistently set the environment variable GOROOT to "!_go_root!" & echo and append the directory "!_go_bindir!" to PATH.
echo.
rem *** Present choice and act on affirmative
choice /m "Do you want to proceed [y/n]? " /n
if errorlevel 2 exit /b 0
rem *** EXTREMELY IMPORTANT: there must be no space between _go_root and &
rem Also, we are going to endlocal so we cannot use variable expansion -- must preprocess
set _fixed_path=!_fixed_path!;!_go_bindir!
set _fixed_path=!_fixed_path:^^=^^^^!
set _go_root=%_go_root:^^=^^^^%
if "%_task_set_goroot%"=="1" setx GOROOT %_go_root%& if "%_task_set_path%"=="1" setx PATH %_fixed_path%
endlocal & if "%_task_set_goroot%"=="1" set GOROOT=%_go_root%& if "%_task_set_path%"=="1" set PATH=%_fixed_path%
echo Environment set up.
exit /b 0
:nothingtodo
echo The GOROOT environment variable is already set to !_go_root!
echo The PATH already includes the Go bin directory !_go_bindir!
echo Nothing to do; exiting.
exit /b 0
:nodelayedexpansion
echo Error: delayed variable expansion could not be enabled.
exit /b 1
:notfound
echo Error: %_go_binary% was not found (searched recursively under %~dp0).
exit /b 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment