cli: migrate packager to use PackageGraph

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-01-07 13:10:23 +01:00
parent f202e2a90b
commit de4f500c22
2 changed files with 35 additions and 57 deletions
+14 -2
View File
@@ -16,13 +16,24 @@
import { Package } from '@manypkg/get-packages';
type PackageJSON = Package['packageJson'];
export interface ExtendedPackageJSON extends PackageJSON {
scripts?: {
[key: string]: string;
};
// The `bundled` field is a field known within Backstage, it means
// that the package bundles all of its dependencies in its build output.
bundled?: boolean;
}
export type PackageGraphNode = {
/** The name of the package */
name: string;
/** The directory of the package */
dir: string;
/** The package data of the package itself */
packageJson: Package['packageJson'];
packageJson: ExtendedPackageJSON;
/** All direct local dependencies of the package */
allLocalDependencies: Map<string, PackageGraphNode>;
/** All direct local dependencies that will be present in the published package */
@@ -50,8 +61,9 @@ export class PackageGraph extends Map<string, PackageGraphNode> {
}
graph.set(name, {
...pkg,
name,
dir: pkg.dir,
packageJson: pkg.packageJson as ExtendedPackageJSON,
allLocalDependencies: new Map(),
publishedLocalDependencies: new Map(),
localDependencies: new Map(),
+21 -55
View File
@@ -29,6 +29,8 @@ import {
dependencies as cliDependencies,
devDependencies as cliDevDependencies,
} from '../../../package.json';
import { getPackages } from '@manypkg/get-packages';
import { PackageGraph, PackageGraphNode } from '../monorepo';
// These packages aren't safe to pack in parallel since the CLI depends on them
const UNSAFE_PACKAGES = [
@@ -36,14 +38,6 @@ const UNSAFE_PACKAGES = [
...Object.keys(cliDevDependencies),
];
type LernaPackage = {
name: string;
private: boolean;
location: string;
scripts: Record<string, string>;
get(key: string): any;
};
type FileEntry =
| string
| {
@@ -102,7 +96,17 @@ export async function createDistWorkspace(
options.targetDir ??
(await fs.mkdtemp(resolvePath(tmpdir(), 'dist-workspace')));
const targets = await findTargetPackages(packageNames);
const { packages } = await getPackages(paths.targetDir);
const packageGraph = PackageGraph.fromPackages(packages);
const targetNames = packageGraph.collectPackageNames(packageNames, node => {
// Don't include dependencies of packages that are marked as bundled
if (node.packageJson.bundled) {
return undefined;
}
return node.publishedLocalDependencies.keys();
});
const targets = Array.from(targetNames).map(name => packageGraph.get(name)!);
if (options.buildDependencies) {
const exclude = options.buildExcludes ?? [];
@@ -133,7 +137,7 @@ export async function createDistWorkspace(
if (options.skeleton) {
const skeletonFiles = targets.map(target => {
const dir = relativePath(paths.targetRoot, target.location);
const dir = relativePath(paths.targetRoot, target.dir);
return joinPath(dir, 'package.json');
});
@@ -154,21 +158,21 @@ export async function createDistWorkspace(
async function moveToDistWorkspace(
workspaceDir: string,
localPackages: LernaPackage[],
localPackages: PackageGraphNode[],
): Promise<void> {
async function pack(target: LernaPackage, archive: string) {
async function pack(target: PackageGraphNode, archive: string) {
console.log(`Repacking ${target.name} into dist workspace`);
const archivePath = resolvePath(workspaceDir, archive);
await run('yarn', ['pack', '--filename', archivePath], {
cwd: target.location,
cwd: target.dir,
});
// TODO(Rugvip): yarn pack doesn't call postpack, once the bug is fixed this can be removed
if (target.scripts.postpack) {
await run('yarn', ['postpack'], { cwd: target.location });
if (target.packageJson?.scripts?.postpack) {
await run('yarn', ['postpack'], { cwd: target.dir });
}
const outputDir = relativePath(paths.targetRoot, target.location);
const outputDir = relativePath(paths.targetRoot, target.dir);
const absoluteOutputPath = resolvePath(workspaceDir, outputDir);
await fs.ensureDir(absoluteOutputPath);
@@ -181,7 +185,7 @@ async function moveToDistWorkspace(
// We remove the dependencies from package.json of packages that are marked
// as bundled, so that yarn doesn't try to install them.
if (target.get('bundled')) {
if (target.packageJson.bundled) {
const pkgJson = await fs.readJson(
resolvePath(absoluteOutputPath, 'package.json'),
);
@@ -220,41 +224,3 @@ async function moveToDistWorkspace(
),
);
}
async function findTargetPackages(pkgNames: string[]): Promise<LernaPackage[]> {
const { Project } = require('@lerna/project');
const { PackageGraph } = require('@lerna/package-graph');
const project = new Project(paths.targetDir);
const packages = await project.getPackages();
const graph = new PackageGraph(packages);
const targets = new Map<string, any>();
const searchNames = pkgNames.slice();
while (searchNames.length) {
const name = searchNames.pop()!;
if (targets.has(name)) {
continue;
}
const node = graph.get(name);
if (!node) {
throw new Error(`Package '${name}' not found`);
}
// Don't include dependencies of packages that are marked as bundled
if (!node.pkg.get('bundled')) {
const pkgDeps = Object.keys(node.pkg.dependencies ?? {});
const localDeps: string[] = Array.from(node.localDependencies.keys());
const filteredDeps = localDeps.filter(dep => pkgDeps.includes(dep));
searchNames.push(...filteredDeps);
}
targets.set(name, node.pkg);
}
return Array.from(targets.values());
}