Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(link): it should be possible to link a subset of components from the workspace #8497

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions e2e/harmony/link.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions scopes/workspace/install/install.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<string, string> }> {
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,
Expand All @@ -888,8 +889,9 @@ export class InstallMain {
return linkToNodeModulesWithCodemod(this.workspace, bitIds, options?.rewire ?? false);
}

async link(options: WorkspaceLinkOptions = {}): Promise<WorkspaceLinkResults> {
const { linkResults, linkedRootDeps } = await this.calculateLinks(options);
async link(ids: string[], options: WorkspaceLinkOptions = {}): Promise<WorkspaceLinkResults> {
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,
Expand Down Expand Up @@ -986,7 +988,7 @@ export class InstallMain {
return;
}
if (needLink) {
await this.link();
await this.link([]);
}
}

Expand Down
2 changes: 1 addition & 1 deletion scopes/workspace/install/link/link.cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}