Files
alexandClaude Opus 5 5926967270 Инсталлятор: убрана кириллица, ломавшая его на запуске
cmd.exe читает .cmd в системной кодировке, поэтому русские комментарии rem
превращались в мусор, и cmd пытался выполнять обрывки строк как команды.
Правило «в батниках только ASCII» уже было записано в шапке файла — и всё
равно нарушено, поэтому теперь его проверяют тесты: любой .cmd проекта
обязан быть чистым ASCII.

Ещё две правки по итогам установки с нуля в чистой папке:
- запись .env вынесена из блока if/else в метки: cmd неверно разбирает блок,
  внутри которого есть rem-строки и вызов PowerShell с переносами через ^,
  и сообщает только «The syntax of the command is incorrect»;
- запуск приложения в конце идёт по полному пути, а не по имени start.cmd —
  относительное имя разрешается не во всех оболочках.

Проверено установкой с нуля: клонирование анонимно из публичного
репозитория, venv, зависимости, .env с выбранным адресом, ярлык на рабочем
столе. Личные данные в архив не попадают — ни базы, ни фотографий, ни .env.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 16:58:10 +03:00

198 lines
6.8 KiB
Batchfile

@echo off
rem ============================================================
rem hlamingo installer
rem
rem Downloads the app and sets up everything needed to run it.
rem Put this file in an empty folder and double-click it.
rem
rem ASCII only: cmd.exe reads .cmd in the system codepage, so Cyrillic here
rem would turn into garbage and break the script. Russian text is printed
rem from Python instead.
rem ============================================================
setlocal
chcp 65001 >nul
cls
set REPO_WEB=https://git.08h.ru/alex/hlamingo
set REPO_GIT=https://git.08h.ru/alex/hlamingo.git
set BRANCH=main
set TARGET=hlamingo
echo ========================================
echo hlamingo - installer
echo ========================================
echo.
echo Source: %REPO_WEB%
echo Target: %CD%\%TARGET%
echo.
cd /d "%~dp0"
rem ---------- 1. Python ----------
where python >nul 2>&1
if errorlevel 1 (
echo [ERROR] Python not found in PATH.
echo.
echo Install Python 3.9 or newer from https://www.python.org/downloads/
echo IMPORTANT: check "Add python.exe to PATH" in the installer.
echo Then run this file again.
pause
exit /b 1
)
for /f "delims=" %%v in ('python -c "import sys;print(sys.version.split()[0])"') do set PYVER=%%v
echo [1/4] Python %PYVER% found.
rem ---------- 2. Download ----------
if exist "%TARGET%\hlamingo\app.py" goto :update
where git >nul 2>&1
if errorlevel 1 goto :download_zip
echo [2/4] Cloning with git...
git clone --branch %BRANCH% "%REPO_GIT%" "%TARGET%"
if errorlevel 1 (
echo git clone failed, falling back to zip download.
goto :download_zip
)
goto :setup
:download_zip
echo [2/4] Downloading archive (git not available or clone failed)...
rem PowerShell does the work: no curl/tar dependency on older Windows.
rem Make sure we actually got an archive: a server that requires signing in
rem answers with an HTML login page, and unpacking would fail confusingly.
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"$ErrorActionPreference='Stop';" ^
"$url='%REPO_WEB%/archive/%BRANCH%.zip';" ^
"$zip=Join-Path $env:TEMP 'hlamingo-src.zip';" ^
"$tmp=Join-Path $env:TEMP 'hlamingo-unpack';" ^
"Write-Host (' ' + $url);" ^
"Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue;" ^
"if (-not (Test-Path $zip)) { throw 'server returned nothing' }" ^
"$head=[IO.File]::ReadAllBytes($zip) | Select-Object -First 2;" ^
"if ($head[0] -ne 0x50 -or $head[1] -ne 0x4B) { Remove-Item $zip -Force; throw 'the server sent a web page instead of an archive - the repository is private or requires signing in' }" ^
"if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }" ^
"Expand-Archive -Path $zip -DestinationPath $tmp -Force;" ^
"$root=Get-ChildItem $tmp -Directory | Select-Object -First 1;" ^
"if (-not $root) { throw 'archive looks empty' }" ^
"Move-Item $root.FullName (Join-Path (Get-Location) '%TARGET%');" ^
"Remove-Item -Recurse -Force $tmp, $zip"
if errorlevel 1 (
echo.
echo [ERROR] Download failed.
echo.
echo Possible reasons:
echo - %REPO_WEB% is not reachable from this computer;
echo - the repository is private, or the server requires signing in
echo to view anything. In that case download the project manually
echo and run setup.cmd inside it.
pause
exit /b 1
)
goto :setup
:update
echo [2/4] Already downloaded - updating.
where git >nul 2>&1
if not errorlevel 1 (
if exist "%TARGET%\.git" (
pushd "%TARGET%"
git pull --ff-only
popd
)
)
rem ---------- 3. venv and dependencies ----------
:setup
if not exist "%TARGET%\requirements.txt" (
echo [ERROR] Download looks incomplete: requirements.txt is missing.
pause
exit /b 1
)
pushd "%TARGET%"
echo [3/4] Creating virtual environment and installing dependencies...
if not exist "venv" python -m venv venv
if errorlevel 1 (
echo [ERROR] Could not create venv.
popd
pause
exit /b 1
)
venv\Scripts\python.exe -m pip install --upgrade pip --quiet
venv\Scripts\python.exe -m pip install -r requirements.txt --quiet
if errorlevel 1 (
echo [ERROR] Dependency installation failed.
popd
pause
exit /b 1
)
rem ---------- 4. Ollama address ----------
echo.
echo [4/4] Where is Ollama running?
echo Enter to accept the default (this computer).
echo Otherwise type the address of the machine on your network,
echo for example: http://192.168.1.50:11434
echo.
set OLLAMA_ADDR=
set /p OLLAMA_ADDR="Ollama URL [http://localhost:11434]: "
if "%OLLAMA_ADDR%"=="" set OLLAMA_ADDR=http://localhost:11434
rem Build the local config from the example file, so the user sees the other
rem settings with explanations next to the Ollama address.
rem
rem Done with labels, not an if/else block: cmd mis-parses a block that holds
rem rem-lines and a caret-continued PowerShell call, and reports only
rem "The syntax of the command is incorrect".
if exist ".env" goto :env_exists
rem -Encoding UTF8 is required: without it PowerShell 5.1 reads the file in the
rem system codepage and the Russian comments turn into mojibake.
powershell -NoProfile -Command ^
"$src = if (Test-Path '.env.example') { Get-Content '.env.example' -Encoding UTF8 } else { @('OLLAMA_HOST=') };" ^
"$out = $src -replace '^\s*#?\s*OLLAMA_HOST=.*', 'OLLAMA_HOST=%OLLAMA_ADDR%';" ^
"if (-not ($out -match '^OLLAMA_HOST=')) { $out += 'OLLAMA_HOST=%OLLAMA_ADDR%' }" ^
"Set-Content -Path '.env' -Value $out -Encoding UTF8"
if not exist ".env" echo OLLAMA_HOST=%OLLAMA_ADDR%>.env
echo Saved to .env: OLLAMA_HOST=%OLLAMA_ADDR%
goto :env_done
:env_exists
echo .env already exists - left as is. Edit it by hand if needed.
:env_done
rem Check whether Ollama actually answers, and report in plain language.
venv\Scripts\python.exe -c "from hlamingo import ollama, config; print(' Ollama ' + config.OLLAMA_HOST + (' otvechaet.' if ollama.check() else ' NE otvechaet - prilozhenie zapustitsya, no bez razbora fraz.'))"
echo.
echo ========================================
echo Done.
echo ========================================
echo.
echo Start the app: %CD%\start.cmd
echo Run tests: %CD%\tests\run.cmd
echo.
echo A shortcut named "hlamingo" is on your Desktop.
powershell -NoProfile -Command ^
"$s=(New-Object -ComObject WScript.Shell).CreateShortcut([IO.Path]::Combine([Environment]::GetFolderPath('Desktop'),'hlamingo.lnk'));" ^
"$s.TargetPath=(Join-Path (Get-Location) 'start.cmd');" ^
"$s.WorkingDirectory=(Get-Location).Path;" ^
"$s.Description='hlamingo - where my stuff is';" ^
"$s.Save()" 2>nul
popd
echo.
set RUNNOW=
set /p RUNNOW="Start it now? [Y/n]: "
if /i "%RUNNOW%"=="n" goto :end
rem Full path, not a bare name: depending on the shell that launched the
rem installer, a relative .cmd name may not resolve.
pushd "%TARGET%"
call "%CD%\start.cmd"
popd
:end
endlocal