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(checkout): do not suggest using --entire-lane flag when the new components were soft-removed #6867

Merged
merged 1 commit into from
Jan 4, 2023
Merged
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
34 changes: 31 additions & 3 deletions e2e/harmony/lanes/lanes.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,8 @@ describe('bit lane command', function () {
});
});
describe('getting new components from the lane', () => {
let firstWorkspaceAfterExport: string;
let secondWorkspace: string;
before(() => {
helper.scopeHelper.setNewLocalAndRemoteScopes();
helper.command.createLane();
Expand All @@ -1356,23 +1358,49 @@ describe('bit lane command', function () {
helper.scopeHelper.reInitLocalScope();
helper.scopeHelper.addRemoteScope();
helper.command.importLane('dev');
const secondWorkspace = helper.scopeHelper.cloneLocalScope();
secondWorkspace = helper.scopeHelper.cloneLocalScope();
helper.scopeHelper.getClonedLocalScope(firstWorkspace);
helper.fixtures.populateComponents(2);
helper.command.snapAllComponentsWithoutBuild();
helper.command.export();
firstWorkspaceAfterExport = helper.scopeHelper.cloneLocalScope();
helper.scopeHelper.getClonedLocalScope(secondWorkspace);
helper.command.import();
});
it('bit checkout without --entire-lane flag', () => {
helper.command.checkoutHead('--skip-dependency-installation');
it('bit checkout without --entire-lane flag should not add the component and should suggest using --entire-lane flag', () => {
const output = helper.command.checkoutHead('--skip-dependency-installation');
const list = helper.command.listParsed();
expect(list).to.have.lengthOf(1);
expect(output).to.have.string('use --entire-lane flag to add them');
});
it('bit checkout with --entire-lane flag', () => {
helper.command.checkoutHead('--entire-lane --skip-dependency-installation');
const list = helper.command.listParsed();
expect(list).to.have.lengthOf(2);
});
describe('when the new component is soft-removed', () => {
let beforeCheckout: string;
before(() => {
helper.scopeHelper.getClonedLocalScope(firstWorkspaceAfterExport);
helper.command.removeComponent('comp2', '--soft');
helper.fs.writeFile('comp1/index.js', ''); // remove the comp2 dependency from the code
helper.command.snapAllComponentsWithoutBuild();
helper.command.export();
helper.scopeHelper.getClonedLocalScope(secondWorkspace);
helper.command.import();
beforeCheckout = helper.scopeHelper.cloneLocalScope();
});
it('bit checkout without --entire-lane flag, should not suggest adding it', () => {
const output = helper.command.checkoutHead('--skip-dependency-installation');
expect(output).to.not.have.string('use --entire-lane flag to add them');
expect(output).to.not.have.string('comp2');
});
it('bit checkout with --entire-lane flag should not add it', () => {
helper.scopeHelper.getClonedLocalScope(beforeCheckout);
helper.command.checkoutHead('--entire-lane --skip-dependency-installation');
const list = helper.command.listParsed();
expect(list).to.have.lengthOf(1);
});
});
});
});
12 changes: 9 additions & 3 deletions scopes/component/checkout/checkout.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ export class CheckoutMain {
const compsNewFromLane = await Promise.all(
newFromLane.map((id) => consumer.loadComponentWithDependenciesFromModel(id._legacy))
);
const compsNewFromLaneNotDeleted = compsNewFromLane.filter((c) => !c.component.removed);
componentsWithDependencies.push(...compsNewFromLaneNotDeleted);
componentsWithDependencies.push(...compsNewFromLane);
newFromLaneAdded = true;
}
}
Expand Down Expand Up @@ -253,7 +252,14 @@ export class CheckoutMain {
const laneBitIds = lane.toBitIds();
const newIds = laneBitIds.filter((bitId) => !ids.find((id) => id._legacy.isEqualWithoutVersion(bitId)));
const newComponentIds = await this.workspace.resolveMultipleComponentIds(newIds);
return newComponentIds;
const nonRemovedNewIds: ComponentID[] = [];
await Promise.all(
newComponentIds.map(async (id) => {
const isRemoved = await this.workspace.scope.isComponentRemoved(id);
if (!isRemoved) nonRemovedNewIds.push(id);
})
);
return nonRemovedNewIds;
}

private async getComponentStatusBeforeMergeAttempt(
Expand Down
12 changes: 12 additions & 0 deletions scopes/scope/scope/scope.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,18 @@ needed-for: ${neededFor || '<unknown>'}`);
return StagedConfig.load(this.path, this.logger, currentLaneId);
}

/**
* wether a component is soft-removed.
* the version is required as it can be removed on a lane. in which case, the version is the head in the lane.
*/
async isComponentRemoved(id: ComponentID): Promise<Boolean> {
const version = id.version;
if (!version) throw new Error(`isComponentRemoved expect to get version, got ${id.toString()}`);
const modelComponent = await this.legacyScope.getModelComponent(id._legacy);
const versionObj = await modelComponent.loadVersion(version, this.legacyScope.objects);
return versionObj.isRemoved();
}

/**
* resolve a component ID.
* @param id component ID.
Expand Down