Skip to content

Commit

Permalink
improvement(import), allow importing main components with wildcard wh…
Browse files Browse the repository at this point in the history
…en on a lane (#8836)

We used to throw an error suggesting the user to import the components
individually. The reason was that when you're on a lane, you probably
want to import components from the lane. not main. That's why when the
wildcard matches both, lane and main, only the lane are imported.
However, if only components from main are matched, it's not very clear
whether you really want to import from lane, or your wildcard syntax
didn't bring the results you thought it would.
With this PR we assume that in this case you do want to import from main
so we let you do that.
  • Loading branch information
davidfirst authored Apr 29, 2024
1 parent 1f9d237 commit 72fb744
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
40 changes: 40 additions & 0 deletions e2e/harmony/lanes/bit-import-on-lanes.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,44 @@ describe('bit lane command', function () {
expect(bitmap.comp1.version).to.equal(headOnLane);
});
});
describe('import with wildcard when a component is on main and user is checked out to a lane', () => {
let beforeImport: string;
before(() => {
helper.scopeHelper.setNewLocalAndRemoteScopes();
helper.fixtures.createComponentBarFoo();
helper.fixtures.addComponentBarFoo();
helper.command.tagAllWithoutBuild();
helper.command.export();
helper.scopeHelper.reInitLocalScope();
helper.scopeHelper.addRemoteScope();
helper.command.createLane();
helper.fixtures.populateComponents(1);
helper.command.snapAllComponentsWithoutBuild();
helper.command.export();
beforeImport = helper.scopeHelper.cloneLocalScope();
});
describe('when the wildcard is parsed to only main', () => {
before(() => {
helper.command.importComponent('bar/*', '-x');
});
it('should import from main', () => {
const list = helper.command.listParsed();
expect(list).to.have.lengthOf(2);
const ids = list.map((c) => c.id);
expect(ids).to.include(`${helper.scopes.remote}/bar/foo`);
});
});
describe('when the wildcard is parsed to components in the lane and in main', () => {
before(() => {
helper.scopeHelper.getClonedLocalScope(beforeImport);
helper.command.importComponent('**', '-x');
});
it('should import only the components from the lane, not main', () => {
const list = helper.command.listParsed();
expect(list).to.have.lengthOf(1);
const ids = list.map((c) => c.id);
expect(ids[0]).to.equal(`${helper.scopes.remote}/comp1`);
});
});
});
});
26 changes: 13 additions & 13 deletions scopes/scope/importer/import-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,22 @@ if you just want to get a quick look into this snap, create a new workspace and
if (!this.options.lanes) {
throw new Error(`getBitIdsForLanes: this.options.lanes must be set`);
}
const bitIdsFromLane = this.remoteLane?.toComponentIds() || new ComponentIdList();
const remoteLaneIds = this.remoteLane?.toComponentIds() || new ComponentIdList();

if (!this.options.ids.length) {
const bitMapIds = this.consumer.bitMap.getAllBitIds();
const bitMapIdsToImport = bitMapIds.filter((id) => id.hasScope() && !bitIdsFromLane.has(id));
bitIdsFromLane.push(...bitMapIdsToImport);
const bitMapIdsToImport = bitMapIds.filter((id) => id.hasScope() && !remoteLaneIds.has(id));
remoteLaneIds.push(...bitMapIdsToImport);

return bitIdsFromLane;
return remoteLaneIds;
}

const idsWithWildcard = this.options.ids.filter((id) => hasWildcard(id));
const idsWithoutWildcard = this.options.ids.filter((id) => !hasWildcard(id));
const idsWithoutWildcardPreferFromLane = await Promise.all(
idsWithoutWildcard.map(async (idStr) => {
const id = await this.getIdFromStr(idStr);
const fromLane = bitIdsFromLane.searchWithoutVersion(id);
const fromLane = remoteLaneIds.searchWithoutVersion(id);
return fromLane && !id.hasVersion() ? fromLane : id;
})
);
Expand All @@ -401,15 +401,15 @@ if you just want to get a quick look into this snap, create a new workspace and
}

await pMapSeries(idsWithWildcard, async (idStr: string) => {
const idsFromRemote = await getRemoteBitIdsByWildcards(idStr, this.options.includeDeprecated);
const existingOnLanes = compact(idsFromRemote.map((id) => bitIdsFromLane.searchWithoutVersion(id)));
if (!existingOnLanes.length) {
throw new BitError(`the id with the the wildcard "${idStr}" has been parsed to multiple component ids.
however, none of them existing on the lane "${this.remoteLane?.id()}".
in case you intend to import these components from main, please run the following:
bit import ${idsFromRemote.map((id) => id.toStringWithoutVersion()).join(' ')}`);
const existingOnLanes = await this.workspace.filterIdsFromPoolIdsByPattern(idStr, remoteLaneIds, false);
// in case the wildcard contains components from the lane, the user wants to import only them. not from main.
// otherwise, if the wildcard translates to main components only, it's ok to import from main.
if (existingOnLanes.length) {
bitIds.push(...existingOnLanes);
} else {
const idsFromRemote = await getRemoteBitIdsByWildcards(idStr, this.options.includeDeprecated);
bitIds.push(...idsFromRemote);
}
bitIds.push(...existingOnLanes);
});

return bitIds;
Expand Down

0 comments on commit 72fb744

Please sign in to comment.