Auto-install Git, Node and Python via winget
Each prerequisite now follows probe -> offer install -> probe again. The second probe matters: a freshly installed tool is never visible to `where` in the session that installed it, since the process inherited its PATH at start. A *_TRIED guard stops the loop at one attempt. Node installs from the LTS package on purpose - better-sqlite3 publishes prebuilt binaries for LTS, so this sidesteps the node-gyp compile that the existing Node >= 23 warning covers. Python detection runs the interpreter instead of calling `where python`. Windows ships a stub python.exe under WindowsApps that only opens the Microsoft Store; `where` finds it but it cannot execute anything. Asking for sys.version_info distinguishes the two, and the py launcher is preferred because the stub does not shadow it. Dependency install now upgrades pip first and verifies pyautogui actually imports, rather than trusting pip's exit code alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8e64d8a34f
commit
a718caeb08
+115
-32
@@ -21,39 +21,85 @@ echo ============================================
|
||||
echo.
|
||||
|
||||
REM ---------------------------------------------------------------- git check
|
||||
REM Git for Windows only adds itself to PATH if "Git from the command line" was
|
||||
REM chosen at install time, and an already-open cmd keeps its old PATH anyway.
|
||||
REM So probe the usual install homes before giving up.
|
||||
REM Git for Windows only lands on PATH if "Git from the command line" was chosen
|
||||
REM at install time, and an already-open cmd keeps its old PATH regardless. So:
|
||||
REM probe the usual homes, then offer to install, then probe again - a fresh
|
||||
REM install is never visible to `where` in this session.
|
||||
:git_probe
|
||||
where git >nul 2>&1
|
||||
if not errorlevel 1 goto :git_ok
|
||||
if not errorlevel 1 goto :git_done
|
||||
if exist "%ProgramFiles%\Git\cmd\git.exe" set "PATH=%ProgramFiles%\Git\cmd;%PATH%"
|
||||
if exist "%ProgramFiles(x86)%\Git\cmd\git.exe" set "PATH=%ProgramFiles(x86)%\Git\cmd;%PATH%"
|
||||
if exist "%LOCALAPPDATA%\Programs\Git\cmd\git.exe" set "PATH=%LOCALAPPDATA%\Programs\Git\cmd;%PATH%"
|
||||
where git >nul 2>&1
|
||||
if not errorlevel 1 (
|
||||
echo [ok] git ^(found off PATH, added for this run^)
|
||||
goto :git_done
|
||||
)
|
||||
if not errorlevel 1 goto :git_found_offpath
|
||||
if "%GIT_TRIED%"=="1" goto :git_missing
|
||||
where winget >nul 2>&1
|
||||
if errorlevel 1 goto :git_missing
|
||||
echo.
|
||||
echo [--] Git is not installed.
|
||||
set "DOIT="
|
||||
set /p "DOIT= Install it now with winget? [Y/n] "
|
||||
if /i "%DOIT%"=="n" goto :git_missing
|
||||
set "GIT_TRIED=1"
|
||||
echo Installing Git ^(a UAC prompt may appear^)...
|
||||
winget install --id Git.Git -e --source winget --accept-source-agreements --accept-package-agreements --silent
|
||||
goto :git_probe
|
||||
|
||||
:git_found_offpath
|
||||
echo [ok] git ^(found off PATH, added for this run^)
|
||||
goto :git_done
|
||||
|
||||
:git_missing
|
||||
echo [X] Git not found on PATH, and not in any of:
|
||||
echo %ProgramFiles%\Git\cmd
|
||||
echo %LOCALAPPDATA%\Programs\Git\cmd
|
||||
echo.
|
||||
echo If Git is NOT installed: https://git-scm.com/download/win
|
||||
echo Install it from https://git-scm.com/download/win
|
||||
echo If you JUST installed it: close this window, open a new Command
|
||||
echo Prompt and run the script again - an open window keeps its old PATH.
|
||||
echo If it is installed elsewhere: check with where git
|
||||
goto :fail
|
||||
:git_ok
|
||||
echo [ok] git
|
||||
|
||||
:git_done
|
||||
echo [ok] git
|
||||
|
||||
REM --------------------------------------------------------------- node check
|
||||
REM winget's LTS package is deliberate: better-sqlite3 publishes prebuilt
|
||||
REM binaries for LTS Node, so installing LTS sidesteps the node-gyp build.
|
||||
:node_probe
|
||||
where node >nul 2>&1
|
||||
if not errorlevel 1 goto :node_found
|
||||
if exist "%ProgramFiles%\nodejs\node.exe" set "PATH=%ProgramFiles%\nodejs;%PATH%"
|
||||
if exist "%LOCALAPPDATA%\Programs\nodejs\node.exe" set "PATH=%LOCALAPPDATA%\Programs\nodejs;%PATH%"
|
||||
where node >nul 2>&1
|
||||
if not errorlevel 1 goto :node_found
|
||||
if "%NODE_TRIED%"=="1" goto :node_missing
|
||||
where winget >nul 2>&1
|
||||
if errorlevel 1 goto :node_missing
|
||||
echo.
|
||||
echo [--] Node.js is not installed.
|
||||
set "DOIT="
|
||||
set /p "DOIT= Install Node 22 LTS now with winget? [Y/n] "
|
||||
if /i "%DOIT%"=="n" goto :node_missing
|
||||
set "NODE_TRIED=1"
|
||||
echo Installing Node LTS ^(a UAC prompt may appear^)...
|
||||
winget install --id OpenJS.NodeJS.LTS -e --source winget --accept-source-agreements --accept-package-agreements --silent
|
||||
goto :node_probe
|
||||
|
||||
:node_missing
|
||||
echo [X] Node.js not found on PATH, and not in any of:
|
||||
echo %ProgramFiles%\nodejs
|
||||
echo %LOCALAPPDATA%\Programs\nodejs
|
||||
echo.
|
||||
echo Install Node 22 LTS from https://nodejs.org/ then re-run.
|
||||
echo If you JUST installed it, open a NEW Command Prompt first.
|
||||
goto :fail
|
||||
|
||||
:node_found
|
||||
if exist "%ProgramFiles%\nodejs\node.exe" set "PATH=%ProgramFiles%\nodejs;%PATH%"
|
||||
if exist "%LOCALAPPDATA%\Programs\nodejs\node.exe" set "PATH=%LOCALAPPDATA%\Programs\nodejs;%PATH%"
|
||||
where node >nul 2>&1
|
||||
if not errorlevel 1 goto :node_found
|
||||
echo [X] Node.js not found on PATH, and not in any of:
|
||||
echo %ProgramFiles%\nodejs
|
||||
echo %LOCALAPPDATA%\Programs\nodejs
|
||||
@@ -84,15 +130,40 @@ if /i not "%GOON%"=="y" goto :fail
|
||||
:node_ok
|
||||
|
||||
REM ------------------------------------------------------------------- python
|
||||
where python >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [--] python not found - the dashboard will still work.
|
||||
echo Needed only for the clicker ^(clicker\runner.py^).
|
||||
set "HAVE_PY=0"
|
||||
) else (
|
||||
echo [ok] python
|
||||
set "HAVE_PY=1"
|
||||
)
|
||||
REM Only the clicker needs Python; the dashboard runs without it.
|
||||
REM
|
||||
REM Detection is deliberately "run it and see" rather than `where python`:
|
||||
REM Windows ships a stub python.exe in WindowsApps that only opens the Microsoft
|
||||
REM Store. `where` finds it, running it does nothing useful. Asking it to print
|
||||
REM its major version separates a real interpreter from the stub. The py
|
||||
REM launcher is preferred when present - it is not shadowed by the stub.
|
||||
:py_probe
|
||||
set "PYCMD="
|
||||
for /f "tokens=*" %%v in ('py -3 -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=py -3"
|
||||
if not defined PYCMD for /f "tokens=*" %%v in ('python -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=python"
|
||||
if defined PYCMD goto :py_found
|
||||
if "%PY_TRIED%"=="1" goto :py_skip
|
||||
where winget >nul 2>&1
|
||||
if errorlevel 1 goto :py_skip
|
||||
echo.
|
||||
echo [--] Python is not installed ^(needed only for the clicker^).
|
||||
set "DOIT="
|
||||
set /p "DOIT= Install Python 3.12 now with winget? [Y/n] "
|
||||
if /i "%DOIT%"=="n" goto :py_skip
|
||||
set "PY_TRIED=1"
|
||||
echo Installing Python ^(a UAC prompt may appear^)...
|
||||
winget install --id Python.Python.3.12 -e --source winget --accept-source-agreements --accept-package-agreements --silent
|
||||
goto :py_probe
|
||||
|
||||
:py_skip
|
||||
echo [--] python not found - the dashboard will still work.
|
||||
echo Needed only for the clicker ^(clicker\runner.py^).
|
||||
goto :py_end
|
||||
|
||||
:py_found
|
||||
for /f "tokens=*" %%v in ('%PYCMD% -c "import sys;print(sys.version.split()[0])" 2^>nul') do set "PYVER=%%v"
|
||||
echo [ok] python %PYVER% ^(via "%PYCMD%"^)
|
||||
:py_end
|
||||
|
||||
REM ------------------------------------------------------------------- prompts
|
||||
echo.
|
||||
@@ -169,17 +240,29 @@ if errorlevel 1 (
|
||||
)
|
||||
|
||||
REM ------------------------------------------------------ python deps (option)
|
||||
if "%HAVE_PY%"=="1" (
|
||||
echo.
|
||||
echo [5/5] Installing clicker Python dependencies...
|
||||
python -m pip install --quiet --disable-pip-version-check -r clicker\requirements.txt
|
||||
if errorlevel 1 (
|
||||
echo [!] pip install failed - the dashboard still works, the clicker will not.
|
||||
)
|
||||
) else (
|
||||
echo.
|
||||
echo [5/5] Skipping Python dependencies ^(python not found^).
|
||||
)
|
||||
echo.
|
||||
if not defined PYCMD goto :deps_skip
|
||||
echo [5/5] Installing clicker Python dependencies...
|
||||
REM requirements.txt guards its pyobjc entries with sys_platform == "darwin",
|
||||
REM so on Windows this resolves to pyautogui and its wheels only.
|
||||
%PYCMD% -m pip install --upgrade --quiet --disable-pip-version-check pip
|
||||
%PYCMD% -m pip install --quiet --disable-pip-version-check -r clicker\requirements.txt
|
||||
if errorlevel 1 goto :deps_failed
|
||||
%PYCMD% -c "import pyautogui" 2>nul
|
||||
if errorlevel 1 goto :deps_failed
|
||||
echo pyautogui imports cleanly.
|
||||
goto :deps_done
|
||||
|
||||
:deps_failed
|
||||
echo [!] Python dependency install failed - the dashboard still works,
|
||||
echo the clicker will not. Retry by hand with:
|
||||
echo %PYCMD% -m pip install -r clicker\requirements.txt
|
||||
goto :deps_done
|
||||
|
||||
:deps_skip
|
||||
echo [5/5] Skipping Python dependencies ^(python not found^).
|
||||
|
||||
:deps_done
|
||||
|
||||
REM ---------------------------------------------------------------- start file
|
||||
> "%~dp0start-autofirmer.bat" (
|
||||
|
||||
Reference in New Issue
Block a user