Windows: official port -- UCRT static build, UTF-8 throughout, Low IL sandbox, ncurses TUI, installer; v0.6.0
Build
* cross build switches to pkgsCross.ucrt64 (shell-win.nix); curl (Schannel),
winpthreads and ncurses 6.6 are linked statically, so the release is
cst-agent.exe + busybox.exe (busybox-w32 Unicode) with no extra DLLs
* windres embeds a manifest with activeCodePage=UTF-8 and a version resource
* ncurses 6.6 Windows console driver patches (mouse button state, A_DIM,
wide-char declarations): scripts/patches/
* scripts/bootstrap_msys2.sh builds the same release natively in MSYS2
UCRT64; PR #1's MINGW64 notes now point there
* vendor/tre-regex (musl's TRE) provides <regex.h> on MinGW
UTF-8
* paths cross the system call boundary as UTF-16 (*W APIs); console code
pages set to 65001 and restored on exit; files are read and written in
binary mode
* child output that is not valid UTF-8 is decoded from the console, OEM or
ANSI system code page
* read_file hides CR; edit_file, apply_patch and write_file keep CRLF line
endings and a UTF-8 BOM
OS layer and processes
* os_dir_* and cst_fnmatch replace the POSIX-only directory walks in
subagent, plugins, skills, undo and fs_tools; realpath / path_under and
symlink rejection work on Windows
* every child goes through CreateProcessW with its own environment block
inside a Job Object, so timeouts and Esc end the whole process tree
Sandbox (auto mode, "auto · lowil")
* run_shell runs with a restricted Low integrity token; the workspace gets
an inheritable Low label once, the sandbox TEMP is labeled Low, and the
credentials file gets a no-read-up label
* drive roots, the profile and system folders are never labeled
* network commands still ask, since Low IL does not block the network;
Access denied and MSYS2's 0xc0000142 offer a rerun outside the sandbox
* /sandbox lists labeled folders, /sandbox reset-labels restores them
TUI
* raster console fonts are switched to Consolas / NSimSun while running
* the home logo falls back to text when the console font lacks U+2580
* mouse drag copy goes to the Windows clipboard
Distribution
* scripts/install_windows.ps1 installs a Gitea release into
%LOCALAPPDATA%\Programs\cst-agent and adds it to the user PATH;
cst-agent-update.cmd reruns it; scripts/release_windows.sh uploads the
zip with the token taken from the environment
* scripts/run_windows.bat is gone; docs/README-windows.md is rewritten
Tests
* new test_lowil, test_win_utf8 and test_os_dir; tests made portable
(cst_test_util.h)
* scripts/win_test.sh and scripts/winvm/ run the suite on English and
Chinese Windows Server VMs as Administrator, a standard user and a
Chinese user name: 29/29 on all six
This commit is contained in:
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the cross-built Windows tests inside the test VMs (scripts/winvm/vm.sh).
|
||||
#
|
||||
# scripts/win_test.sh [-b BUILD_DIR] [-v "en zh"] [-u "Administrator tester 测试"] [-f FILTER]
|
||||
#
|
||||
# BUILD_DIR (default build-win) must contain test_*.exe from the MinGW build;
|
||||
# busybox.exe is taken from third_party/busybox/. VMs that are not running are
|
||||
# started and stopped again afterwards. Exit status is the number of failed
|
||||
# variant/user runs.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
VM="$ROOT/scripts/winvm/vm.sh"
|
||||
BUILD="$ROOT/build-win"
|
||||
VARIANTS="en zh"
|
||||
USERS_LIST="Administrator tester 测试"
|
||||
FILTER="*"
|
||||
while getopts "b:v:u:f:" o; do
|
||||
case "$o" in
|
||||
b) BUILD="$(cd "$OPTARG" && pwd)" ;;
|
||||
v) VARIANTS="$OPTARG" ;;
|
||||
u) USERS_LIST="$OPTARG" ;;
|
||||
f) FILTER="$OPTARG" ;;
|
||||
*) sed -n '2,8p' "$0"; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shopt -s nullglob
|
||||
exes=("$BUILD"/test_*.exe)
|
||||
[[ ${#exes[@]} -gt 0 ]] || { echo "no test_*.exe in $BUILD" >&2; exit 1; }
|
||||
|
||||
stage="$(mktemp -d)"
|
||||
trap 'rm -rf "$stage"' EXIT
|
||||
mkdir -p "$stage/bundle/bin" "$stage/bundle/data/tests"
|
||||
cp "${exes[@]}" "$stage/bundle/bin/"
|
||||
for f in "$BUILD"/*.dll "$ROOT/third_party/busybox/busybox.exe"; do
|
||||
[[ -f "$f" ]] && cp "$f" "$stage/bundle/bin/"
|
||||
done
|
||||
cp -r "$ROOT/tests/fixtures" "$stage/bundle/data/tests/"
|
||||
cp "$ROOT/scripts/winvm/run_tests.ps1" "$stage/bundle/"
|
||||
tar -C "$stage" -cf "$stage/bundle.tar" bundle
|
||||
|
||||
total_fail=0
|
||||
summary=()
|
||||
for v in $VARIANTS; do
|
||||
started=0
|
||||
if [[ "$("$VM" status "$v")" != running ]]; then
|
||||
"$VM" start "$v"
|
||||
started=1
|
||||
fi
|
||||
"$VM" ssh "$v" 'Remove-Item -Recurse -Force C:\cst-test\bundle -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Force C:\cst-test | Out-Null' >/dev/null
|
||||
"$VM" put "$v" "$stage/bundle.tar" "C:/cst-test/bundle.tar"
|
||||
"$VM" ssh "$v" 'tar -xf C:\cst-test\bundle.tar -C C:\cst-test; Remove-Item C:\cst-test\bundle.tar' >/dev/null
|
||||
for u in $USERS_LIST; do
|
||||
echo "===== $v / $u"
|
||||
rc=0
|
||||
"$VM" ps "$v" "$u" "$stage/bundle/run_tests.ps1" -Bundle 'C:\cst-test\bundle' -Filter "'$FILTER'" || rc=$?
|
||||
summary+=("$v/$u: $([[ $rc == 0 ]] && echo ok || echo FAIL)")
|
||||
[[ $rc == 0 ]] || total_fail=$((total_fail + 1))
|
||||
done
|
||||
[[ $started == 1 ]] && "$VM" stop "$v"
|
||||
done
|
||||
|
||||
echo
|
||||
printf '%s\n' "${summary[@]}"
|
||||
exit "$total_fail"
|
||||
Reference in New Issue
Block a user