Skip to content

Commit

Permalink
fix(rename-scope), keep the namespace when renaming scope (#8476)
Browse files Browse the repository at this point in the history
This is a regression caused by #8456.
When renaming a component with a namespace it was emitting the
namespace, which resulted in ComponentNotFound error.
Also, it was loading the components after the rename before changing
their env in case the env was renamed as well.
Both issues are fixed in this PR.
  • Loading branch information
davidfirst authored Jan 30, 2024
1 parent 4377ca5 commit 7657930
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 15 deletions.
37 changes: 22 additions & 15 deletions scopes/component/renaming/renaming.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export class RenamingMain {
private remove: RemoveMain
) {}

async rename(sourceIdStr: string, targetName: string, options: RenameOptions): Promise<RenameDependencyNameResult> {
async rename(
sourceIdStr: string,
targetName: string,
options: RenameOptions = {}
): Promise<RenameDependencyNameResult> {
if (!isValidIdChunk(targetName)) {
if (targetName.includes('.'))
throw new Error(`error: new-name argument "${targetName}" includes a dot.
Expand Down Expand Up @@ -114,10 +118,10 @@ make sure this argument is the name only, without the scope-name. to change the
await this.deleteLinkFromNodeModules(sourcePkg);
}
});

await this.workspace.bitMap.write(`rename`);
await this.renameAspectIdsInWorkspaceConfig(multipleIds);
await this.workspace._reloadConsumer(); // in order to reload .bitmap file and clear all caches.
await this.changeEnvsAccordingToNewIds(renameData);
await pMapSeries(renameData, async (itemData) => {
itemData.targetComp = await this.workspace.get(itemData.targetId);
itemData.targetPkg = this.workspace.componentPackageName(itemData.targetComp);
Expand Down Expand Up @@ -161,16 +165,6 @@ make sure this argument is the name only, without the scope-name. to change the
multipleIds.forEach(({ sourceId, targetId }) => {
this.workspace.bitMap.renameAspectInConfig(sourceId, targetId);
});
await pMapSeries(renameData, async (renameItem) => {
const componentIds = renameItem.compIdsUsingItAsEnv;
if (!componentIds?.length) return;
const newEnvId = renameItem.targetId;
const newComponentIds = componentIds.map((id) => {
const found = renameData.find((r) => r.sourceId.isEqualWithoutVersion(id));
return found ? found.targetId : id;
});
await this.workspace.setEnvToComponents(newEnvId, newComponentIds);
});

await this.workspace.bitMap.write(`rename`);

Expand All @@ -195,7 +189,7 @@ make sure this argument is the name only, without the scope-name. to change the
* keep in mind that this is working for new components only, for tagged/exported it's impossible. See the errors
* thrown in such cases in this method.
*/
async renameScope(oldScope: string, newScope: string, options: { refactor?: boolean }): Promise<RenameResult> {
async renameScope(oldScope: string, newScope: string, options: { refactor?: boolean } = {}): Promise<RenameResult> {
const allComponentsIds = await this.workspace.listIds();
const componentsUsingOldScope = allComponentsIds.filter((compId) => compId.scope === oldScope);
if (!componentsUsingOldScope.length && this.workspace.defaultScope !== oldScope) {
Expand All @@ -205,7 +199,7 @@ make sure this argument is the name only, without the scope-name. to change the
await this.workspace.setDefaultScope(newScope);
}
const multipleIds: RenameId[] = componentsUsingOldScope.map((compId) => {
const targetId = ComponentID.fromObject({ name: compId.name }, newScope);
const targetId = ComponentID.fromObject({ name: compId.fullName }, newScope);
return { sourceId: compId, targetId };
});
return this.renameMultiple(multipleIds, { ...options, preserve: true });
Expand Down Expand Up @@ -255,7 +249,18 @@ make sure this argument is the name only, without the scope-name. to change the
);
if (hasChanged) await config.write({ reasonForChange: 'rename' });
}

private async changeEnvsAccordingToNewIds(renameData: RenameData[]) {
await pMapSeries(renameData, async (renameItem) => {
const componentIds = renameItem.compIdsUsingItAsEnv;
if (!componentIds?.length) return;
const newEnvId = renameItem.targetId;
const newComponentIds = componentIds.map((id) => {
const found = renameData.find((r) => r.sourceId.isEqualWithoutVersion(id));
return found ? found.targetId : id;
});
await this.workspace.setEnvToComponents(newEnvId, newComponentIds);
});
}
private async deleteLinkFromNodeModules(packageName: string) {
await fs.remove(path.join(this.workspace.path, 'node_modules', packageName));
}
Expand Down Expand Up @@ -364,3 +369,5 @@ export type RenameDependencyNameResult = { sourceId: ComponentID; targetId: Comp
export type RenamingInfo = {
renamedFrom: ComponentID;
};

export default RenamingMain;
51 changes: 51 additions & 0 deletions scopes/component/renaming/renaming.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import chai, { expect } from 'chai';
import {
ConfigAspect,
// ConfigMain
} from '@teambit/config';
import { loadManyAspects } from '@teambit/harmony.testing.load-aspect';
import WorkspaceAspect, { Workspace } from '@teambit/workspace';
import { mockWorkspace, destroyWorkspace, WorkspaceData } from '@teambit/workspace.testing.mock-workspace';
import { mockComponents } from '@teambit/component.testing.mock-components';
import { RenamingMain } from './renaming.main.runtime';
import { RenamingAspect } from './renaming.aspect';

chai.use(require('chai-fs'));

describe('Renaming Aspect', function () {
this.timeout(0);

// @todo: when running this, it changes the workspace.jsonc of this bit repo itself.
// see the commented line, it shows why. the config aspect is the config-aspect of bit repo instead of the
// same Harmony instance for some reason.
describe.skip('rename scope when a component id has a namespace', () => {
let renaming: RenamingMain;
let workspace: Workspace;
let workspaceData: WorkspaceData;
before(async () => {
workspaceData = mockWorkspace();
const { workspacePath } = workspaceData;
await mockComponents(workspacePath);

const harmony = await loadManyAspects([WorkspaceAspect, RenamingAspect, ConfigAspect], workspacePath);
renaming = harmony.get<RenamingMain>(RenamingAspect.id);
workspace = harmony.get<Workspace>(WorkspaceAspect.id);

// console.log('\nworkspace', workspace.path);
// const config = harmony.get<ConfigMain>('teambit.harmony/config');
// console.log('\nconfig path ', config.path);

await renaming.rename('comp1', 'ui/comp1');
await renaming.renameScope(workspaceData.remoteScopeName, 'another-scope-name');
});
after(async () => {
await destroyWorkspace(workspaceData);
});
// previously, it was throwing MissingBitMapComponent due to incorrect replacement of "ui/comp1" with "comp1"
it('should bring the files back', async () => {
const ids = await workspace.listIds();
expect(ids[0].scope).to.equal('another-scope-name');
expect(ids[0].fullName).to.equal('ui/comp1');
});
});
});

0 comments on commit 7657930

Please sign in to comment.