Инсталлятор: убрана кириллица, ломавшая его на запуске
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>
This commit is contained in:
+29
-21
@@ -59,8 +59,8 @@ goto :setup
|
|||||||
:download_zip
|
:download_zip
|
||||||
echo [2/4] Downloading archive (git not available or clone failed)...
|
echo [2/4] Downloading archive (git not available or clone failed)...
|
||||||
rem PowerShell does the work: no curl/tar dependency on older Windows.
|
rem PowerShell does the work: no curl/tar dependency on older Windows.
|
||||||
rem Проверяем, что скачался именно архив: сервер, требующий входа, отдаёт
|
rem Make sure we actually got an archive: a server that requires signing in
|
||||||
rem HTML-страницу логина с кодом 200, и распаковка падала бы невнятно.
|
rem answers with an HTML login page, and unpacking would fail confusingly.
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||||
"$ErrorActionPreference='Stop';" ^
|
"$ErrorActionPreference='Stop';" ^
|
||||||
"$url='%REPO_WEB%/archive/%BRANCH%.zip';" ^
|
"$url='%REPO_WEB%/archive/%BRANCH%.zip';" ^
|
||||||
@@ -139,26 +139,32 @@ set OLLAMA_ADDR=
|
|||||||
set /p OLLAMA_ADDR="Ollama URL [http://localhost:11434]: "
|
set /p OLLAMA_ADDR="Ollama URL [http://localhost:11434]: "
|
||||||
if "%OLLAMA_ADDR%"=="" set OLLAMA_ADDR=http://localhost:11434
|
if "%OLLAMA_ADDR%"=="" set OLLAMA_ADDR=http://localhost:11434
|
||||||
|
|
||||||
rem Локальный конфиг делаем из образца: рядом с адресом Ollama человек увидит
|
rem Build the local config from the example file, so the user sees the other
|
||||||
rem и остальные настройки с пояснениями, а не одну голую строку.
|
rem settings with explanations next to the Ollama address.
|
||||||
if exist ".env" (
|
rem
|
||||||
echo .env already exists - left as is. Edit it by hand if needed.
|
rem Done with labels, not an if/else block: cmd mis-parses a block that holds
|
||||||
) else (
|
rem rem-lines and a caret-continued PowerShell call, and reports only
|
||||||
rem -Encoding UTF8 обязателен: без него PowerShell 5.1 читает файл в
|
rem "The syntax of the command is incorrect".
|
||||||
rem системной кодировке, и русские пояснения превращаются в кракозябры.
|
if exist ".env" goto :env_exists
|
||||||
powershell -NoProfile -Command ^
|
|
||||||
"$src = if (Test-Path '.env.example') { Get-Content '.env.example' -Encoding UTF8 } else { @('OLLAMA_HOST=') };" ^
|
rem -Encoding UTF8 is required: without it PowerShell 5.1 reads the file in the
|
||||||
"$out = $src -replace '^\s*#?\s*OLLAMA_HOST=.*', 'OLLAMA_HOST=%OLLAMA_ADDR%';" ^
|
rem system codepage and the Russian comments turn into mojibake.
|
||||||
"if (-not ($out -match '^OLLAMA_HOST=')) { $out += 'OLLAMA_HOST=%OLLAMA_ADDR%' }" ^
|
powershell -NoProfile -Command ^
|
||||||
"Set-Content -Path '.env' -Value $out -Encoding UTF8"
|
"$src = if (Test-Path '.env.example') { Get-Content '.env.example' -Encoding UTF8 } else { @('OLLAMA_HOST=') };" ^
|
||||||
if errorlevel 1 (
|
"$out = $src -replace '^\s*#?\s*OLLAMA_HOST=.*', 'OLLAMA_HOST=%OLLAMA_ADDR%';" ^
|
||||||
> .env echo OLLAMA_HOST=%OLLAMA_ADDR%
|
"if (-not ($out -match '^OLLAMA_HOST=')) { $out += 'OLLAMA_HOST=%OLLAMA_ADDR%' }" ^
|
||||||
)
|
"Set-Content -Path '.env' -Value $out -Encoding UTF8"
|
||||||
echo Saved to .env ^(OLLAMA_HOST=%OLLAMA_ADDR%^)
|
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.
|
rem Check whether Ollama actually answers, and report in plain language.
|
||||||
venv\Scripts\python.exe -c "from hlamingo import ollama, config; ok=ollama.check(); print((' Ollama ' + config.OLLAMA_HOST + (' отвечает.' if ok else ' НЕ отвечает — приложение будет работать, но без разбора фраз и поиска по смыслу.')))"
|
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 ========================================
|
echo ========================================
|
||||||
@@ -181,8 +187,10 @@ echo.
|
|||||||
set RUNNOW=
|
set RUNNOW=
|
||||||
set /p RUNNOW="Start it now? [Y/n]: "
|
set /p RUNNOW="Start it now? [Y/n]: "
|
||||||
if /i "%RUNNOW%"=="n" goto :end
|
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%"
|
pushd "%TARGET%"
|
||||||
call start.cmd
|
call "%CD%\start.cmd"
|
||||||
popd
|
popd
|
||||||
|
|
||||||
:end
|
:end
|
||||||
|
|||||||
@@ -177,6 +177,20 @@ config.DB_FILE.write_text("{ битый json", encoding="utf-8")
|
|||||||
r.check("битая база не роняет", c.get("/api/tree").status_code == 200)
|
r.check("битая база не роняет", c.get("/api/tree").status_code == 200)
|
||||||
r.check("пустой ввод не роняет", "reply" in j("POST", "/api/say", text=" "))
|
r.check("пустой ввод не роняет", "reply" in j("POST", "/api/say", text=" "))
|
||||||
|
|
||||||
|
print("\n== Батники: только ASCII ==")
|
||||||
|
# cmd.exe читает .cmd в системной кодировке. Кириллица внутри — даже
|
||||||
|
# в комментарии rem — превращается в мусор, и cmd пытается выполнить обрывки
|
||||||
|
# как команды. На этом уже дважды ломался инсталлятор.
|
||||||
|
import pathlib # noqa: E402
|
||||||
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
for cmd_file in sorted(root.rglob("*.cmd")):
|
||||||
|
if "venv" in cmd_file.parts:
|
||||||
|
continue
|
||||||
|
lines = cmd_file.read_text(encoding="utf-8").splitlines()
|
||||||
|
bad = [(n, l) for n, l in enumerate(lines, 1) if any(ord(ch) > 127 for ch in l)]
|
||||||
|
r.check("%s без не-ASCII" % cmd_file.relative_to(root), not bad,
|
||||||
|
bad[0] if bad else "")
|
||||||
|
|
||||||
print("\n== Настройки из браузера ==")
|
print("\n== Настройки из браузера ==")
|
||||||
d = c.get("/api/config").get_json()
|
d = c.get("/api/config").get_json()
|
||||||
r.check("отдаёт текущие", d.get("ollama_host") and d.get("chat_model"), d)
|
r.check("отдаёт текущие", d.get("ollama_host") and d.get("chat_model"), d)
|
||||||
|
|||||||
Reference in New Issue
Block a user