forked from microsoft/fluentui-react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheckDependencies.js
More file actions
105 lines (85 loc) · 3.58 KB
/
checkDependencies.js
File metadata and controls
105 lines (85 loc) · 3.58 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
// @ts-check
/**
* Quick and dirty script to ensure we have got our nested peerDependencies correct
*
* Any package that depends on a package within the repo, that has a peerDependency, should also have that dependency declared as a peerDependency
* Also, peerDependencies for additional platforms should be marked as optional peerDependencies
*/
import { readFileSync, writeFileSync } from 'node:fs';
import { findGitRoot, getPackageInfos } from 'workspace-tools';
export function checkDependencies() {
let requireRescan = true;
let everWrote = false;
// These packages should be optional peers, since not all consumers may require all platforms
const optionalPeers = ['react-native-windows', '@office-iss/react-native-win32', 'react-native-macos'];
while (requireRescan) {
requireRescan = false;
const infos = getPackageInfos(findGitRoot(process.cwd()));
// getPackageInfos unfortunately doesn't provide peerDependenciesMeta, so we need to parse the whole package.json
for (const pkgName in infos) {
infos[pkgName].pkgJson = JSON.parse(readFileSync(infos[pkgName].packageJsonPath).toString());
}
for (const pkgName in infos) {
// App packages don't have npm consumers, so peerDependency propagation doesn't apply
if (infos[pkgName].pkgJson['rnx-kit']?.kitType === 'app') continue;
const deps = { ...infos[pkgName].dependencies, ...infos[pkgName].peerDependencies };
/** @type {{ name: string, version: string }[]} */
const missingPeerDeps = [];
/** @type {string[]} */
const missingPeerDepsMeta = [];
for (const dep in deps) {
if (infos[dep]) {
for (const peerDep in infos[dep].peerDependencies) {
if (!deps[peerDep]) {
if (!missingPeerDeps.some((missingDep) => missingDep.name === peerDep)) {
missingPeerDeps.push({ name: peerDep, version: infos[dep].peerDependencies[peerDep] });
if (optionalPeers.includes(peerDep)) {
missingPeerDepsMeta.push(peerDep);
}
}
}
}
}
}
for (const peerDep in infos[pkgName].peerDependencies) {
if (optionalPeers.includes(peerDep)) {
if (!infos[pkgName].pkgJson.peerDependenciesMeta || !infos[pkgName].pkgJson.peerDependenciesMeta[peerDep]) {
missingPeerDepsMeta.push(peerDep);
}
}
}
let requireWriteFile = false;
if (missingPeerDeps.length !== 0) {
if (!infos[pkgName].pkgJson.peerDependencies) {
infos[pkgName].pkgJson.peerDependencies = {};
}
for (const missingDep of missingPeerDeps) {
infos[pkgName].pkgJson.peerDependencies[missingDep.name] = missingDep.version;
}
requireWriteFile = true;
}
if (missingPeerDepsMeta.length !== 0) {
if (!infos[pkgName].pkgJson.peerDependenciesMeta) {
infos[pkgName].pkgJson.peerDependenciesMeta = {};
}
for (const missingMeta of missingPeerDepsMeta) {
infos[pkgName].pkgJson.peerDependenciesMeta[missingMeta] = {
optional: true,
};
}
requireWriteFile = true;
}
if (requireWriteFile) {
writeFileSync(infos[pkgName].packageJsonPath, JSON.stringify(infos[pkgName].pkgJson, null, 2));
everWrote = true;
requireRescan = true;
}
// Run the whole process again, since we have more peerDependencies to track now
}
}
if (everWrote) {
const errorMsg = `Required package dependencies updated.`;
console.error(errorMsg);
throw errorMsg;
}
}