fix(ngcc): capture path-mapped entry-points that start with same string (#35592)
Previously if there were two path-mapped libraries that are in different directories but the path of one started with same string as the path of the other, we would incorrectly return the shorter path - e.g. `dist/my-lib` and `dist/my-lib-second`. This was because the list of `basePaths` was searched in ascending alphabetic order and we were using `startsWith()` to match the path. Now the `basePaths` are searched in reverse alphabetic order so the longer path will be matched correctly. // FW-1873 Fixes #35536 PR Close #35592
This commit is contained in:

committed by
Miško Hevery

parent
53f059ee8f
commit
71b5970450
@ -5,7 +5,7 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AbsoluteFsPath, getFileSystem, join, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {AbsoluteFsPath, getFileSystem, join, relative, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {PathMappings} from '../utils';
|
||||
|
||||
/**
|
||||
@ -42,8 +42,8 @@ export function getBasePaths(
|
||||
basePaths.push(basePath);
|
||||
}));
|
||||
}
|
||||
basePaths.sort(); // Get the paths in order with the shorter ones first.
|
||||
return basePaths.filter(removeDeeperPaths);
|
||||
basePaths.sort().reverse(); // Get the paths in order with the longer ones first.
|
||||
return basePaths.filter(removeContainedPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,16 +56,25 @@ function extractPathPrefix(path: string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter function that removes paths that are already covered by higher paths.
|
||||
* A filter function that removes paths that are contained by other paths.
|
||||
*
|
||||
* For example:
|
||||
* Given `['a/b/c', 'a/b/x', 'a/b', 'd/e', 'd/f']` we will end up with `['a/b', 'd/e', 'd/f]`.
|
||||
* (Note that we do not get `d` even though `d/e` and `d/f` share a base directory, since `d` is not
|
||||
* one of the base paths.)
|
||||
*
|
||||
* @param value The current path.
|
||||
* @param index The index of the current path.
|
||||
* @param array The array of paths (sorted alphabetically).
|
||||
* @returns true if this path is not already covered by a previous path.
|
||||
* @param array The array of paths (sorted in reverse alphabetical order).
|
||||
* @returns true if this path is not contained by another path.
|
||||
*/
|
||||
function removeDeeperPaths(value: AbsoluteFsPath, index: number, array: AbsoluteFsPath[]) {
|
||||
for (let i = 0; i < index; i++) {
|
||||
if (value.startsWith(array[i])) return false;
|
||||
function removeContainedPaths(value: AbsoluteFsPath, index: number, array: AbsoluteFsPath[]) {
|
||||
// We only need to check the following paths since the `array` is sorted in reverse alphabetic
|
||||
// order.
|
||||
for (let i = index + 1; i < array.length; i++) {
|
||||
// We need to use `relative().startsWith()` rather than a simple `startsWith()` to ensure we
|
||||
// don't assume that `a/b` contains `a/b-2`.
|
||||
if (!relative(array[i], value).startsWith('..')) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user