fix: simplify svglide ppe proxy setup

This commit is contained in:
songtianyi.theo
2026-07-09 17:54:55 +08:00
parent 1a52644461
commit a448ce86de
2 changed files with 132 additions and 77 deletions

View File

@@ -5,12 +5,6 @@ CANONICAL_RULE_NAME="lark-cli-openapi-ppe-svg-slides"
PROXY_HOST="${LARK_CLI_PROXY_HOST:-127.0.0.1}"
PROXY_PORT="${LARK_CLI_PROXY_PORT:-8899}"
# Keep this list intentionally small and explicit. These were previous local
# SVGlide/PPE rule names that can route generated SVG Slides to the wrong lane.
# Do not store them in a whitespace-split variable: this script is meant to be
# sourced by zsh as well as POSIX shells, and zsh does not split scalars by
# whitespace unless SH_WORD_SPLIT is enabled.
fail() {
printf '%s\n' "[svglide-ppe] $*" >&2
return 1 2>/dev/null || exit 1
@@ -23,14 +17,15 @@ info() {
usage() {
cat <<USAGE
Usage:
. ./scripts/dev-svglide-ppe-env.sh pre [--host <host>] [--port <port>] [--no-clear]
. ./scripts/dev-svglide-ppe-env.sh pre
. ./scripts/dev-svglide-ppe-env.sh off
./scripts/dev-svglide-ppe-env.sh rules
Notes:
- Use "source" or "." for pre/off so proxy env vars apply to the current shell.
- pre writes the canonical Whistle rule "${CANONICAL_RULE_NAME}".
- pre also clears known legacy SVGlide/PPE rule names unless --no-clear is passed.
- off disables only the canonical Whistle rule "${CANONICAL_RULE_NAME}".
- The only PPE lane is "ppe_svg_slides".
- This is dev-only PPE plumbing, not production publish behavior.
USAGE
}
@@ -89,11 +84,9 @@ RULES
}
disabled_rules() {
rule_name="$1"
cat <<RULES
# disabled by scripts/dev-svglide-ppe-env.sh
# canonical SVGlide PPE rule: ${CANONICAL_RULE_NAME}
# cleared legacy rule: ${rule_name}
RULES
}
@@ -115,12 +108,22 @@ process.stdout.write(`module.exports = function (callback) {
NODE
}
create_temp_rule_js() {
tmp_base="$(mktemp "${TMPDIR:-/tmp}/svglide-ppe-rule.XXXXXX")" || fail "failed to create temp file"
tmp_js="${tmp_base}.js"
mv "$tmp_base" "$tmp_js" || {
rm -f "$tmp_base" "$tmp_js"
fail "failed to create temp file"
}
printf '%s\n' "$tmp_js"
}
apply_rule() {
wcmd="$1"
rule_name="$2"
rules="$3"
tmp_js="$(mktemp "${TMPDIR:-/tmp}/svglide-ppe-rule.XXXXXX.js")" || fail "failed to create temp file"
tmp_js="$(create_temp_rule_js)" || return 1
write_rule_js "$tmp_js" "$rule_name" "$rules"
"$wcmd" add "$tmp_js" --force >/dev/null 2>&1 || {
rm -f "$tmp_js"
@@ -129,41 +132,6 @@ apply_rule() {
rm -f "$tmp_js"
}
clear_legacy_rules() {
wcmd="$1"
clear_legacy_rule "$wcmd" "lark-cli-openapi-env-switch"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-svglide"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-pure-svg"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-pure-svg-control"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-svg-slides-header-only"
clear_legacy_rule "$wcmd" "lark-cli-pre-ppe-svglide-combined"
clear_legacy_rule "$wcmd" "lark-cli-ppe-pure-svg"
clear_legacy_rule "$wcmd" "lark-cli-ppe-svglide"
clear_legacy_rule "$wcmd" "lark-cli-prod-host-pre-env-ppe-header"
clear_legacy_rule "$wcmd" "lark-cli-prod-ppe-svglide-header-only"
}
clear_legacy_rule() {
wcmd="$1"
rule_name="$2"
[ "$rule_name" = "$CANONICAL_RULE_NAME" ] && return 0
remove_rule "$wcmd" "$rule_name" || apply_rule "$wcmd" "$rule_name" "$(disabled_rules "$rule_name")"
info "cleared legacy Whistle rule: ${rule_name}"
}
remove_rule() {
_wcmd="$1"
rule_name="$2"
if ! command -v curl >/dev/null 2>&1; then
return 1
fi
curl -fsS \
-X POST \
-H 'Content-Type: application/json' \
--data "{\"name\":\"${rule_name}\"}" \
"http://${PROXY_HOST}:${PROXY_PORT}/cgi-bin/rules/remove" >/dev/null 2>&1
}
apply_proxy_env() {
proxy_url="http://${PROXY_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="$proxy_url"
@@ -189,32 +157,7 @@ mode="${1:-}"
}
shift || true
clear_legacy="1"
while [ "$#" -gt 0 ]; do
case "$1" in
--host)
[ "$#" -ge 2 ] || fail "--host requires a value"
PROXY_HOST="$2"
shift 2
;;
--port)
[ "$#" -ge 2 ] || fail "--port requires a value"
PROXY_PORT="$2"
shift 2
;;
--no-clear)
clear_legacy="0"
shift
;;
-h|--help)
usage
return 0 2>/dev/null || exit 0
;;
*)
fail "unknown arg: $1"
;;
esac
done
[ "$#" -eq 0 ] || fail "unexpected args for mode ${mode}"
case "$mode" in
rules)
@@ -223,9 +166,6 @@ case "$mode" in
pre)
wcmd="$(pick_whistle_cmd)"
ensure_whistle_running "$wcmd"
if [ "$clear_legacy" = "1" ]; then
clear_legacy_rules "$wcmd"
fi
apply_rule "$wcmd" "$CANONICAL_RULE_NAME" "$(canonical_rules)"
info "applied canonical Whistle rule: ${CANONICAL_RULE_NAME}"
if is_sourced; then
@@ -239,8 +179,7 @@ case "$mode" in
off|cancel)
wcmd="$(pick_whistle_cmd)"
ensure_whistle_running "$wcmd"
clear_legacy_rules "$wcmd"
apply_rule "$wcmd" "$CANONICAL_RULE_NAME" "$(disabled_rules "$CANONICAL_RULE_NAME")"
apply_rule "$wcmd" "$CANONICAL_RULE_NAME" "$(disabled_rules)"
info "disabled canonical Whistle rule: ${CANONICAL_RULE_NAME}"
if is_sourced; then
clear_proxy_env

View File

@@ -0,0 +1,116 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
const { describe, it } = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { spawnSync } = require("node:child_process");
const repoRoot = path.resolve(__dirname, "..");
function createMockWhistle() {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "svglide-ppe-test-"));
const binDir = path.join(tmp, "bin");
const logPath = path.join(tmp, "w2.log");
fs.mkdirSync(binDir);
fs.writeFileSync(path.join(binDir, "w2"), `#!/usr/bin/env sh
case "$1" in
status)
printf '%s\\n' "Whistle is running"
;;
add)
node -e 'require(process.argv[1])((rule) => console.log(JSON.stringify({ name: rule.name, rules: rule.rules })))' "$2" >>"$SVGLIDE_TEST_W2_LOG"
;;
start)
printf '%s\\n' "START" >>"$SVGLIDE_TEST_W2_LOG"
;;
*)
printf 'unexpected w2 args: %s\\n' "$*" >&2
exit 2
;;
esac
`);
fs.chmodSync(path.join(binDir, "w2"), 0o755);
return { binDir, logPath };
}
function readLoggedRules(logPath) {
return fs
.readFileSync(logPath, "utf8")
.trim()
.split("\n")
.filter(Boolean)
.map((line) => JSON.parse(line));
}
describe("dev-svglide-ppe-env", () => {
it("keeps one canonical rule name in the script source", () => {
const source = fs.readFileSync(path.join(repoRoot, "scripts/dev-svglide-ppe-env.sh"), "utf8");
assert.match(source, /CANONICAL_RULE_NAME="lark-cli-openapi-ppe-svg-slides"/);
assert.doesNotMatch(
source,
/lark-cli-openapi-env-switch|lark-cli-openapi-ppe-svglide|lark-cli-openapi-ppe-pure-svg|lark-cli-ppe-svglide|lark-cli-prod-ppe/
);
});
it("prints only the canonical SVG Slides PPE lane", () => {
const result = spawnSync("sh", ["scripts/dev-svglide-ppe-env.sh", "rules"], {
cwd: repoRoot,
encoding: "utf8",
});
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, /open\.feishu-pre\.cn/);
assert.match(result.stdout, /x-tt-env=ppe_svg_slides/);
assert.match(result.stdout, /x-use-ppe=1/);
assert.doesNotMatch(result.stdout, /ppe_pure_svg|ppe_svglide/);
});
it("keeps pre mode to one written Whistle rule", () => {
const { binDir, logPath } = createMockWhistle();
const result = spawnSync("sh", ["-c", ". ./scripts/dev-svglide-ppe-env.sh pre"], {
cwd: repoRoot,
env: {
...process.env,
PATH: `${binDir}${path.delimiter}${process.env.PATH}`,
SVGLIDE_TEST_W2_LOG: logPath,
},
encoding: "utf8",
});
assert.equal(result.status, 0, result.stderr);
const rules = readLoggedRules(logPath);
assert.equal(rules.length, 1);
assert.equal(rules[0].name, "lark-cli-openapi-ppe-svg-slides");
assert.match(rules[0].rules, /x-tt-env=ppe_svg_slides/);
assert.doesNotMatch(rules[0].rules, /ppe_pure_svg|ppe_svglide/);
});
it("keeps off mode to one disabled canonical Whistle rule", () => {
const { binDir, logPath } = createMockWhistle();
const result = spawnSync("sh", ["-c", ". ./scripts/dev-svglide-ppe-env.sh off"], {
cwd: repoRoot,
env: {
...process.env,
PATH: `${binDir}${path.delimiter}${process.env.PATH}`,
SVGLIDE_TEST_W2_LOG: logPath,
},
encoding: "utf8",
});
assert.equal(result.status, 0, result.stderr);
const rules = readLoggedRules(logPath);
assert.equal(rules.length, 1);
assert.equal(rules[0].name, "lark-cli-openapi-ppe-svg-slides");
assert.match(rules[0].rules, /disabled by scripts\/dev-svglide-ppe-env\.sh/);
assert.match(rules[0].rules, /canonical SVGlide PPE rule: lark-cli-openapi-ppe-svg-slides/);
assert.doesNotMatch(rules[0].rules, /legacy|ppe_pure_svg|ppe_svglide/);
});
});