diff --git a/e2e/harmony/link.e2e.ts b/e2e/harmony/link.e2e.ts index 40361d707a4..ac302980d55 100644 --- a/e2e/harmony/link.e2e.ts +++ b/e2e/harmony/link.e2e.ts @@ -21,6 +21,25 @@ describe('linking to a target', function () { }); }); +describe('linking a subset of components to a target', function () { + this.timeout(0); + let helper: Helper; + let targetDir: string; + before(() => { + helper = new Helper(); + helper.scopeHelper.setNewLocalAndRemoteScopes(); + helper.fixtures.populateComponents(2); + targetDir = globalBitTempDir(); + helper.command.link(`comp1 --target=${targetDir}`); + }); + it('should link the scecified component to the target directory', () => { + expect(path.join(targetDir, `node_modules/@${helper.scopes.remote}/comp1`)).to.be.a.path(); + }); + it('should not link the not specified component to the target directory', () => { + expect(path.join(targetDir, `node_modules/@${helper.scopes.remote}/comp2`)).not.to.be.a.path(); + }); +}); + describe('linking to a target including peers', function () { this.timeout(0); let helper: Helper; diff --git a/scopes/workspace/install/install.main.runtime.ts b/scopes/workspace/install/install.main.runtime.ts index d3d0bb39e86..ffd070632e2 100644 --- a/scopes/workspace/install/install.main.runtime.ts +++ b/scopes/workspace/install/install.main.runtime.ts @@ -296,7 +296,7 @@ export class InstallMain { linkDepsResolvedFromEnv: !hasRootComponents, linkNestedDepsInNM: !this.workspace.isLegacy && !hasRootComponents, }; - const { linkedRootDeps } = await this.calculateLinks(linkOpts); + const { linkedRootDeps } = await this.calculateLinks([], linkOpts); // eslint-disable-next-line prefer-const let { mergedRootPolicy, componentsAndManifests: current } = await this._getComponentsManifestsAndRootPolicy( installer, @@ -858,10 +858,11 @@ export class InstallMain { * This information may then be passed to the package manager, which will create the links on its own. */ async calculateLinks( + ids: ComponentID[], options: WorkspaceLinkOptions = {} ): Promise<{ linkResults: WorkspaceLinkResults; linkedRootDeps: Record }> { await pMapSeries(this.preLinkSlot.values(), (fn) => fn(options)); // import objects if not disabled in options - const compDirMap = await this.getComponentsDirectory([]); + const compDirMap = await this.getComponentsDirectory(ids); const linker = this.dependencyResolver.getLinker({ rootDir: this.workspace.path, linkingOptions: options, @@ -888,8 +889,9 @@ export class InstallMain { return linkToNodeModulesWithCodemod(this.workspace, bitIds, options?.rewire ?? false); } - async link(options: WorkspaceLinkOptions = {}): Promise { - const { linkResults, linkedRootDeps } = await this.calculateLinks(options); + async link(ids: string[], options: WorkspaceLinkOptions = {}): Promise { + const componentIds = await Promise.all(ids.map((id) => this.workspace.resolveComponentId(id))); + const { linkResults, linkedRootDeps } = await this.calculateLinks(componentIds, options); await createLinks(options.linkToDir ?? this.workspace.path, linkedRootDeps, { avoidHardLink: true, skipIfSymlinkValid: true, @@ -986,7 +988,7 @@ export class InstallMain { return; } if (needLink) { - await this.link(); + await this.link([]); } } diff --git a/scopes/workspace/install/link/link.cmd.ts b/scopes/workspace/install/link/link.cmd.ts index 29a519a6424..2e25c941589 100644 --- a/scopes/workspace/install/link/link.cmd.ts +++ b/scopes/workspace/install/link/link.cmd.ts @@ -95,7 +95,7 @@ export class LinkCommand implements Command { fetchObject: !opts.skipFetchingObjects, includePeers: opts.peers, }; - const linkResults = await this.install.link(linkOpts); + const linkResults = await this.install.link(ids ?? [], linkOpts); return linkResults; } }