Skip to content

Commit 89064e4

Browse files
committed
collect peer deps of projects dependencies
1 parent 9b8f5f7 commit 89064e4

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

packages/cli/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import childProcess from 'child_process';
1010
import {Command as CommanderCommand} from 'commander';
1111
import path from 'path';
1212
import {detachedCommands, projectCommands} from './commands';
13+
import installTransitiveDeps from './tools/resolveTransitiveDeps';
1314

1415
const pkgJson = require('../package.json');
1516

@@ -172,6 +173,9 @@ async function setupAndRun() {
172173
}
173174
}
174175

176+
// are peer dependencies installed?
177+
await installTransitiveDeps();
178+
175179
let config: Config | undefined;
176180
try {
177181
config = loadConfig();
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import path from 'path';
2+
import fs from 'fs-extra';
3+
import {logger} from '@react-native-community/cli-tools';
4+
import chalk from 'chalk';
5+
import {prompt} from 'prompts';
6+
7+
interface DependencyInfo {
8+
path: string;
9+
peerDependencies: {[key: string]: string};
10+
}
11+
12+
function getPeerDependencies(root: string): Map<string, DependencyInfo> {
13+
const packageJsonPath = path.join(root, 'package.json');
14+
const packageJson = require(packageJsonPath);
15+
16+
const dependenciesAndPeerDependencies = new Map<string, DependencyInfo>();
17+
18+
for (const dependency in {...packageJson.dependencies}) {
19+
const dependencyPath = path.join(root, 'node_modules', dependency);
20+
21+
if (fs.existsSync(dependencyPath)) {
22+
const packageJsonPath = path.join(dependencyPath, 'package.json');
23+
const packageJson = require(packageJsonPath);
24+
25+
if (
26+
packageJson.peerDependencies &&
27+
!dependenciesAndPeerDependencies.has(dependency)
28+
) {
29+
dependenciesAndPeerDependencies.set(dependency, {
30+
path: dependencyPath,
31+
peerDependencies: packageJson.peerDependencies,
32+
});
33+
}
34+
}
35+
}
36+
37+
return dependenciesAndPeerDependencies;
38+
}
39+
40+
function excludeInstalledPeerDependencies(
41+
root: string,
42+
peerDependencies: Map<string, DependencyInfo>,
43+
) {
44+
const missingPeerDependencies: Record<string, Record<string, string>> = {};
45+
46+
peerDependencies.forEach((value, key) => {
47+
const missingDeps = Object.entries(value.peerDependencies).reduce(
48+
(missingDepsList, [name, version]) => {
49+
const rootPath = path.join(root, 'node_modules', name);
50+
if (!fs.existsSync(rootPath)) {
51+
missingDepsList[name] = version;
52+
}
53+
return missingDepsList;
54+
},
55+
{},
56+
);
57+
58+
if (Object.keys(missingDeps).length > 0) {
59+
missingPeerDependencies[key] = missingDeps;
60+
}
61+
});
62+
63+
return missingPeerDependencies;
64+
}
65+
66+
export default async function installTransitiveDeps() {
67+
const root = process.cwd();
68+
69+
const peerDependencies = getPeerDependencies(root);
70+
const depsToInstall = excludeInstalledPeerDependencies(
71+
root,
72+
peerDependencies,
73+
);
74+
const dependenciesWithMissingDeps = Object.keys(depsToInstall);
75+
if (dependenciesWithMissingDeps.length > 0) {
76+
logger.warn(
77+
`Looks like you are missing some of the peer dependencies of your libraries:
78+
${dependenciesWithMissingDeps.map(
79+
(dep) =>
80+
`${chalk.bold(dep)}:\n ${Object.keys(depsToInstall[dep]).map(
81+
(d) => `\t-${d}\n`,
82+
)}`,
83+
)}`,
84+
);
85+
const {install} = await prompt({
86+
type: 'confirm',
87+
name: 'install',
88+
message: 'Do you want to install them now?',
89+
});
90+
console.log({install});
91+
}
92+
}

0 commit comments

Comments
 (0)