Thư mục gốc: 22 file .py -> 7
--------------------------------
13 file "thành phần" nằm rải rác ngay ngoài thư mục gốc, mỗi file chỉ có ĐÚNG
MỘT nơi import — chính cái hub của nó:
i18n.py + 10 file i18n_*.py -> i18n/__init__.py + i18n/*.py
theme.py + 3 file theme_*.py -> theme/__init__.py + theme/*.py
Đổi hub thành `__init__.py` nên 78 chỗ `from ..i18n import tr` và 24 chỗ
`from ..theme import current_palette` KHÔNG phải sửa một dòng nào. Git nhận ra
11/15 file là đổi tên thuần, 0 dòng thay đổi; 4 file còn lại chỉ sửa đúng dòng
import và mấy tham chiếu tên file trong docstring.
Đối chiếu với bản trước khi gom, cùng một phép băm:
số khoá i18n 1431 -> 1431 hash STRINGS a06cc34b... (trùng)
QSS dark hash 7bb230a4... (trùng)
QSS light hash 884f73ce... (trùng)
`check_loc.py` phải khai thêm "i18n", "theme" vào DEFAULT_TARGET_DIRS: chúng
từng được quét theo diện "module nằm ở thư mục gốc", gom vào gói rồi thì không
khai là lặng lẽ tuột khỏi tầm quét.
Bánh cóc `ui/widgets.py` siết 505 -> 466 sau khi tách SegmentedControl — nợ cũ
co lại thì con số phải co theo, không thì bánh cóc đứng yên mãi ở mức cũ.
Một file requirements
---------------------
Xoá `requirements-test.txt`. Nó chỉ có `pytest` + `pydantic`, nhưng 64/108 file
test dựng widget thật và 20 file trong đó import PySide6 thẳng ở đầu file không
có bảo vệ — nên CI cài mỗi file kia thì pytest chết ngay lúc thu thập test chứ
không phải "vài test bị bỏ qua". Hai file cho một danh sách gần trùng nhau chỉ
tạo thêm một chỗ để lệch phiên bản, và `pydantic` đã bị chép ở cả hai.
CI đổi sang cài `requirements.txt`. Người dùng cuối cài thừa pytest vài MB.
Kèm theo: `install.bat` bỏ cờ `--dev` (không còn gì để cài thêm). Khối `if`
rỗng còn sót lại làm cmd.exe báo "( was unexpected at this time" và script chết
ngay sau bước cài thư viện — đã gỡ hẳn.
859 test xanh · 4/4 cổng CASAN · check_design_parity 32/32 ·
check_layout_geometry trùng từng byte với bản trước refactor.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
193 lines
7.0 KiB
Batchfile
193 lines
7.0 KiB
Batchfile
@echo off
|
|
rem ===========================================================================
|
|
rem Cowork-Local BamBOO - cai dat thu vien Python (chay MOT lan)
|
|
rem
|
|
rem Cach dung:
|
|
rem install.bat cai vao moi truong ao rieng (khuyen dung)
|
|
rem install.bat --system cai thang vao Python dang co, khong dung venv
|
|
rem install.bat --force dung lai moi truong ao tu dau
|
|
rem
|
|
rem Cai gi va cai o dau:
|
|
rem %LOCALAPPDATA%\CoworkLocal\venv moi truong ao
|
|
rem %LOCALAPPDATA%\CoworkLocal\launcher lien ket de import duoc goi
|
|
rem
|
|
rem Vi sao KHONG dat venv trong repo: cac cong chat luong
|
|
rem (scripts/check_orphan_modules.py, check_imports.py) quet TOAN BO cay thu
|
|
rem muc chu khong doc .gitignore, nen mot thu muc .venv o day se bien vai nghin
|
|
rem module cua thu vien thanh "ma production khong ai import" va lam cong do.
|
|
rem ===========================================================================
|
|
setlocal EnableExtensions EnableDelayedExpansion
|
|
chcp 65001 >nul 2>&1
|
|
|
|
set "REPO=%~dp0"
|
|
set "REPO=%REPO:~0,-1%"
|
|
set "APPHOME=%LOCALAPPDATA%\CoworkLocal"
|
|
set "VENV=%APPHOME%\venv"
|
|
set "LAUNCHER=%APPHOME%\launcher"
|
|
|
|
set "USE_SYSTEM=0"
|
|
set "FORCE=0"
|
|
|
|
:parse_args
|
|
if "%~1"=="" goto args_done
|
|
if /I "%~1"=="--system" set "USE_SYSTEM=1" & shift & goto parse_args
|
|
if /I "%~1"=="--force" set "FORCE=1" & shift & goto parse_args
|
|
if /I "%~1"=="-h" goto usage
|
|
if /I "%~1"=="--help" goto usage
|
|
echo [LOI] Khong hieu tham so: %~1
|
|
goto usage
|
|
:args_done
|
|
|
|
echo.
|
|
echo ===========================================================================
|
|
echo Cowork-Local BamBOO — cài đặt
|
|
echo ===========================================================================
|
|
echo Mã nguồn : %REPO%
|
|
echo Cài vào : %APPHOME%
|
|
echo.
|
|
|
|
rem --------------------------------------------------------------------------
|
|
rem 1. Tim Python
|
|
rem
|
|
rem Uu tien "py -3" chu khong phai "python": tren Windows 11, python.exe trong
|
|
rem WindowsApps thuong chi la lien ket mo Microsoft Store chu khong phai
|
|
rem Python that.
|
|
rem --------------------------------------------------------------------------
|
|
set "PY="
|
|
py -3 -c "import sys" >nul 2>&1 && set "PY=py -3"
|
|
if not defined PY (
|
|
python -c "import sys" >nul 2>&1 && set "PY=python"
|
|
)
|
|
if not defined PY (
|
|
echo [LỖI] Không tìm thấy Python trên máy này.
|
|
echo Cài Python 3.11 trở lên từ https://www.python.org/downloads/
|
|
echo và nhớ tích "Add python.exe to PATH" khi cài.
|
|
goto fail
|
|
)
|
|
|
|
for /f "delims=" %%V in ('%PY% -c "import sys;print('%%d.%%d'%%sys.version_info[:2])" 2^>nul') do set "PYVER=%%V"
|
|
echo [1/5] Python %PYVER% (%PY%)
|
|
|
|
%PY% -c "import sys;raise SystemExit(0 if sys.version_info>=(3,11) else 1)" >nul 2>&1
|
|
if errorlevel 1 (
|
|
echo [LỖI] Cần Python 3.11 trở lên, máy đang có %PYVER%.
|
|
goto fail
|
|
)
|
|
|
|
rem --------------------------------------------------------------------------
|
|
rem 2. Moi truong ao
|
|
rem --------------------------------------------------------------------------
|
|
if "%USE_SYSTEM%"=="1" (
|
|
echo [2/5] Bỏ qua môi trường ảo — cài thẳng vào Python đang có ^(--system^)
|
|
set "PIP=%PY% -m pip"
|
|
goto deps
|
|
)
|
|
|
|
if "%FORCE%"=="1" if exist "%VENV%" (
|
|
echo [2/5] Xoá môi trường ảo cũ...
|
|
rmdir /s /q "%VENV%" 2>nul
|
|
)
|
|
|
|
if exist "%VENV%\Scripts\python.exe" (
|
|
echo [2/5] Môi trường ảo đã có — dùng lại
|
|
) else (
|
|
echo [2/5] Tạo môi trường ảo...
|
|
%PY% -m venv "%VENV%"
|
|
if errorlevel 1 (
|
|
echo [LỖI] Không tạo được môi trường ảo.
|
|
echo Thử lại với: install.bat --system
|
|
goto fail
|
|
)
|
|
)
|
|
set "PIP="%VENV%\Scripts\python.exe" -m pip"
|
|
|
|
rem --------------------------------------------------------------------------
|
|
rem 3. Cai thu vien
|
|
rem --------------------------------------------------------------------------
|
|
:deps
|
|
echo [3/5] Cập nhật pip...
|
|
%PIP% install --disable-pip-version-check --quiet --upgrade pip
|
|
if errorlevel 1 echo ^(bỏ qua — pip cũ vẫn dùng được^)
|
|
|
|
echo [3/5] Cài thư viện từ requirements.txt ^(PySide6 khá nặng, chờ vài phút^)...
|
|
%PIP% install --disable-pip-version-check -r "%REPO%\requirements.txt"
|
|
if errorlevel 1 (
|
|
echo [LỖI] Cài thư viện thất bại.
|
|
echo Nếu máy qua proxy công ty, đặt biến môi trường HTTPS_PROXY rồi chạy lại.
|
|
goto fail
|
|
)
|
|
|
|
rem --------------------------------------------------------------------------
|
|
rem 4. Lien ket de goi import duoc dung ten
|
|
rem
|
|
rem Ma nguon phai import duoc duoi dung ten "cowork_local". Thu muc nay ten la
|
|
rem "%~nx0"'s parent — neu no khong phai "cowork_local" thi ca
|
|
rem "python -m cowork_local" lan "python __main__.py" deu bao
|
|
rem ModuleNotFoundError, va tien trinh con chay may chu MCP MS365
|
|
rem (state.py: python -m cowork_local.mcp_servers.ms365_server) cung hong theo.
|
|
rem
|
|
rem Junction giai quyet ca hai ma khong phai doi ten thu muc lam viec, khong
|
|
rem phai sua mot dong code nao, va khong can quyen quan tri.
|
|
rem --------------------------------------------------------------------------
|
|
for %%I in ("%REPO%") do set "REPO_NAME=%%~nxI"
|
|
if /I "%REPO_NAME%"=="cowork_local" (
|
|
echo [4/5] Thư mục đã đúng tên "cowork_local" — không cần liên kết
|
|
goto smoke
|
|
)
|
|
|
|
if not exist "%LAUNCHER%" mkdir "%LAUNCHER%" >nul 2>&1
|
|
if exist "%LAUNCHER%\cowork_local" rmdir "%LAUNCHER%\cowork_local" >nul 2>&1
|
|
mklink /J "%LAUNCHER%\cowork_local" "%REPO%" >nul
|
|
if errorlevel 1 (
|
|
echo [LỖI] Không tạo được liên kết thư mục.
|
|
echo Thư mục "%REPO_NAME%" không phải tên gói Python hợp lệ nên
|
|
echo ứng dụng không import được chính nó. Cách khác: đổi tên thư mục
|
|
echo mã nguồn thành "cowork_local".
|
|
goto fail
|
|
)
|
|
echo [4/5] Đã tạo liên kết: %LAUNCHER%\cowork_local
|
|
|
|
rem --------------------------------------------------------------------------
|
|
rem 5. Chay thu mot lan
|
|
rem --------------------------------------------------------------------------
|
|
:smoke
|
|
if "%USE_SYSTEM%"=="1" (set "RUNPY=%PY%") else (set "RUNPY="%VENV%\Scripts\python.exe"")
|
|
if /I "%REPO_NAME%"=="cowork_local" (
|
|
for %%I in ("%REPO%\..") do set "PKGPATH=%%~fI"
|
|
) else (
|
|
set "PKGPATH=%LAUNCHER%"
|
|
)
|
|
|
|
echo [5/5] Kiểm tra lại...
|
|
set "PYTHONPATH=!PKGPATH!"
|
|
%RUNPY% -c "import cowork_local, PySide6; print(' cowork_local + PySide6 nạp được')"
|
|
if errorlevel 1 (
|
|
echo [LỖI] Cài xong nhưng vẫn chưa import được gói.
|
|
goto fail
|
|
)
|
|
|
|
echo.
|
|
echo ===========================================================================
|
|
echo XONG. Từ giờ chỉ cần bấm đúp vào run.bat
|
|
echo ===========================================================================
|
|
echo.
|
|
pause
|
|
exit /b 0
|
|
|
|
:usage
|
|
echo.
|
|
echo install.bat [--system] [--force]
|
|
echo.
|
|
echo --system cài thẳng vào Python đang có, không tạo môi trường ảo
|
|
echo --force xoá môi trường ảo cũ rồi tạo lại từ đầu
|
|
echo.
|
|
pause
|
|
exit /b 2
|
|
|
|
:fail
|
|
echo.
|
|
echo Cài đặt KHÔNG thành công. Xem thông báo lỗi ở trên.
|
|
echo.
|
|
pause
|
|
exit /b 1
|