Skip to content

Commit 65d67ce

Browse files
authored
chore: check unstable module usage in stable modules (denoland#5984)
1 parent f84e735 commit 65d67ce

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

_tools/check_unstable_deps.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2+
// deno-lint-ignore-file no-console
3+
4+
/**
5+
* This script checks if the stable modules import the unstable modules.
6+
*
7+
* Usage: `deno run -A _tools/check_unstable_deps.ts`
8+
*
9+
* @module
10+
*/
11+
12+
// These 2 paths are known to include unstable module (net/unstable_get_network_address.ts)
13+
// and should be ignored.
14+
const EXCEPTIONS = [
15+
"std/http/file_server.ts",
16+
"std/http/mod.ts",
17+
];
18+
19+
import denoJson from "../deno.json" with { type: "json" };
20+
import { join } from "@std/path/unstable-join";
21+
import { greaterOrEqual, parse } from "@std/semver";
22+
import { zip } from "@std/collections/zip";
23+
import { resolveWorkspaceSpecifiers } from "./utils.ts";
24+
import { createGraph } from "@deno/graph";
25+
26+
type DenoJson = { version: string; exports: Record<string, string> };
27+
function readDenoJson(path: string): Promise<DenoJson> {
28+
return Deno.readTextFile(join(path, "deno.json")).then(JSON.parse);
29+
}
30+
const semver1 = parse("1.0.0");
31+
function isStable(version: string) {
32+
return greaterOrEqual(parse(version), semver1);
33+
}
34+
35+
const { workspace } = denoJson;
36+
const packages = zip(workspace, await Promise.all(workspace.map(readDenoJson)));
37+
const stablePackages = packages.filter(([_, { version }]) => isStable(version));
38+
const unstablePackagePaths = packages
39+
.filter(([_, { version }]) => !isStable(version))
40+
.map(([path]) => join("std", path));
41+
const stableEntrypoints = stablePackages.flatMap(([dir, { exports }]) =>
42+
Object.values(exports)
43+
.filter((path) => !path.includes("unstable_"))
44+
.map((path) => new URL(`../${dir}/${path}`, import.meta.url).href)
45+
);
46+
47+
function isUnstableModule(specifier: string) {
48+
return unstablePackagePaths.some((path) => specifier.includes(path)) ||
49+
specifier.includes("unstable_");
50+
}
51+
52+
let hasError = false;
53+
for (const path of stableEntrypoints) {
54+
if (EXCEPTIONS.some((exception) => path.endsWith(exception))) {
55+
console.log(`Skip checking ${path}`);
56+
continue;
57+
}
58+
const graph = await createGraph(path, {
59+
resolve: resolveWorkspaceSpecifiers,
60+
});
61+
const dependencySpecifiers = graph.modules.map((m) => m.specifier);
62+
const unstableDependencies = dependencySpecifiers.filter(isUnstableModule);
63+
if (unstableDependencies.length > 0) {
64+
console.error(
65+
`Stable module ${path} imports unstable modules:`,
66+
unstableDependencies,
67+
);
68+
hasError = true;
69+
}
70+
}
71+
if (hasError) {
72+
Deno.exit(1);
73+
}
74+
console.log("No unstable module is used in stable modules.");

deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"lint:tools-types": "deno check _tools/*.ts",
1919
"lint:docs": "deno run -A _tools/check_docs.ts",
2020
"lint:import-map": "deno run -A _tools/check_import_map.ts",
21-
"lint": "deno lint && deno task fmt:licence-headers --check && deno task lint:circular && deno task lint:deprecations && deno task lint:tools-types && deno task lint:mod-exports && deno task lint:import-map && deno task lint:docs",
21+
"lint:unstable-deps": "deno run -A _tools/check_unstable_deps.ts",
22+
"lint": "deno lint && deno task fmt:licence-headers --check && deno task lint:circular && deno task lint:deprecations && deno task lint:tools-types && deno task lint:mod-exports && deno task lint:import-map && deno task lint:docs && deno task lint:unstable-deps",
2223
"typos": "typos -c ./.github/workflows/typos.toml",
2324
"build:crypto": "deno task --cwd crypto/_wasm wasmbuild",
2425
"wasmbuild": "deno run -A jsr:@deno/[email protected] --js-ext mjs --sync",

0 commit comments

Comments
 (0)