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

Improve bit link to regenerate all links in case some links were reported missing #2043

Merged
merged 3 commits into from
Sep 27, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [unreleased]

- [#2033](https://github.com/teambit/bit/issues/2033) improve bit link to build unrecognized missing links
- [#2035](https://github.com/teambit/bit/issues/2035) fix "unable to manually add the dependency" error when package.json of an imported component is missing
- [#2034](https://github.com/teambit/bit/issues/2034) make sure versions are not deleted upon tag when components have cycle dependencies and a version is specified
- [#2027](https://github.com/teambit/bit/issues/2027) fix ComponentNotFound error when building a typescript component and its Bit dependency is installed as a package
Expand Down
1 change: 0 additions & 1 deletion src/cli/commands/public-cmds/link-cmd.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @flow */
import chalk from 'chalk';
import Command from '../../command';
import { link } from '../../../api/consumer';
import linkTemplate from '../../templates/link-template';
Expand Down
22 changes: 5 additions & 17 deletions src/consumer/component/consumer-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -899,25 +899,13 @@ export default class Component {
this.docs = flattenedDocs;
}

copyDependenciesFromModel(ids: string[]) {
copyAllDependenciesFromModel() {
const componentFromModel = this.componentFromModel;
if (!componentFromModel) throw new Error('copyDependenciesFromModel: component is missing from the model');
ids.forEach((id: string) => {
const addDependency = (modelDependencies: Dependencies, dependencies: Dependencies) => {
const dependency = modelDependencies.getByIdStr(id);
if (dependency) dependencies.add(dependency);
return Boolean(dependency);
};
const addedDep = addDependency(componentFromModel.dependencies, this.dependencies);
if (addedDep) return;
const addedDevDep = addDependency(componentFromModel.devDependencies, this.devDependencies);
if (addedDevDep) return;
const addedCompilerDep = addDependency(componentFromModel.compilerDependencies, this.compilerDependencies);
if (addedCompilerDep) return;
const addedTesterDep = addDependency(componentFromModel.testerDependencies, this.testerDependencies);
if (addedTesterDep) return;
throw new Error(`copyDependenciesFromModel unable to find dependency ${id} in the model`);
});
this.setDependencies(componentFromModel.dependencies.get());
this.setDevDependencies(componentFromModel.devDependencies.get());
this.setCompilerDependencies(componentFromModel.compilerDependencies.get());
this.setTesterDependencies(componentFromModel.testerDependencies.get());
}

static async fromObject(object: Object): Component {
Expand Down
2 changes: 1 addition & 1 deletion src/links/linker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import logger from '../logger/logger';
import { pathNormalizeToLinux } from '../utils';
import * as linkGenerator from '../links/link-generator';
import NodeModuleLinker from './node-modules-linker';
import type Consumer from '../consumer/consumer';
import Consumer from '../consumer/consumer';
import ComponentWithDependencies from '../scope/component-dependencies';
import * as packageJsonUtils from '../consumer/component/package-json-utils';
import type { LinksResult } from './node-modules-linker';
Expand Down
69 changes: 18 additions & 51 deletions src/links/node-modules-linker.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export default class NodeModuleLinker {
async _populateImportedComponentsLinks(component: Component): Promise<void> {
const componentMap = component.componentMap;
const componentId = component.id;
// @todo: this should probably be `const bindingPrefix = component.bindingPrefix;`
const bindingPrefix = this.consumer ? this.consumer.config.bindingPrefix : DEFAULT_BINDINGS_PREFIX;
const linkPath: PathOsBasedRelative = getNodeModulesPathOfComponent(bindingPrefix, componentId, true);
// when a user moves the component directory, use component.writtenPath to find the correct target
Expand Down Expand Up @@ -177,25 +178,27 @@ export default class NodeModuleLinker {
async _populateDependenciesAndMissingLinks(component: Component): Promise<void> {
// $FlowFixMe loaded from FS, componentMap must be set
const componentMap: ComponentMap = component.componentMap;
if (
component.issues &&
(component.issues.missingLinks || component.issues.missingCustomModuleResolutionLinks) &&
this.consumer &&
component.componentFromModel
) {
const componentWithDependencies = await component.toComponentWithDependencies(this.consumer);
component.copyAllDependenciesFromModel();
const componentsDependenciesLinks = getComponentsDependenciesLinks(
[componentWithDependencies],
this.consumer,
false,
this.bitMap
);
this.dataToPersist.addManyFiles(componentsDependenciesLinks.files);
this.dataToPersist.addManySymlinks(componentsDependenciesLinks.symlinks);
}
if (component.hasDependencies()) {
const dependenciesLinks = this._getDependenciesLinks(component, componentMap);
this.dataToPersist.addManySymlinks(dependenciesLinks);
}
const missingDependenciesLinks =
this.consumer && component.issues && component.issues.missingLinks ? this._getMissingLinks(component) : [];
this.dataToPersist.addManySymlinks(missingDependenciesLinks);
if (this.consumer && component.issues && component.issues.missingCustomModuleResolutionLinks) {
const missingCustomResolvedLinks = await this._getMissingCustomResolvedLinks(component);
this.dataToPersist.addManyFiles(missingCustomResolvedLinks.files);
this.dataToPersist.addManySymlinks(missingCustomResolvedLinks.symlinks);
if (component.componentFromModel && component.componentFromModel.hasDependencies()) {
// when custom-resolve links are missing, the component has been loaded without that
// dependency. (see "deleting the link generated for the custom-module-resolution" test)
// as a result, dependency links were not generated. our option is to get it from the scope
const dependenciesLinks = this._getDependenciesLinks(component.componentFromModel, componentMap);
this.dataToPersist.addManySymlinks(dependenciesLinks);
}
}
}
/**
* When the dists is outside the components directory, it doesn't have access to the node_modules of the component's
Expand Down Expand Up @@ -253,26 +256,6 @@ export default class NodeModuleLinker {
return R.flatten(symlinks);
}

_getMissingLinks(component: Component): Symlink[] {
const missingLinks = component.issues.missingLinks;
const result = Object.keys(component.issues.missingLinks).map((key) => {
return missingLinks[key]
.map((dependencyIdRaw: BitId) => {
const dependencyId: BitId = this.bitMap.getBitId(dependencyIdRaw, { ignoreVersion: true });
const dependencyComponentMap = this.bitMap.getComponent(dependencyId);
if (!dependencyComponentMap.rootDir) return null;
return this._getDependencyLink(
component.componentMap.rootDir,
dependencyId,
dependencyComponentMap.rootDir,
component.bindingPrefix
);
})
.filter(x => x);
});
return R.flatten(result);
}

_getDependencyLink(
parentRootDir: PathOsBasedRelative,
bitId: BitId,
Expand All @@ -284,22 +267,6 @@ export default class NodeModuleLinker {
return Symlink.makeInstance(rootDir, destPathInsideParent, bitId);
}

async _getMissingCustomResolvedLinks(component: Component): Promise<DataToPersist> {
if (!component.componentFromModel) return new DataToPersist();
if (!this.consumer) throw new Error('_getMissingCustomResolvedLinks expects to have consumer set');
const componentWithDependencies = await component.toComponentWithDependencies(this.consumer);
const missingLinks = component.issues.missingCustomModuleResolutionLinks;
const dependenciesStr = R.flatten(Object.keys(missingLinks).map(fileName => missingLinks[fileName]));
component.copyDependenciesFromModel(dependenciesStr);
const componentsDependenciesLinks = getComponentsDependenciesLinks(
[componentWithDependencies],
this.consumer,
false,
this.bitMap
);
return componentsDependenciesLinks;
}

/**
* create package.json on node_modules/@bit/component-name/package.json with a property 'main'
* pointing to the component's main file.
Expand Down