chore: import upstream snapshot with attribution
Python CI / Python bindings (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Neovim aarch64-linux-android (push) Failing after 0s
Build & Publish / Build Neovim aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Python wheels aarch64 (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Python wheels x86_64 (ubuntu-latest) (push) Failing after 1s
Build & Publish / Build Python sdist (push) Failing after 1s
Rust CI / Fuzz Tests (ubuntu-latest) (push) Failing after 1s
Rust CI / Build i686-unknown-linux-gnu (push) Failing after 0s
Rust CI / cargo clippy (push) Failing after 1s
e2e Tests / e2e (ubuntu-latest) (push) Failing after 1s
Lua CI / luacheck lint (push) Failing after 1s
Build & Publish / Build Neovim aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Neovim x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build Neovim x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI aarch64-linux-android (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-gnu (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-musl (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-gnu (push) Failing after 1s
Spelling / Spell Check with Typos (push) Failing after 0s
Rust CI / Test (ubuntu-latest) (push) Failing after 0s
Rust CI / cargo fmt (push) Failing after 0s
Stylua / Check lua files using Stylua (push) Failing after 1s
Lua CI / lua-language-server type check (push) Failing after 12m29s
e2e Tests / e2e (alpine-musl) (push) Successful in 57m31s
e2e Tests / e2e (macos-latest) (push) Has been cancelled
Build & Publish / Build C FFI aarch64-apple-darwin (push) Has been cancelled
Rust CI / Test (windows-latest) (push) Has been cancelled
e2e Tests / e2e (windows-latest) (push) Has been cancelled
Nix CI / check (push) Has been cancelled
Python CI / Python bindings (macos-latest) (push) Has been cancelled
Python CI / Python bindings (windows-latest) (push) Has been cancelled
Build & Publish / Build Neovim aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Neovim x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build C FFI x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Python wheels aarch64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (windows-latest) (push) Has been cancelled
Build & Publish / Release (push) Has been cancelled
Build & Publish / Publish Python wheels to PyPI (push) Has been cancelled
Build & Publish / Publish Rust crates (push) Has been cancelled
Build & Publish / Publish npm packages (push) Has been cancelled
Rust CI / Fuzz Tests (windows-latest) (push) Has been cancelled
Rust CI / Test (macos-latest) (push) Has been cancelled
Rust CI / Fuzz Tests (macos-latest) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:27:16 +08:00
commit d5f207424b
328 changed files with 87463 additions and 0 deletions
View File
+21
View File
@@ -0,0 +1,21 @@
import { FileFinder } from "@ff-labs/fff-node";
const finder = FileFinder.create({ basePath: "~/dev/linux-root" });
if (!finder.ok) {
throw new Error(`Failed to create FileFinder: ${finder.error}`);
}
const scan = await finder.value.waitForScan(5_000);
if (!scan.ok) {
throw new Error(`Failed to wait for scan: ${scan.error}`);
}
// 5ms on m1 mac at the linux kernel repo root
const result = finder.value.grep("hardwre", { mode: "plain" });
for (const match of result.value.items) {
console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);
}
console.log(`\n${result.value.totalMatched} matches across ${result.value.totalFilesSearched} files`);
finder.value.destroy();
+353
View File
@@ -0,0 +1,353 @@
import { after, before, describe, it } from "node:test";
import { strict as assert } from "node:assert";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { FileFinder } from "../dist/src/index.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = resolve(__dirname, "..", "..", "..");
const normalizePath = (p) => p.replace(/\\/g, "/");
/** @type {import("../dist/src/finder.js").FileFinder | null} */
let finder = null;
describe("fff-node", { concurrency: 1 }, () => {
before(async () => {
const result = FileFinder.create({ basePath: REPO_ROOT });
assert.ok(result.ok, `create failed: ${!result.ok ? result.error : ""}`);
finder = result.value;
const wait = await finder.waitForScan(5_000);
if (!wait.ok) {
assert.ok(wait.ok, `waitForScan failed: ${wait.error}`);
}
assert.equal(wait.value, true, "scan should finish within 5s");
});
after(() => {
if (finder && !finder.isDestroyed) {
finder.destroy();
}
});
it("isAvailable returns true when the native library is loadable", () => {
assert.equal(FileFinder.isAvailable(), true);
});
it("getScanProgress reports >100 indexed files", () => {
const r = finder.getScanProgress();
assert.ok(r.ok, "getScanProgress failed");
assert.equal(typeof r.value.scannedFilesCount, "number");
assert.ok(
r.value.scannedFilesCount > 100,
`expected >100, got ${r.value.scannedFilesCount}`,
);
assert.equal(r.value.isScanning, false);
});
describe("search", { concurrency: 1 }, () => {
it("finds the root Cargo.toml", () => {
const r = finder.fileSearch("Cargo.toml", { pageSize: 10 });
assert.ok(r.ok, `search failed: ${!r.ok ? r.error : ""}`);
const paths = r.value.items.map((i) => i.relativePath);
assert.ok(
paths.includes("Cargo.toml"),
`expected Cargo.toml in results, got: ${paths}`,
);
});
it("finds crates/fff-c/src/lib.rs", () => {
const r = finder.fileSearch("lib.rs", { pageSize: 20 });
assert.ok(r.ok);
const paths = r.value.items.map((i) => i.relativePath);
assert.ok(
paths.some((p) => p.includes("fff-c") && p.endsWith("lib.rs")),
`expected fff-c/src/lib.rs, got: ${paths}`,
);
});
it("respects pageSize", () => {
const r = finder.fileSearch("lua", { pageSize: 3 });
assert.ok(r.ok);
assert.ok(
r.value.items.length <= 3,
`expected <=3, got ${r.value.items.length}`,
);
});
it("items contain all required fields", () => {
const r = finder.fileSearch("Cargo.toml", { pageSize: 1 });
assert.ok(r.ok);
const item = r.value.items[0];
for (const f of ["relativePath", "fileName", "gitStatus"]) {
assert.equal(typeof item[f], "string", `${f} should be a string`);
}
for (const f of ["size", "modified"]) {
assert.equal(typeof item[f], "number", `${f} should be a number`);
}
});
it("scores contain all required fields", () => {
const r = finder.fileSearch("Cargo.toml", { pageSize: 1 });
assert.ok(r.ok);
assert.ok(r.value.scores.length > 0);
const s = r.value.scores[0];
for (const f of ["total", "baseScore"]) {
assert.equal(typeof s[f], "number", `${f} should be a number`);
}
assert.equal(typeof s.matchType, "string");
});
it("totalMatched <= totalFiles", () => {
const r = finder.fileSearch("rs", { pageSize: 1 });
assert.ok(r.ok);
assert.ok(r.value.totalMatched > 0);
assert.ok(r.value.totalFiles > 100);
assert.ok(r.value.totalFiles >= r.value.totalMatched);
});
it("empty query returns files", () => {
const r = finder.fileSearch("", { pageSize: 5 });
assert.ok(r.ok, `empty query failed: ${!r.ok ? r.error : ""}`);
assert.equal(typeof r.value.totalFiles, "number");
});
});
describe("glob", { concurrency: 1 }, () => {
it("filters by extension via raw glob pattern", () => {
const r = finder.glob("**/*.rs", { pageSize: 50 });
assert.ok(r.ok, `glob failed: ${!r.ok ? r.error : ""}`);
assert.ok(r.value.items.length > 0, "expected at least one .rs file");
for (const item of r.value.items) {
assert.ok(
item.relativePath.endsWith(".rs"),
`unexpected file: ${item.relativePath}`,
);
}
});
it("returns empty result for non-matching pattern", () => {
const r = finder.glob("**/this-extension-does-not-exist-anywhere.zzz");
assert.ok(r.ok);
assert.equal(r.value.items.length, 0);
});
it("rejects empty pattern", () => {
const r = finder.glob("");
assert.equal(r.ok, false);
});
it("respects pageSize", () => {
const r = finder.glob("**/*.rs", { pageSize: 3 });
assert.ok(r.ok);
assert.ok(r.value.items.length <= 3);
});
});
describe("grep", { concurrency: 1 }, () => {
it("finds FffResult in Rust sources", () => {
// Constrain to .rs files so the assertion doesn't depend on result ordering
// or content-indexing timing for other file types.
const rustResults = finder.grep("*.rs FffResult", { mode: "plain" });
assert.ok(
rustResults.ok,
`grep failed: ${!rustResults.ok ? rustResults.error : ""}`,
);
assert.ok(
rustResults.value.items.length > 0,
"expected at least one .rs match",
);
assert.ok(
rustResults.value.items.some((m) => m.relativePath.endsWith(".rs")),
);
const cResults = finder.grep("!**/*.{js,ts,rs} FffResult", {
mode: "plain",
});
assert.ok(
cResults.ok,
`grep failed: ${!cResults.ok ? cResults.error : ""}`,
);
assert.ok(
cResults.value.items.length > 0,
"expected at least one non-js/ts/rs match",
);
assert.ok(
cResults.value.items.some((m) => m.relativePath.endsWith(".h")),
);
});
it("match items contain all required fields", () => {
const r = finder.grep("FffResult", { mode: "plain" });
assert.ok(r.ok);
const m = r.value.items[0];
assert.equal(typeof m.relativePath, "string");
assert.equal(typeof m.lineNumber, "number");
assert.ok(m.lineNumber > 0, "lineNumber is 1-based");
assert.equal(typeof m.lineContent, "string");
assert.ok(m.lineContent.includes("FffResult"));
assert.equal(typeof m.col, "number");
assert.equal(typeof m.byteOffset, "number");
assert.ok(Array.isArray(m.matchRanges));
console.log(m.matchRanges);
});
it("pagination returns a second page", () => {
const r = finder.grep("fn", { mode: "plain" });
assert.ok(r.ok);
if (r.value.nextCursor) {
const r2 = finder.grep("fn", { cursor: r.value.nextCursor });
assert.ok(r2.ok, `page 2 failed: ${!r2.ok ? r2.error : ""}`);
assert.equal(typeof r2.value.totalMatched, "number");
}
});
it("respects pageSize", () => {
// Cap to one match per file so pageSize bounds the total deterministically.
const unbounded = finder.grep("fn", {
mode: "plain",
maxMatchesPerFile: 1,
});
assert.ok(
unbounded.ok,
`grep failed: ${!unbounded.ok ? unbounded.error : ""}`,
);
assert.ok(unbounded.value.items.length > 2);
const limited = finder.grep("fn", {
mode: "plain",
maxMatchesPerFile: 1,
pageSize: 2,
});
assert.ok(limited.ok, `grep failed: ${!limited.ok ? limited.error : ""}`);
assert.ok(
limited.value.items.length <= 2,
`expected <=2 items, got ${limited.value.items.length}`,
);
assert.ok(
limited.value.items.length < unbounded.value.items.length,
"limited page should yield fewer matches than the default",
);
assert.ok(limited.value.nextCursor !== null, "nextCursor should be set");
});
it("regex mode matches pub fn declarations", () => {
const r = finder.grep("pub fn \\w+", { mode: "regex" });
assert.ok(r.ok, `regex grep failed: ${!r.ok ? r.error : ""}`);
assert.ok(r.value.items.length > 0);
});
it("decodes before/after context lines", () => {
const r = finder.grep(
"LOLLOWOIEJIWOIUOIWUIWUIOUWE", // the random text visible here
{
mode: "plain",
beforeContext: 1,
afterContext: 1,
maxMatchesPerFile: 5,
},
);
assert.ok(r.ok, `grep with context failed: ${!r.ok ? r.error : ""}`);
const match = r.value.items.find(
(m) =>
normalizePath(m.relativePath) === "packages/fff-node/test/e2e.mjs",
);
assert.ok(
match,
`expected a single match in the codebase, got: ${r.value.items
.map((m) => normalizePath(m.relativePath))
.join(", ")}`,
);
assert.deepEqual(match.contextBefore, [" const r = finder.grep("]);
assert.deepEqual(match.contextAfter, [" {"]);
});
});
describe("multiGrep", { concurrency: 1 }, () => {
it("finds lines matching any of the C FFI function names", () => {
const r = finder.multiGrep({
patterns: ["fff_create_instance", "fff_destroy", "fff_search"],
});
assert.ok(r.ok, `multiGrep failed: ${!r.ok ? r.error : ""}`);
assert.ok(r.value.items.length > 0);
});
it("rejects empty patterns array", () => {
const r = finder.multiGrep({ patterns: [] });
assert.ok(!r.ok);
});
});
it("refreshGitStatus returns a positive count", () => {
const r = finder.refreshGitStatus();
assert.ok(r.ok, `refreshGitStatus failed: ${!r.ok ? r.error : ""}`);
assert.equal(typeof r.value, "number");
assert.ok(r.value > 0);
});
it("isScanning returns a boolean", () => {
assert.equal(typeof finder.isScanning(), "boolean");
});
describe("healthCheck", { concurrency: 1 }, () => {
it("reports initialized state with instance", () => {
const r = finder.healthCheck(REPO_ROOT);
assert.ok(r.ok, `healthCheck failed: ${!r.ok ? r.error : ""}`);
assert.equal(typeof r.value.version, "string");
assert.ok(r.value.version.length > 0);
assert.equal(r.value.git.available, true);
assert.equal(r.value.git.repositoryFound, true);
assert.equal(r.value.filePicker.initialized, true);
assert.ok(r.value.filePicker.indexedFiles > 100);
});
it("static check works without instance", () => {
const r = FileFinder.healthCheckStatic(REPO_ROOT);
assert.ok(r.ok, `static healthCheck failed: ${!r.ok ? r.error : ""}`);
assert.equal(typeof r.value.version, "string");
assert.equal(r.value.filePicker.initialized, false);
assert.equal(r.value.git.repositoryFound, true);
});
});
it("create rejects a non-existent path", () => {
const r = FileFinder.create({ basePath: "/nonexistent/fff-test-path" });
assert.ok(!r.ok);
assert.ok(
r.error.toLowerCase().includes("invalid path") ||
r.error.toLowerCase().includes("not exist"),
`unexpected error: ${r.error}`,
);
});
// This must be the last describe block since it destroys the shared instance.
describe("after destroy", { concurrency: 1 }, () => {
before(() => {
finder.destroy();
});
it("isDestroyed is true", () => {
assert.equal(finder.isDestroyed, true);
});
it("search returns an error", () => {
const r = finder.fileSearch("test");
assert.ok(!r.ok);
assert.ok(r.error.includes("destroyed"));
});
it("grep returns an error", () => {
const r = finder.grep("test");
assert.ok(!r.ok);
assert.ok(r.error.includes("destroyed"));
});
it("double destroy is a safe no-op", () => {
finder.destroy();
assert.equal(finder.isDestroyed, true);
});
});
});
+122
View File
@@ -0,0 +1,122 @@
/**
* Stress reproducer for issue #515.
*
* Repeatedly creates a FileFinder, waits for scan, runs mixed file / dir /
* grep operations with periodic scanFiles() and refreshGitStatus() calls,
* destroys it, then repeats across two repos.
*
* Usage:
* node test/stress-515.mjs [iterations] [repoA] [repoB]
*/
import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";
import { FileFinder } from "../dist/src/index.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = resolve(__dirname, "..", "..", "..");
const args = process.argv.slice(2);
const ITERS = Number(args[0] || process.env.FFF_STRESS_ITERS || 50);
const REPO_A = resolve(args[1] || process.env.FFF_STRESS_REPO_A || REPO_ROOT);
const REPO_B_CANDIDATE = args[2] || process.env.FFF_STRESS_REPO_B || resolve(REPO_ROOT, "big-repo");
const REPO_B = existsSync(REPO_B_CANDIDATE) ? resolve(REPO_B_CANDIDATE) : REPO_A;
const REPOS = REPO_A === REPO_B ? [REPO_A] : [REPO_A, REPO_B];
const SEARCH_QUERIES = [
"main",
"lib",
"fn",
"TODO",
"config",
"README",
"Cargo",
"test",
"src/",
"init",
"pub",
"use",
];
const GREP_QUERIES = [
"fn ",
"pub fn",
"TODO",
"FIXME",
"use std",
"impl ",
"struct ",
"let mut",
"return",
"match ",
];
function pick(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
async function runIteration(iter) {
const base = REPOS[iter % REPOS.length];
process.stdout.write(`[iter ${iter}] base=${base} `);
const created = FileFinder.create({
basePath: base,
logFilePath: `/tmp/fff-515-${iter}.log`,
logLevel: "debug",
});
if (!created.ok) {
console.error(`create failed: ${created.error}`);
return false;
}
const finder = created.value;
const wait = await finder.waitForScan(60_000);
if (!wait.ok || !wait.value) {
console.error(`waitForScan failed: ${JSON.stringify(wait)}`);
finder.destroy();
return false;
}
process.stdout.write("scan-done ");
const opCount = 30 + Math.floor(Math.random() * 30);
for (let i = 0; i < opCount; i++) {
const r = Math.random();
if (r < 0.35) {
finder.fileSearch(pick(SEARCH_QUERIES), { pageSize: 20 });
} else if (r < 0.55) {
finder.directorySearch(pick(SEARCH_QUERIES), { pageSize: 20 });
} else if (r < 0.85) {
finder.grep(pick(GREP_QUERIES), { mode: "plain", pageSize: 20 });
} else if (r < 0.93) {
finder.scanFiles();
} else {
finder.refreshGitStatus();
}
}
process.stdout.write("ops-done ");
finder.destroy();
process.stdout.write("destroyed\n");
return true;
}
(async () => {
console.log(`Running ${ITERS} iterations across:`);
console.log(` A: ${REPO_A}`);
console.log(` B: ${REPO_B}`);
for (let i = 0; i < ITERS; i++) {
const ok = await runIteration(i);
if (!ok) {
console.error(`Aborting at iteration ${i}`);
process.exit(1);
}
}
console.log("Completed without crash.");
})();