diff --git a/e2e/harmony/lanes/bit-import-on-lanes.e2e.ts b/e2e/harmony/lanes/bit-import-on-lanes.e2e.ts index 593d8bd51455..f30743f5fd34 100644 --- a/e2e/harmony/lanes/bit-import-on-lanes.e2e.ts +++ b/e2e/harmony/lanes/bit-import-on-lanes.e2e.ts @@ -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`); + }); + }); + }); }); diff --git a/scopes/scope/importer/import-components.ts b/scopes/scope/importer/import-components.ts index c118d5bbf3a3..3265bbc3018e 100644 --- a/scopes/scope/importer/import-components.ts +++ b/scopes/scope/importer/import-components.ts @@ -374,14 +374,14 @@ 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)); @@ -389,7 +389,7 @@ if you just want to get a quick look into this snap, create a new workspace and 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; }) ); @@ -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;