fix(ivy): ngcc - don't crash if entry-points have multiple invalid dependencies (#31276)

If an entry-point has missing dependencies then it cannot be
processed and is marked as invalid. Similarly, if an entry-point
has dependencies that have been marked as invalid then that
entry-point too is invalid. In all these cases, ngcc should quietly
ignore these entry-points and continue processing what it can.

Previously, if an entry-point had more than one entry-point that
was transitively invalid then ngcc was crashing rather than
ignoring the entry-point.

PR Close #31276
This commit is contained in:
Pete Bacon Darwin 2019-06-26 09:16:15 +01:00 committed by Kara Erickson
parent 32c760f5e7
commit 3788ebb714
2 changed files with 22 additions and 6 deletions

View File

@ -130,12 +130,13 @@ export class DependencyResolver {
removeNodes(entryPoint, Array.from(missing)); removeNodes(entryPoint, Array.from(missing));
} else { } else {
dependencies.forEach(dependencyPath => { dependencies.forEach(dependencyPath => {
if (graph.hasNode(dependencyPath)) { if (!graph.hasNode(entryPoint.path)) {
if (graph.hasNode(entryPoint.path)) { // The entry-point has already been identified as invalid so we don't need
// The entry-point is still valid (i.e. has no missing dependencies) and // to do any further work on it.
// the dependency maps to an entry point that exists in the graph so add it } else if (graph.hasNode(dependencyPath)) {
graph.addDependency(entryPoint.path, dependencyPath); // The entry-point is still valid (i.e. has no missing dependencies) and
} // the dependency maps to an entry point that exists in the graph so add it
graph.addDependency(entryPoint.path, dependencyPath);
} else if (invalidEntryPoints.some(i => i.entryPoint.path === dependencyPath)) { } else if (invalidEntryPoints.some(i => i.entryPoint.path === dependencyPath)) {
// The dependency path maps to an entry-point that was previously removed // The dependency path maps to an entry-point that was previously removed
// from the graph, so remove this entry-point as well. // from the graph, so remove this entry-point as well.

View File

@ -125,6 +125,21 @@ runInEachFileSystem(() => {
]); ]);
}); });
it('should cope with entry points having multiple indirect missing dependencies', () => {
spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({
[_('/first/index.js')]: {resolved: [], missing: ['/missing1']},
[_('/second/sub/index.js')]: {resolved: [], missing: ['/missing2']},
[_('/third/index.js')]: {resolved: [first.path, second.path], missing: []},
}));
const result = resolver.sortEntryPointsByDependency([first, second, third]);
expect(result.entryPoints).toEqual([]);
expect(result.invalidEntryPoints).toEqual([
{entryPoint: first, missingDependencies: ['/missing1']},
{entryPoint: second, missingDependencies: ['/missing2']},
{entryPoint: third, missingDependencies: [first.path]},
]);
});
it('should error if the entry point does not have a suitable format', () => { it('should error if the entry point does not have a suitable format', () => {
expect(() => resolver.sortEntryPointsByDependency([ expect(() => resolver.sortEntryPointsByDependency([
{ path: '/first', packageJson: {}, compiledByAngular: true } as EntryPoint { path: '/first', packageJson: {}, compiledByAngular: true } as EntryPoint