feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import { promises as fs } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
/**
|
||||
* Shared "no hardcoded px text size" guard.
|
||||
*
|
||||
* Zoom (Cmd +/-) scales the root <html> font-size, so only **rem**-based text
|
||||
* scales. Hardcoded px text sizes (`text-[15px]`, `font-size: 15px`) freeze
|
||||
* against zoom — that's the timeline regression we fixed. This guard stops new
|
||||
* px text sizes from creeping back in. Use a rem-based Tailwind token instead
|
||||
* (e.g. the stock `text-base`, `text-sm`, `text-xs` scale — chat === base).
|
||||
*
|
||||
* It flags:
|
||||
* - Tailwind arbitrary text-size utilities: `text-[NNpx]`, `text-[N.NNrem]`,
|
||||
* `text-[N.NNem]` — any arbitrary font-size literal. Use a named token
|
||||
* (`text-2xs`, `text-3xs`, or the stock `text-base`/`text-sm`/`text-xs`
|
||||
* scale) so the size lives in `tailwind.config.js` as rem and stays
|
||||
* consistent. px literals freeze against zoom; arbitrary rem literals
|
||||
* re-fragment the scale we just consolidated.
|
||||
* - CSS px font sizes: `font-size: NNpx`
|
||||
*
|
||||
* Decorative/chrome exceptions (avatar initials sized to a fixed avatar box,
|
||||
* the `text-[6rem]` emoji glyph, etc.) live in the `overrides` allowlist
|
||||
* supplied by each app.
|
||||
*/
|
||||
|
||||
// Any arbitrary Tailwind text-size literal — px, rem, or em. Color literals
|
||||
// like `text-[#fff]` or `text-[var(--x)]` don't match (no unit-bearing number).
|
||||
const TEXT_ARBITRARY_RE = /\btext-\[\d+(?:\.\d+)?(?:px|rem|em)\]/g;
|
||||
// Match the CSS `font-size` property, but NOT custom properties like
|
||||
// `--font-size:` (third-party widget vars) which merely contain the substring.
|
||||
const FONT_SIZE_PX_RE = /(?<!-)\bfont-size:\s*\d+(?:\.\d+)?px/g;
|
||||
|
||||
async function walkFiles(directory) {
|
||||
const entries = await fs.readdir(directory, { withFileTypes: true });
|
||||
const files = await Promise.all(
|
||||
entries.map(async (entry) => {
|
||||
const fullPath = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
return walkFiles(fullPath);
|
||||
}
|
||||
return [fullPath];
|
||||
}),
|
||||
);
|
||||
return files.flat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} options.projectRoot Absolute path the rule roots resolve against.
|
||||
* @param {Array<{root: string, extensions: Set<string>}>} options.rules Where to scan.
|
||||
* @param {string} options.label Human label for the failure header.
|
||||
* @param {Set<string>} [options.overrides] Allowlisted "relativePath:matchedLiteral" entries.
|
||||
* @param {string} options.scriptPath Path mentioned in the failure hint.
|
||||
*/
|
||||
export async function runPxTextCheck({
|
||||
projectRoot,
|
||||
rules,
|
||||
label,
|
||||
overrides = new Set(),
|
||||
scriptPath,
|
||||
}) {
|
||||
const candidateFiles = (
|
||||
await Promise.all(
|
||||
rules.map((rule) => {
|
||||
const dir = path.join(projectRoot, rule.root);
|
||||
return fs
|
||||
.access(dir)
|
||||
.then(() => walkFiles(dir))
|
||||
.catch(() => []);
|
||||
}),
|
||||
)
|
||||
).flat();
|
||||
|
||||
const violations = [];
|
||||
|
||||
for (const filePath of candidateFiles) {
|
||||
// `rules[].root` and the `overrides` keys are authored with `/`, but
|
||||
// path.relative yields `\` on Windows — so every comparison against them
|
||||
// has to happen in posix form or it silently matches nothing.
|
||||
const relativePath = path
|
||||
.relative(projectRoot, filePath)
|
||||
.split(path.sep)
|
||||
.join("/");
|
||||
const rule = rules.find((r) => relativePath.startsWith(`${r.root}/`));
|
||||
if (!rule) {
|
||||
continue;
|
||||
}
|
||||
if (!rule.extensions.has(path.extname(relativePath))) {
|
||||
continue;
|
||||
}
|
||||
// Optional per-rule basename allowlist — scopes the scan to specific files.
|
||||
if (rule.files && !rule.files.has(path.basename(relativePath))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const content = await fs.readFile(filePath, "utf8");
|
||||
const lines = content.split(/\r?\n/);
|
||||
lines.forEach((line, index) => {
|
||||
const lineNumber = index + 1;
|
||||
const matches = [
|
||||
...(line.match(TEXT_ARBITRARY_RE) ?? []),
|
||||
...(line.match(FONT_SIZE_PX_RE) ?? []),
|
||||
];
|
||||
for (const match of matches) {
|
||||
const key = `${relativePath}:${match}`;
|
||||
if (!overrides.has(key)) {
|
||||
violations.push({ relativePath, lineNumber, match });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (violations.length > 0) {
|
||||
console.error(`${label} px-text check failed:`);
|
||||
for (const v of violations) {
|
||||
console.error(`- ${v.relativePath}:${v.lineNumber}: ${v.match}`);
|
||||
}
|
||||
console.error(
|
||||
"Use a rem-based Tailwind text token (e.g. the stock `text-base`, " +
|
||||
"`text-sm`, `text-xs` scale, or the `text-2xs` / `text-3xs` meta-text " +
|
||||
"tokens) so the text scales with Cmd +/- zoom and stays on one scale. " +
|
||||
"If this size is " +
|
||||
"genuinely decorative/chrome (not readable message text), add a " +
|
||||
`narrowly scoped \`relativePath:matchedLiteral\` exception in \`${scriptPath}\`.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user