|
| 1 | +import { execFileSync } from "node:child_process"; |
| 2 | +import { readFile } from "node:fs/promises"; |
| 3 | +import { dirname, relative } from "node:path"; |
| 4 | +import { fileURLToPath } from "node:url"; |
| 5 | + |
| 6 | +const bindingKind = (pkg) => { |
| 7 | + if (pkg.name.endsWith("-napi")) { |
| 8 | + return "napi"; |
| 9 | + } |
| 10 | + |
| 11 | + if (pkg.name.endsWith("-wasm")) { |
| 12 | + return "wasm"; |
| 13 | + } |
| 14 | + |
| 15 | + return null; |
| 16 | +}; |
| 17 | + |
| 18 | +const cargoPublishIsDisabled = (pkg) => Array.isArray(pkg.publish) && pkg.publish.length === 0; |
| 19 | + |
| 20 | +const releaseSteps = (workflow) => workflow.split(/\n {6}- name:/); |
| 21 | + |
| 22 | +const hasReleasePath = (pkg, workflow, rootPath) => { |
| 23 | + const kind = bindingKind(pkg); |
| 24 | + const packagePath = relative(rootPath, dirname(pkg.manifest_path)).replaceAll("\\", "/"); |
| 25 | + const buildCommand = kind === "napi" ? "napi build" : "wasm-pack build"; |
| 26 | + |
| 27 | + return releaseSteps(workflow).some( |
| 28 | + (step) => |
| 29 | + step.includes(buildCommand) && |
| 30 | + (step.includes(`cd ${packagePath}`) || step.includes(`working-directory: ${packagePath}`)), |
| 31 | + ); |
| 32 | +}; |
| 33 | + |
| 34 | +export const findUnclassifiedBindings = ({ packages, releaseWorkflow, rootPath }) => |
| 35 | + packages |
| 36 | + .filter((pkg) => bindingKind(pkg) !== null) |
| 37 | + .filter((pkg) => !cargoPublishIsDisabled(pkg)) |
| 38 | + .filter((pkg) => !hasReleasePath(pkg, releaseWorkflow, rootPath)) |
| 39 | + .map((pkg) => pkg.name) |
| 40 | + .sort(); |
| 41 | + |
| 42 | +export const loadBindingPolicyInputs = async (rootUrl) => { |
| 43 | + const rootPath = fileURLToPath(rootUrl); |
| 44 | + const metadata = JSON.parse( |
| 45 | + execFileSync("cargo", ["metadata", "--format-version", "1", "--no-deps"], { |
| 46 | + cwd: rootPath, |
| 47 | + encoding: "utf8", |
| 48 | + }), |
| 49 | + ); |
| 50 | + const workspaceMembers = new Set(metadata.workspace_members); |
| 51 | + const releaseWorkflow = await readFile(new URL(".github/workflows/release.yml", rootUrl), "utf8"); |
| 52 | + |
| 53 | + return { |
| 54 | + packages: metadata.packages.filter((pkg) => workspaceMembers.has(pkg.id)), |
| 55 | + releaseWorkflow, |
| 56 | + rootPath, |
| 57 | + }; |
| 58 | +}; |
0 commit comments