mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
docs: document script lib extension helpers
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// Small error formatting helper for scripts that accept unknown thrown values.
|
||||
/** Return a readable message for Error and non-Error thrown values. */
|
||||
export function formatErrorMessage(error) {
|
||||
if (error instanceof Error) {
|
||||
return error.message || error.name || "Error";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Creates reusable import-boundary guards for bundled extension source trees.
|
||||
import { promises as fs } from "node:fs";
|
||||
import { BUNDLED_PLUGIN_PATH_PREFIX } from "./bundled-plugin-paths.mjs";
|
||||
import {
|
||||
@@ -8,12 +9,12 @@ import {
|
||||
resolveRepoSpecifier,
|
||||
writeLine,
|
||||
} from "./guard-inventory-utils.mjs";
|
||||
import { mapWithConcurrency } from "./source-file-scan-cache.mjs";
|
||||
import {
|
||||
collectTypeScriptFilesFromRoots,
|
||||
resolveRepoRoot,
|
||||
resolveSourceRoots,
|
||||
} from "./ts-guard-utils.mjs";
|
||||
import { mapWithConcurrency } from "./source-file-scan-cache.mjs";
|
||||
|
||||
const repoRoot = resolveRepoRoot(import.meta.url);
|
||||
|
||||
@@ -64,6 +65,7 @@ function scanImportBoundaryViolations(source, filePath, boundaryLabel, allowReso
|
||||
return entries;
|
||||
}
|
||||
|
||||
/** Create a boundary checker with cached inventory collection and a CLI-style main function. */
|
||||
export function createExtensionImportBoundaryChecker(params) {
|
||||
const scanRoots = resolveSourceRoots(repoRoot, params.roots);
|
||||
|
||||
@@ -73,25 +75,21 @@ export function createExtensionImportBoundaryChecker(params) {
|
||||
.toSorted((left, right) =>
|
||||
normalizeRepoPath(repoRoot, left).localeCompare(normalizeRepoPath(repoRoot, right)),
|
||||
);
|
||||
const entriesByFile = await mapWithConcurrency(
|
||||
files,
|
||||
undefined,
|
||||
async (filePath) => {
|
||||
const source = await fs.readFile(filePath, "utf8");
|
||||
if (
|
||||
params.skipSourcesWithoutBundledPluginPrefix &&
|
||||
!source.includes(BUNDLED_PLUGIN_PATH_PREFIX)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
return scanImportBoundaryViolations(
|
||||
source,
|
||||
filePath,
|
||||
params.boundaryLabel,
|
||||
params.allowResolvedPath,
|
||||
);
|
||||
},
|
||||
);
|
||||
const entriesByFile = await mapWithConcurrency(files, undefined, async (filePath) => {
|
||||
const source = await fs.readFile(filePath, "utf8");
|
||||
if (
|
||||
params.skipSourcesWithoutBundledPluginPrefix &&
|
||||
!source.includes(BUNDLED_PLUGIN_PATH_PREFIX)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
return scanImportBoundaryViolations(
|
||||
source,
|
||||
filePath,
|
||||
params.boundaryLabel,
|
||||
params.allowResolvedPath,
|
||||
);
|
||||
});
|
||||
const inventory = entriesByFile.flat();
|
||||
return inventory.toSorted(compareEntries);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Classifies bundled extension files as production, barrel, test-like, or infra artifacts.
|
||||
const CODE_FILE_RE = /\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u;
|
||||
const DECLARATION_FILE_RE = /\.d\.ts$/u;
|
||||
const RUNTIME_API_BARREL_RE = /(^|\/)runtime-api\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u;
|
||||
@@ -17,6 +18,7 @@ function normalizeExtensionSourcePath(filePath) {
|
||||
return filePath.replaceAll("\\", "/");
|
||||
}
|
||||
|
||||
/** Classify one bundled extension source path for boundary and packaging guards. */
|
||||
export function classifyBundledExtensionSourcePath(filePath) {
|
||||
const normalizedPath = normalizeExtensionSourcePath(filePath);
|
||||
const isCodeFile = CODE_FILE_RE.test(normalizedPath) && !DECLARATION_FILE_RE.test(normalizedPath);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Resolves extension Vitest configs, costs, and batch shards for plugin test runs.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
@@ -29,6 +30,7 @@ import { listAvailableExtensionIds } from "./changed-extensions.mjs";
|
||||
import { parsePositiveInt } from "./numeric-options.mjs";
|
||||
|
||||
const repoRoot = path.resolve(import.meta.dirname, "..", "..");
|
||||
/** Default number of shards for broad bundled extension test batches. */
|
||||
export const DEFAULT_EXTENSION_TEST_SHARD_COUNT = 8;
|
||||
const EXTENSION_TEST_COST_MULTIPLIERS = {
|
||||
// CI shard planning uses measured wall time rather than raw file count.
|
||||
@@ -129,6 +131,7 @@ function listFilesystemTestFiles(rootPath) {
|
||||
return files.toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
/** List tracked or filesystem-discovered test files for extension roots. */
|
||||
export function listTrackedTestFilesForRoots(roots) {
|
||||
const files = [];
|
||||
for (const root of roots) {
|
||||
@@ -190,6 +193,7 @@ function resolveExtensionDirectory(targetArg, cwd = process.cwd()) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Resolve the Vitest configs, files, and estimated cost for one extension target. */
|
||||
export function resolveExtensionTestPlan(params = {}) {
|
||||
const cwd = params.cwd ?? process.cwd();
|
||||
const targetArg = params.targetArg;
|
||||
@@ -327,6 +331,7 @@ function mergeTestPlans(plans) {
|
||||
};
|
||||
}
|
||||
|
||||
/** Resolve a combined extension test plan for explicit or all available extension ids. */
|
||||
export function resolveExtensionBatchPlan(params = {}) {
|
||||
const cwd = params.cwd ?? process.cwd();
|
||||
const hasExplicitExtensionIds = params.extensionIds !== undefined;
|
||||
@@ -357,6 +362,7 @@ function pickLeastLoadedShard(shards) {
|
||||
}, -1);
|
||||
}
|
||||
|
||||
/** Create balanced extension test shards from per-extension plans. */
|
||||
export function createExtensionTestShards(params = {}) {
|
||||
const cwd = params.cwd ?? process.cwd();
|
||||
const extensionIds = params.extensionIds ?? listAvailableExtensionIds();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Formats generated TypeScript/JavaScript modules through the repo formatter.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { resolvePnpmRunner } from "../pnpm-runner.mjs";
|
||||
|
||||
/** Resolve the fastest available oxfmt command for a generated module path. */
|
||||
export function resolveGeneratedModuleFormatter(params) {
|
||||
const platform = params.platform ?? process.platform;
|
||||
const existsSync = params.existsSync ?? fs.existsSync;
|
||||
@@ -26,6 +28,7 @@ export function resolveGeneratedModuleFormatter(params) {
|
||||
});
|
||||
}
|
||||
|
||||
/** Format generated source in a temporary file and return the formatter output. */
|
||||
export function formatGeneratedModule(source, { repoRoot, outputPath, errorLabel }) {
|
||||
const resolvedRepoRoot = path.resolve(repoRoot);
|
||||
const resolvedOutputPath = path.resolve(
|
||||
|
||||
Reference in New Issue
Block a user