-
Notifications
You must be signed in to change notification settings - Fork 195
Expand file tree
/
Copy pathcheck-plugin-version-pr.ts
More file actions
executable file
·105 lines (85 loc) · 3.16 KB
/
Copy pathcheck-plugin-version-pr.ts
File metadata and controls
executable file
·105 lines (85 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env node
/**
* PR Plugin Version Check
*
* Validates that all plugin.json files use the "0.0.0-placeholder" version.
* Real versions are stamped at build time by NBGV, so the source should
* never contain a real version number.
*/
import * as fs from "node:fs";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const PLUGIN_RELATIVE_PATHS = [
".plugin/plugin.json",
".claude-plugin/plugin.json",
".cursor-plugin/plugin.json"
] as const;
const EXPECTED_VERSION = "0.0.0-placeholder";
function getPluginDirectoryNames(repoRoot: string): string[] {
const pluginsRoot = path.resolve(repoRoot, "plugins");
if (!fs.existsSync(pluginsRoot)) {
return [];
}
return fs
.readdirSync(pluginsRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort();
}
function getPluginJsonPaths(repoRoot: string, pluginDirname: string): string[] {
const pluginRoot = path.resolve(repoRoot, "plugins", pluginDirname);
return PLUGIN_RELATIVE_PATHS.map(relativePath => path.resolve(pluginRoot, relativePath));
}
interface PluginConfig {
version: string;
[key: string]: unknown;
}
/**
* Check that all plugin.json files have the placeholder version.
*/
function checkPluginVersionPlaceholders(): void {
const repoRoot = path.resolve(__dirname, "../..");
const pluginDirs = getPluginDirectoryNames(repoRoot);
let hasErrors = false;
if (pluginDirs.length === 0) {
console.log(" ℹ️ No plugin directories found under plugins/, skipping...");
}
for (const pluginDir of pluginDirs) {
const pluginJsonPaths = getPluginJsonPaths(repoRoot, pluginDir);
for (let index = 0; index < pluginJsonPaths.length; index += 1) {
const fullPath = pluginJsonPaths[index];
const relativePath = PLUGIN_RELATIVE_PATHS[index];
const displayPath = path.join("plugins", pluginDir, relativePath).replace(/\\/g, "/");
if (!fs.existsSync(fullPath)) {
console.log(` ℹ️ ${displayPath} not found, skipping...`);
continue;
}
const content = fs.readFileSync(fullPath, "utf8");
const json: PluginConfig = JSON.parse(content);
if (json.version === EXPECTED_VERSION) {
console.log(` ✅ ${displayPath}: version is "${EXPECTED_VERSION}"`);
} else {
console.error(` ❌ ${displayPath}: expected version "${EXPECTED_VERSION}", found "${json.version}"`);
hasErrors = true;
}
}
}
if (hasErrors) {
console.error("\n❌ Plugin version check failed!");
console.error(" Plugin versions are stamped automatically at build time by NBGV.");
console.error(` Source files must always use "${EXPECTED_VERSION}".\n`);
process.exit(1);
} else {
console.log("\n✅ All plugin.json files have the correct placeholder version.");
}
}
function main(): void {
console.log("🔍 Checking plugin.json versions are placeholders...\n");
checkPluginVersionPlaceholders();
}
if (__filename === path.resolve(process.argv[1])) {
main();
}
export { checkPluginVersionPlaceholders, type PluginConfig };