-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathpatch-project.ts
More file actions
125 lines (100 loc) · 3.89 KB
/
patch-project.ts
File metadata and controls
125 lines (100 loc) · 3.89 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import fs from 'node:fs';
import { glob } from 'node:fs/promises';
import { dirname, join, relative } from 'node:path';
import yaml from 'js-yaml';
import repos from './repo.json' with { type: 'json' };
const projectDir = import.meta.dirname;
const rootDir = join(projectDir, '..');
const tgzPath = rootDir;
const projects = Object.keys(repos);
const project = process.argv[2];
if (!projects.includes(project)) {
console.error(`Project ${project} is not defined in repo.json`);
process.exit(1);
}
// Read pnpm-workspace.yaml to get workspace patterns
const workspaceConfig = yaml.load(fs.readFileSync(join(rootDir, 'pnpm-workspace.yaml'), 'utf8')) as {
packages: string[];
};
// Use glob to find all package directories dynamically
async function discoverPackages(): Promise<[string, string][]> {
const packages: [string, string][] = [];
for (const pattern of workspaceConfig.packages) {
// Convert pnpm patterns (e.g., 'packages/*') to glob patterns for package.json
const globPattern = `${pattern}/package.json`;
for await (const entry of glob(globPattern, { cwd: rootDir })) {
const pkgJsonPath = join(rootDir, entry);
try {
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
// Skip private packages and packages without names
if (pkgJson.private || !pkgJson.name) continue;
const relativePath = dirname(relative(rootDir, pkgJsonPath));
packages.push([pkgJson.name, relativePath]);
} catch {
// Skip if package.json is invalid or cannot be read
console.warn(`Warning: Could not read ${pkgJsonPath}`);
}
}
}
return packages;
}
async function buildOverrides(): Promise<Record<string, string>> {
const packages = await discoverPackages();
const overrides: Record<string, string> = {};
for (const [name, path] of packages) {
const version = JSON.parse(fs.readFileSync(join(tgzPath, path, 'package.json'), 'utf8')).version;
const filename = `${name.replace('@', '').replace('/', '-')}-${version}.tgz`;
overrides[name] = `file:${tgzPath}/${filename}`;
}
return overrides;
}
async function patchPackageJSON(filePath: string, overrides: Record<string, string>): Promise<void> {
const packageJson = JSON.parse(fs.readFileSync(filePath, 'utf8'));
// Add overrides with tgz files
packageJson.overrides = {
...packageJson.overrides,
...overrides,
};
for (const name in packageJson.dependencies) {
const override = overrides[name];
if (override) {
packageJson.dependencies[name] = override;
}
}
for (const name in packageJson.devDependencies) {
const override = overrides[name];
if (override) {
packageJson.devDependencies[name] = override;
}
}
const packageJsonString = JSON.stringify(packageJson, null, 2) + '\n';
console.log(packageJsonString);
fs.writeFileSync(filePath, packageJsonString);
}
async function patchCnpmcore(overrides: Record<string, string>): Promise<void> {
const packageJsonPath = join(projectDir, 'cnpmcore', 'package.json');
await patchPackageJSON(packageJsonPath, overrides);
}
async function patchExamples(overrides: Record<string, string>): Promise<void> {
// https://github.com/eggjs/examples/tree/master/hello-tegg
let packageJsonPath = join(projectDir, 'examples', 'hello-tegg', 'package.json');
await patchPackageJSON(packageJsonPath, overrides);
// https://github.com/eggjs/examples/blob/master/helloworld/package.json
packageJsonPath = join(projectDir, 'examples', 'helloworld', 'package.json');
await patchPackageJSON(packageJsonPath, overrides);
}
async function main(): Promise<void> {
const overrides = await buildOverrides();
switch (project) {
case 'cnpmcore':
await patchCnpmcore(overrides);
break;
case 'examples':
await patchExamples(overrides);
break;
default:
console.error(`Project ${project} is not supported`);
process.exit(1);
}
}
main();