Skip to content

Instantly share code, notes, and snippets.

@renatoaraujoc
Last active May 15, 2023 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renatoaraujoc/57221c43f3e9ed2e8577c6a9d8355238 to your computer and use it in GitHub Desktop.
Save renatoaraujoc/57221c43f3e9ed2e8577c6a9d8355238 to your computer and use it in GitHub Desktop.
[Nx] Syncs all buildable libraries peerDependencies with root's package.json ones and updates its version.
import { execSync } from 'child_process';
import fs from 'fs';
import { ProjectGraph } from 'nx-cloud/lib/core/models/run-context.model';
import path from 'path';
// Get a list of all projects in the workspace
execSync('npx nx dep-graph --file=dep-graph.json');
const depGraphData = JSON.parse(fs.readFileSync('dep-graph.json', 'utf-8'));
// get root package.json data dependencies
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
const packageJsonDeps = new Map<string, string>();
for (const dep in packageJson.dependencies) {
packageJsonDeps.set(dep, packageJson.dependencies[dep]);
}
// resolve all buildable libraries peerDependencies
Object.entries((depGraphData.graph as ProjectGraph).nodes).forEach(
([projectName, projectData]) => {
const projectPath = path.join(process.cwd(), projectData.data.root);
// if it's not a lib, skip it
if (!projectData.data.root.startsWith('libs')) {
return;
}
const isLibBuildable = fs.existsSync(
path.join(projectPath, 'package.json')
);
// if its not buildable, skip it
if (!isLibBuildable) {
return;
}
// get all external dependencies
const depCruiseFile = `dep-cruise-${projectName}.json`;
execSync(
`npx depcruise --exclude 'test-setup.ts' --ts-pre-compilation-deps --output-type json --output-to '${depCruiseFile}' '${projectPath}'`,
{ encoding: 'utf-8' }
);
const depGraph = JSON.parse(fs.readFileSync(depCruiseFile, 'utf-8'));
let externalDeps: string[] = [];
for (const module of depGraph.modules) {
for (const dep of module.dependencies) {
for (const [pkgDep] of packageJsonDeps) {
if (dep.resolved.match(new RegExp(`${pkgDep}\/`))) {
externalDeps.push(pkgDep);
}
}
}
}
// sort the external dependencies
externalDeps = Array.from(new Set([...externalDeps].sort()));
// sync!
const libsPackageJson = JSON.parse(
fs.readFileSync(path.join(projectPath, 'package.json'), 'utf-8')
);
// sync version
libsPackageJson.version = packageJson.version;
// sync peerDependencies
libsPackageJson.peerDependencies =
externalDeps.length > 0
? externalDeps.reduce(
(acc, next) => ({
...acc,
[next]: packageJsonDeps.get(next)
}),
{}
)
: {};
console.log(
`Syncing to '${projectName}' package.json...\n- ${externalDeps.length} peerDependencies\n- version ${packageJson.version}\n`
);
fs.writeFileSync(
path.join(projectPath, 'package.json'),
JSON.stringify(libsPackageJson, null, 4)
);
// delete the tmp depCruise file
fs.unlinkSync(depCruiseFile);
}
);
// Delete the dep-graph.json file
fs.unlinkSync('dep-graph.json');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment