diff --git a/e2e/harmony/link.e2e.ts b/e2e/harmony/link.e2e.ts index 40361d707a47..ac302980d55e 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/component/testing/mock-components/mock-components.ts b/scopes/component/testing/mock-components/mock-components.ts index 7b190d90e73a..98c52e74d73b 100644 --- a/scopes/component/testing/mock-components/mock-components.ts +++ b/scopes/component/testing/mock-components/mock-components.ts @@ -35,7 +35,7 @@ export async function mockComponents( }); await workspace.bitMap.write(); const install = harmony.get(InstallAspect.id); - await install.link({ rewire: true }); + await install.link([], { rewire: true }); const compiler = harmony.get(CompilerAspect.id); await compiler.compileOnWorkspace(); diff --git a/scopes/workspace/install/install.main.runtime.ts b/scopes/workspace/install/install.main.runtime.ts index f2ce4b3623bc..aaa97329937f 100644 --- a/scopes/workspace/install/install.main.runtime.ts +++ b/scopes/workspace/install/install.main.runtime.ts @@ -312,7 +312,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, @@ -1078,10 +1078,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, @@ -1108,8 +1109,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, @@ -1209,7 +1211,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 29a519a64247..2e25c9415893 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; } }