refactor(deps): removed turbo-based workspace pipeline in favor of bun workspaces
- Removed Turborepo cache steps from CI and dropped .turbo from gitignore. - Migrated root scripts from turbo commands to bun workspace execution for build, test, lint, check, format, and fix. - Removed turbo dependencies and deleted turbo.json task configuration files from the repository.
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun";
|
||||
import * as path from "node:path";
|
||||
|
||||
const RUST_AFFECTING_FILE_NAMES = [
|
||||
"Cargo.toml",
|
||||
"Cargo.lock",
|
||||
"build.rs",
|
||||
"rust-toolchain",
|
||||
"rust-toolchain.toml",
|
||||
"clippy.toml",
|
||||
".clippy.toml",
|
||||
"rustfmt.toml",
|
||||
".rustfmt.toml",
|
||||
] as const satisfies readonly string[];
|
||||
const TASK_COMMANDS = {
|
||||
"check:rs": [
|
||||
["cargo", "fmt", "--all", "--", "--check"],
|
||||
["cargo", "clippy", "--workspace", "--", "-D", "warnings"],
|
||||
],
|
||||
"fix:rs": [
|
||||
["cargo", "fmt", "--all"],
|
||||
[
|
||||
"cargo",
|
||||
"clippy",
|
||||
"--workspace",
|
||||
"--fix",
|
||||
"--allow-dirty",
|
||||
"--all-targets",
|
||||
"--no-deps",
|
||||
"--allow-staged",
|
||||
"--broken-code",
|
||||
"--allow-no-vcs",
|
||||
],
|
||||
],
|
||||
"fmt:rs": [["cargo", "fmt", "--all"]],
|
||||
"lint:rs": [["cargo", "clippy", "--workspace", "--", "-D", "warnings"]],
|
||||
"test:rs": [["cargo", "nextest", "run", "--workspace", "--status-level=fail", "--final-status-level=fail"]],
|
||||
} as const satisfies Record<string, readonly (readonly string[])[]>;
|
||||
|
||||
type RustTaskName = keyof typeof TASK_COMMANDS;
|
||||
|
||||
const repoRoot = path.join(import.meta.dir, "..");
|
||||
const taskName = process.argv[2];
|
||||
|
||||
if (!isRustTaskName(taskName)) {
|
||||
console.error(`Unknown Rust task: ${taskName ?? "(missing)"}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!(isCI() || (await hasRustAffectingChanges()))) {
|
||||
console.log(`Skipping ${taskName} (not in CI and no Rust-affecting changes were found).`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
for (const command of TASK_COMMANDS[taskName]) {
|
||||
const exitCode = await runCommand(command);
|
||||
if (exitCode !== 0) {
|
||||
process.exit(exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
function isRustTaskName(value: string | undefined): value is RustTaskName {
|
||||
return value != null && value in TASK_COMMANDS;
|
||||
}
|
||||
|
||||
function isCI(): boolean {
|
||||
const value = Bun.env.CI;
|
||||
if (!value) return false;
|
||||
const normalized = value.trim().toLowerCase();
|
||||
return normalized !== "" && normalized !== "0" && normalized !== "false";
|
||||
}
|
||||
|
||||
async function hasRustAffectingChanges(): Promise<boolean> {
|
||||
const result = await $`git status --porcelain -z`.cwd(repoRoot).quiet().nothrow();
|
||||
if (result.exitCode !== 0) {
|
||||
const stderr = result.stderr.toString().trim();
|
||||
const suffix = stderr === "" ? `exit ${result.exitCode}` : stderr;
|
||||
console.warn(`Warning: failed to inspect git status: ${suffix}. Running ${taskName} conservatively.`);
|
||||
return true;
|
||||
}
|
||||
return getChangedPathsFromPorcelain(result.stdout).some(isRustAffectingPath);
|
||||
}
|
||||
|
||||
function getChangedPathsFromPorcelain(buf: Uint8Array): string[] {
|
||||
const entries = new TextDecoder().decode(buf).split("\0").filter(Boolean);
|
||||
const changedPaths: string[] = [];
|
||||
|
||||
for (let index = 0; index < entries.length; index += 1) {
|
||||
const entry = entries[index];
|
||||
if (entry.length < 4) continue;
|
||||
|
||||
const status = entry.slice(0, 2);
|
||||
const changedPath = entry.slice(3);
|
||||
if (changedPath !== "") {
|
||||
changedPaths.push(changedPath);
|
||||
}
|
||||
|
||||
if (status.includes("R") || status.includes("C")) {
|
||||
const renamedPath = entries[index + 1];
|
||||
if (renamedPath) {
|
||||
changedPaths.push(renamedPath);
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changedPaths;
|
||||
}
|
||||
|
||||
function isRustAffectingPath(changedPath: string): boolean {
|
||||
const normalized = changedPath.replace(/\\/g, "/");
|
||||
const fileName = normalized.slice(normalized.lastIndexOf("/") + 1);
|
||||
return (
|
||||
normalized.endsWith(".rs") ||
|
||||
normalized.startsWith(".cargo/") ||
|
||||
isOneOf(fileName, RUST_AFFECTING_FILE_NAMES)
|
||||
);
|
||||
}
|
||||
|
||||
function isOneOf<T extends string>(value: string, values: readonly T[]): value is T {
|
||||
return values.some(entry => entry === value);
|
||||
}
|
||||
|
||||
async function runCommand(command: readonly string[]): Promise<number> {
|
||||
const proc = Bun.spawn(command, {
|
||||
cwd: repoRoot,
|
||||
stdin: "inherit",
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
});
|
||||
return proc.exited;
|
||||
}
|
||||
Reference in New Issue
Block a user