Skip to content

Commit 9d0635b

Browse files
tools: add validation for internal bindings
1 parent 578a893 commit 9d0635b

File tree

5 files changed

+697
-0
lines changed

5 files changed

+697
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Internal Bindings Validation
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, ready_for_review]
6+
paths:
7+
- src/**
8+
- lib/**
9+
- test/**
10+
push:
11+
branches:
12+
- main
13+
- canary
14+
- v[0-9]+.x-staging
15+
- v[0-9]+.x
16+
- dario/58162/internal-bindings-validation
17+
paths:
18+
- src/**
19+
- lib/**
20+
- test/**
21+
22+
concurrency:
23+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
24+
cancel-in-progress: true
25+
26+
permissions:
27+
contents: read
28+
29+
jobs:
30+
test-internal-binding-validation:
31+
if: github.event.pull_request.draft == false
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
35+
with:
36+
persist-credentials: false
37+
path: node
38+
- name: Validate internal binding functions typing
39+
run: |
40+
node ./tools/internal-bindings-functions-validation/typings.mjs
41+
- name: Validate internal binding functions usage
42+
run: |
43+
node ./tools/internal-bindings-functions-validation/usage.mjs
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
When a function is defined in the C++ layer, it can be registered to an internal binding, making it accessible from the JavaScript layer. The scripts in this directory provide automated validation for this process. Specifically, there are two scripts:
2+
3+
- `typings.mjs`: Ensures that every function registered to an internal binding has a corresponding type defined in the [typings directory](../../typings).
4+
- `usage.mjs`: Verifies that every function registered to an internal binding is utilized in at least one JavaScript file, either in the [lib directory](../../lib) or the [test directory](../../test).
5+
6+
Note: This validation is a best-effort approach that relies on reading file contents and using regular expressions for the checks. It can be enhanced over time if necessary.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { globSync, readFileSync } from 'node:fs';
2+
import { relative, dirname } from 'node:path';
3+
import { readFile } from 'node:fs/promises';
4+
import { fileURLToPath } from 'node:url';
5+
6+
export const __dirname = dirname(fileURLToPath(import.meta.url));
7+
8+
const srcFiles = globSync(`${__dirname}/../../src/**/*.cc`);
9+
10+
export const declaredSrcFunctions = (
11+
await Promise.all(
12+
srcFiles.map(async (srcFile) => {
13+
const srcFilePath = relative(`${__dirname}/../..`, srcFile);
14+
15+
const srcFileContents = await readFile(srcFile, 'utf8');
16+
const matches = srcFileContents.matchAll(
17+
/\b(SetMethod|SetMethodNoSideEffect)\([^,]*,\s+[^,]*,\s+"(?<functionName>.*?)",\s+[^)]*?\);/g
18+
);
19+
return [...matches].map((match) => {
20+
const { functionName } = match.groups;
21+
return { srcFilePath, functionName };
22+
});
23+
})
24+
)
25+
)
26+
.filter((declarations) => declarations.length)
27+
.flat();
28+
29+
export function functionPresentInJsFiles(files, functionName) {
30+
return files.some((file) => {
31+
const fileContents = readFileSync(file);
32+
return new RegExp(`\\b${functionName}\\b`).test(fileContents);
33+
});
34+
}

0 commit comments

Comments
 (0)