forked from silexlabs/Silex
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsort-internal-deps.js
More file actions
executable file
·145 lines (126 loc) · 4.98 KB
/
sort-internal-deps.js
File metadata and controls
executable file
·145 lines (126 loc) · 4.98 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env node
import { readFileSync } from 'fs';
import path from 'path';
import { DepGraph } from 'dependency-graph';
import * as glob from 'glob';
// Ce script est utilisé pour trier les dépendances internes des packages dans le monorepo.
// Il génère un graphe de dépendances et effectue un tri topologique pour afficher l'ordre des packages.
// Il peut également filtrer les packages sans dépendances internes et afficher les dépendances internes si nécessaire.
function usage() {
console.log('Usage: ./scripts/sort-internal-deps.js [options] [package-name]');
console.log('Options:');
console.log(' --help, -h Show this help message');
console.log(' --hide-empty Hide packages without internal dependencies');
console.log(' --show-internal-deps Show internal dependencies');
console.log(' [package-name] Display the dependencies of a specific package');
console.log('Examples:');
console.log(' ./scripts/sort-internal-deps.js');
console.log(' ./scripts/sort-internal-deps.js --hide-empty');
console.log(' ./scripts/sort-internal-deps.js --show-internal-deps');
console.log(' ./scripts/sort-internal-deps.js @silexlabs/silex');
console.log(' ./scripts/sort-internal-deps.js @silexlabs/silex --hide-empty');
process.exit(0);
}
console.log('Display internal dependencies of packages in the monorepo sorted by dependency order');
// Usage
if (process.argv.includes('--help') || process.argv.includes('-h')) {
usage();
}
// Récup du flag pour cacher les packages qui n'ont pas de dépendances internes
const hideEmpty = process.argv.includes('--hide-empty');
if (hideEmpty) {
console.log('Hiding packages without internal dependencies');
}
// Flag pour afficher les dépendances internes
const showInternalDeps = process.argv.includes('--show-internal-deps');
if (showInternalDeps) {
console.log('Showing internal dependencies');
}
// Trouver l'argument non positionnel
const nonPositionalArgs = process.argv.filter(arg => !arg.startsWith('-') && !arg.startsWith('/'));
if (nonPositionalArgs.length > 0) {
const pkgName = nonPositionalArgs[0];
if (pkgName) {
console.log(`Displaying dependencies for package: ${pkgName}`);
}
}
// Étape 1 : trouver tous les packages internes valides
const currentScript = process.argv[1];
const scriptDir = path.dirname(currentScript);
const packagesDir = path.join(scriptDir, '..', 'packages');
const packagePaths = glob.sync(`${packagesDir}/**/package.json`, {
ignore: '**/node_modules/**',
});
const internalPackages = {};
for (const pkgPath of packagePaths) {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
const isInternal = pkgPath.match(/\/packages\//) && pkgPath.match(/\/packages\/[^/]+\/package.json$/);
if (pkg.name && isInternal) {
internalPackages[pkg.name] = pkgPath;
}
}
// Étape 2 : construire le graphe
const graph = new DepGraph();
Object.keys(internalPackages).forEach(pkgName => graph.addNode(pkgName));
for (const [pkgName, pkgPath] of Object.entries(internalPackages)) {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
const deps = {
...pkg.dependencies,
...pkg.devDependencies,
...pkg.peerDependencies,
};
for (const depName of Object.keys(deps || {})) {
if (internalPackages[depName]) {
graph.addDependency(pkgName, depName);
}
}
}
// Étape 3 : tri topologique
try {
if (nonPositionalArgs.length > 0) {
if (showInternalDeps) {
console.error(`Not implemented: cannot show internal dependencies for a specific package's dependencies`);
process.exit(1);
}
const pkgName = nonPositionalArgs[0];
const pkgPath = internalPackages[pkgName];
if (!pkgPath) {
console.error(`Package ${pkgName} not found`);
process.exit(1);
}
const deps = graph.dependenciesOf(pkgName);
const filteredDeps = deps.filter(dep => internalPackages[dep]);
if (hideEmpty) {
const filteredSortedDeps = filteredDeps.filter(dep => graph.directDependenciesOf(dep).length > 0);
console.log(`Dependencies of ${pkgName}:\n- ${filteredSortedDeps.join('\n- ')}`);
} else {
console.log(`Dependencies of ${pkgName}:\n- ${filteredDeps.join('\n- ')}`);
}
if (filteredDeps.length === 0) {
console.log(`No dependencies found for ${pkgName}`);
}
} else {
const ordered = graph.overallOrder();
ordered.forEach((pkg, i) => {
const deps = graph.directDependenciesOf(pkg);
if (!hideEmpty || deps.length > 0) {
const name = internalPackages[pkg]
.replace(/.*\/packages\//, '')
.replace(/\/package.json$/, '');
if (showInternalDeps) {
console.log(`- ${pkg}\n${deps.map(dep => ` | ${dep}\n`).join('')}`);
} else {
console.log(`- ${name}`);
}
}
});
}
} catch (err) {
console.error('\n⛔️ Dependency cycle detected among internal packages:');
if (err.cyclePath) {
console.error(' → ' + err.cyclePath.join(' → '));
} else {
console.error(err);
}
process.exit(1);
}