diff --git a/.yarn/versions/f772082a.yml b/.yarn/versions/f772082a.yml new file mode 100644 index 000000000000..788294e22c38 --- /dev/null +++ b/.yarn/versions/f772082a.yml @@ -0,0 +1,25 @@ +releases: + "@yarnpkg/cli": minor + "@yarnpkg/plugin-pack": minor + +declined: + - "@yarnpkg/plugin-catalog" + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/core" + - "@yarnpkg/doctor" diff --git a/packages/plugin-pack/sources/commands/pack.ts b/packages/plugin-pack/sources/commands/pack.ts index ea835f52d8d7..3da6fd03c6c6 100644 --- a/packages/plugin-pack/sources/commands/pack.ts +++ b/packages/plugin-pack/sources/commands/pack.ts @@ -34,6 +34,10 @@ export default class PackCommand extends BaseCommand { description: `Run a preliminary \`yarn install\` if the package contains build scripts`, }); + preserveWorkspaces = Option.Boolean(`--preserve-workspaces`, false, { + description: `Preserve the workspaces in the package manifest`, + }); + dryRun = Option.Boolean(`-n,--dry-run`, false, { description: `Print the file paths without actually generating the package archive`, }); @@ -89,7 +93,9 @@ export default class PackCommand extends BaseCommand { } if (!this.dryRun) { - const pack = await packUtils.genPackStream(workspace, files); + const pack = await packUtils.genPackStream(workspace, files, { + preserveWorkspaces: this.preserveWorkspaces, + }); await xfs.mkdirPromise(ppath.dirname(target), {recursive: true}); const write = xfs.createWriteStream(target); diff --git a/packages/plugin-pack/sources/index.ts b/packages/plugin-pack/sources/index.ts index 949292356aa3..acc224a538ce 100644 --- a/packages/plugin-pack/sources/index.ts +++ b/packages/plugin-pack/sources/index.ts @@ -7,6 +7,10 @@ import * as packUtils from './packUtils'; export {PackCommand}; export {packUtils}; +export type WorkspacePackingOptions = { + preserveWorkspaces?: boolean; +}; + export interface Hooks { /** * Called before a workspace is packed. The `rawManifest` value passed in @@ -16,13 +20,14 @@ export interface Hooks { beforeWorkspacePacking?: ( workspace: Workspace, rawManifest: object, + options: WorkspacePackingOptions, ) => Promise | void; } const DEPENDENCY_TYPES = [`dependencies`, `devDependencies`, `peerDependencies`]; const WORKSPACE_PROTOCOL = `workspace:`; -const beforeWorkspacePacking = (workspace: Workspace, rawManifest: any) => { +const beforeWorkspacePacking = (workspace: Workspace, rawManifest: any, options: WorkspacePackingOptions) => { if (rawManifest.publishConfig) { if (rawManifest.publishConfig.type) rawManifest.type = rawManifest.publishConfig.type; @@ -49,39 +54,41 @@ const beforeWorkspacePacking = (workspace: Workspace, rawManifest: any) => { const project = workspace.project; - for (const dependencyType of DEPENDENCY_TYPES) { - for (const descriptor of workspace.manifest.getForScope(dependencyType).values()) { - const matchingWorkspace = project.tryWorkspaceByDescriptor(descriptor); - const range = structUtils.parseRange(descriptor.range); - - if (range.protocol !== WORKSPACE_PROTOCOL) - continue; - - if (matchingWorkspace === null) { - if (project.tryWorkspaceByIdent(descriptor) === null) { - throw new ReportError(MessageName.WORKSPACE_NOT_FOUND, `${structUtils.prettyDescriptor(project.configuration, descriptor)}: No local workspace found for this range`); + if (!options.preserveWorkspaces) { + for (const dependencyType of DEPENDENCY_TYPES) { + for (const descriptor of workspace.manifest.getForScope(dependencyType).values()) { + const matchingWorkspace = project.tryWorkspaceByDescriptor(descriptor); + const range = structUtils.parseRange(descriptor.range); + + if (range.protocol !== WORKSPACE_PROTOCOL) + continue; + + if (matchingWorkspace === null) { + if (project.tryWorkspaceByIdent(descriptor) === null) { + throw new ReportError(MessageName.WORKSPACE_NOT_FOUND, `${structUtils.prettyDescriptor(project.configuration, descriptor)}: No local workspace found for this range`); + } + } else { + let versionToWrite: string; + + // For workspace:path/to/workspace and workspace:* we look up the workspace version + if (structUtils.areDescriptorsEqual(descriptor, matchingWorkspace.anchoredDescriptor) || range.selector === `*`) + versionToWrite = matchingWorkspace.manifest.version ?? `0.0.0`; + // For workspace:~ and workspace:^ we add the selector in front of the workspace version + else if (range.selector === `~` || range.selector === `^`) + versionToWrite = `${range.selector}${matchingWorkspace.manifest.version ?? `0.0.0`}`; + else + // for workspace:version we simply strip the protocol + versionToWrite = range.selector; + + // Ensure optional dependencies are handled as well + const identDescriptor = dependencyType === `dependencies` + ? structUtils.makeDescriptor(descriptor, `unknown`) + : null; + const finalDependencyType = identDescriptor !== null && workspace.manifest.ensureDependencyMeta(identDescriptor).optional + ? `optionalDependencies` + : dependencyType; + rawManifest[finalDependencyType][structUtils.stringifyIdent(descriptor)] = versionToWrite; } - } else { - let versionToWrite: string; - - // For workspace:path/to/workspace and workspace:* we look up the workspace version - if (structUtils.areDescriptorsEqual(descriptor, matchingWorkspace.anchoredDescriptor) || range.selector === `*`) - versionToWrite = matchingWorkspace.manifest.version ?? `0.0.0`; - // For workspace:~ and workspace:^ we add the selector in front of the workspace version - else if (range.selector === `~` || range.selector === `^`) - versionToWrite = `${range.selector}${matchingWorkspace.manifest.version ?? `0.0.0`}`; - else - // for workspace:version we simply strip the protocol - versionToWrite = range.selector; - - // Ensure optional dependencies are handled as well - const identDescriptor = dependencyType === `dependencies` - ? structUtils.makeDescriptor(descriptor, `unknown`) - : null; - const finalDependencyType = identDescriptor !== null && workspace.manifest.ensureDependencyMeta(identDescriptor).optional - ? `optionalDependencies` - : dependencyType; - rawManifest[finalDependencyType][structUtils.stringifyIdent(descriptor)] = versionToWrite; } } } diff --git a/packages/plugin-pack/sources/packUtils.ts b/packages/plugin-pack/sources/packUtils.ts index 636bd8c44eb6..8465984d987f 100644 --- a/packages/plugin-pack/sources/packUtils.ts +++ b/packages/plugin-pack/sources/packUtils.ts @@ -5,7 +5,7 @@ import mm fr import tar from 'tar-stream'; import {createGzip} from 'zlib'; -import {Hooks} from './'; +import {Hooks, WorkspacePackingOptions} from './'; const NEVER_IGNORE = [ `/package.json`, @@ -67,7 +67,7 @@ export async function prepareForPack(workspace: Workspace, {report}: {report: Re } } -export async function genPackStream(workspace: Workspace, files?: Array) { +export async function genPackStream(workspace: Workspace, files?: Array, options: WorkspacePackingOptions = {}) { if (typeof files === `undefined`) files = await genPackList(workspace); @@ -118,7 +118,7 @@ export async function genPackStream(workspace: Workspace, files?: Array { +export async function genPackageManifest(workspace: Workspace, options: WorkspacePackingOptions = {}): Promise { const data = JSON.parse(JSON.stringify(workspace.manifest.raw)); await workspace.project.configuration.triggerHook( (hooks: Hooks) => hooks.beforeWorkspacePacking, workspace, data, + options, ); return data;