fix(ivy): handle windows drives correctly (#30297)
At the moment the module resolver will end up in an infinite loop in Windows because we are assuming that the root directory is always `/` however in windows this can be any drive letter example `c:/` or `d:/` etc... With this change we also resolve the drive letter in windows, when using `AbsoluteFsPath.from` for consistence so under `/foo` will be converted to `c:/foo` this is also needed because of relative paths with different drive letters. PR Close #30297
This commit is contained in:
parent
f74373f2dd
commit
3a7bfc721e
|
@ -118,7 +118,7 @@ export class ModuleResolver {
|
||||||
*/
|
*/
|
||||||
private resolveAsEntryPoint(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
|
private resolveAsEntryPoint(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
|
||||||
let folder = fromPath;
|
let folder = fromPath;
|
||||||
while (folder !== '/') {
|
while (!AbsoluteFsPath.isRoot(folder)) {
|
||||||
folder = AbsoluteFsPath.dirname(folder);
|
folder = AbsoluteFsPath.dirname(folder);
|
||||||
if (folder.endsWith('node_modules')) {
|
if (folder.endsWith('node_modules')) {
|
||||||
// Skip up if the folder already ends in node_modules
|
// Skip up if the folder already ends in node_modules
|
||||||
|
@ -225,7 +225,7 @@ export class ModuleResolver {
|
||||||
*/
|
*/
|
||||||
private findPackagePath(path: AbsoluteFsPath): AbsoluteFsPath|null {
|
private findPackagePath(path: AbsoluteFsPath): AbsoluteFsPath|null {
|
||||||
let folder = path;
|
let folder = path;
|
||||||
while (folder !== '/') {
|
while (!AbsoluteFsPath.isRoot(folder)) {
|
||||||
folder = AbsoluteFsPath.dirname(folder);
|
folder = AbsoluteFsPath.dirname(folder);
|
||||||
if (this.fs.exists(AbsoluteFsPath.join(folder, 'package.json'))) {
|
if (this.fs.exists(AbsoluteFsPath.join(folder, 'package.json'))) {
|
||||||
return folder;
|
return folder;
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class NgccCompilerHost implements ts.CompilerHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultLibLocation(): string {
|
getDefaultLibLocation(): string {
|
||||||
const nodeLibPath = AbsoluteFsPath.fromUnchecked(require.resolve('typescript'));
|
const nodeLibPath = AbsoluteFsPath.from(require.resolve('typescript'));
|
||||||
return AbsoluteFsPath.join(nodeLibPath, '..');
|
return AbsoluteFsPath.join(nodeLibPath, '..');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {FileStats, FileSystem} from '../../src/file_system/file_system';
|
||||||
export class MockFileSystem implements FileSystem {
|
export class MockFileSystem implements FileSystem {
|
||||||
files: Folder = {};
|
files: Folder = {};
|
||||||
constructor(...folders: Folder[]) {
|
constructor(...folders: Folder[]) {
|
||||||
folders.forEach(files => this.processFiles(this.files, files));
|
folders.forEach(files => this.processFiles(this.files, files, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
exists(path: AbsoluteFsPath): boolean { return this.findFromPath(path) !== null; }
|
exists(path: AbsoluteFsPath): boolean { return this.findFromPath(path) !== null; }
|
||||||
|
@ -67,7 +67,7 @@ export class MockFileSystem implements FileSystem {
|
||||||
return new MockFileStats(fileOrFolder);
|
return new MockFileStats(fileOrFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
pwd(): AbsoluteFsPath { return AbsoluteFsPath.fromUnchecked('/'); }
|
pwd(): AbsoluteFsPath { return AbsoluteFsPath.from('/'); }
|
||||||
|
|
||||||
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void {
|
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void {
|
||||||
this.writeFile(to, this.readFile(from));
|
this.writeFile(to, this.readFile(from));
|
||||||
|
@ -82,9 +82,10 @@ export class MockFileSystem implements FileSystem {
|
||||||
|
|
||||||
ensureDir(path: AbsoluteFsPath): void { this.ensureFolders(this.files, path.split('/')); }
|
ensureDir(path: AbsoluteFsPath): void { this.ensureFolders(this.files, path.split('/')); }
|
||||||
|
|
||||||
private processFiles(current: Folder, files: Folder): void {
|
private processFiles(current: Folder, files: Folder, isRootPath = false): void {
|
||||||
Object.keys(files).forEach(path => {
|
Object.keys(files).forEach(path => {
|
||||||
const segments = path.split('/');
|
const pathResolved = isRootPath ? AbsoluteFsPath.from(path) : path;
|
||||||
|
const segments = pathResolved.split('/');
|
||||||
const lastSegment = segments.pop() !;
|
const lastSegment = segments.pop() !;
|
||||||
const containingFolder = this.ensureFolders(current, segments);
|
const containingFolder = this.ensureFolders(current, segments);
|
||||||
const entity = files[path];
|
const entity = files[path];
|
||||||
|
|
|
@ -40,6 +40,12 @@ export const AbsoluteFsPath = {
|
||||||
* Convert the path `str` to an `AbsoluteFsPath`, throwing an error if it's not an absolute path.
|
* Convert the path `str` to an `AbsoluteFsPath`, throwing an error if it's not an absolute path.
|
||||||
*/
|
*/
|
||||||
from: function(str: string): AbsoluteFsPath {
|
from: function(str: string): AbsoluteFsPath {
|
||||||
|
if (str.startsWith('/') && process.platform === 'win32') {
|
||||||
|
// in Windows if it's absolute path and starts with `/` we shall
|
||||||
|
// resolve it and return it including the drive.
|
||||||
|
str = path.resolve(str);
|
||||||
|
}
|
||||||
|
|
||||||
const normalized = normalizeSeparators(str);
|
const normalized = normalizeSeparators(str);
|
||||||
if (!isAbsolutePath(normalized)) {
|
if (!isAbsolutePath(normalized)) {
|
||||||
throw new Error(`Internal Error: AbsoluteFsPath.from(${str}): path is not absolute`);
|
throw new Error(`Internal Error: AbsoluteFsPath.from(${str}): path is not absolute`);
|
||||||
|
@ -80,6 +86,9 @@ export const AbsoluteFsPath = {
|
||||||
*/
|
*/
|
||||||
resolve: function(basePath: string, ...paths: string[]):
|
resolve: function(basePath: string, ...paths: string[]):
|
||||||
AbsoluteFsPath { return AbsoluteFsPath.from(path.resolve(basePath, ...paths));},
|
AbsoluteFsPath { return AbsoluteFsPath.from(path.resolve(basePath, ...paths));},
|
||||||
|
|
||||||
|
/** Returns true when the path provided is the root path. */
|
||||||
|
isRoot: function(path: AbsoluteFsPath): boolean { return AbsoluteFsPath.dirname(path) === path;},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue