fix(compiler-cli): ensure file_system handles mixed Windows drives (#38030)
The `fs.relative()` method assumed that the file-system is a single tree, which is not the case in Windows, where you can have multiple drives, e.g. `C:`, `D:` etc. This commit changes `fs.relative()` so that it no longer forces the result to be a `PathSegment` and then flows that refactoring through the rest of the compiler-cli (and ngcc). The main difference is that now, in some cases, we needed to check whether the result is "rooted", i.e an `AbsoluteFsPath`, rather than a `PathSegment`, before using it. Fixes #36777 PR Close #38030
This commit is contained in:

committed by
Andrew Kushnir

parent
13d176302b
commit
dba402344f
@ -5,12 +5,12 @@
|
||||
* 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, relative} from '../../../src/ngtsc/file_system';
|
||||
import {AbsoluteFsPath, isLocalRelativePath, relative} from '../../../src/ngtsc/file_system';
|
||||
import {DependencyTracker} from '../../../src/ngtsc/incremental/api';
|
||||
|
||||
export function isWithinPackage(packagePath: AbsoluteFsPath, filePath: AbsoluteFsPath): boolean {
|
||||
const relativePath = relative(packagePath, filePath);
|
||||
return !relativePath.startsWith('..') && !relativePath.startsWith('node_modules/');
|
||||
return isLocalRelativePath(relativePath) && !relativePath.startsWith('node_modules/');
|
||||
}
|
||||
|
||||
class NoopDependencyTracker implements DependencyTracker {
|
||||
|
@ -193,7 +193,7 @@ export abstract class TracingEntryPointFinder implements EntryPointFinder {
|
||||
* Split the given `path` into path segments using an FS independent algorithm.
|
||||
* @param path The path to split.
|
||||
*/
|
||||
private splitPath(path: PathSegment) {
|
||||
private splitPath(path: PathSegment|AbsoluteFsPath) {
|
||||
const segments = [];
|
||||
while (path !== '.') {
|
||||
segments.unshift(this.fs.basename(path));
|
||||
|
@ -9,7 +9,7 @@ import {Statement} from '@angular/compiler';
|
||||
import MagicString from 'magic-string';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFromSourceFile, AbsoluteFsPath, dirname, relative} from '../../../src/ngtsc/file_system';
|
||||
import {absoluteFromSourceFile, AbsoluteFsPath, dirname, relative, toRelativeImport} from '../../../src/ngtsc/file_system';
|
||||
import {NOOP_DEFAULT_IMPORT_RECORDER, Reexport} from '../../../src/ngtsc/imports';
|
||||
import {Import, ImportManager, translateStatement} from '../../../src/ngtsc/translator';
|
||||
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
|
||||
@ -57,8 +57,9 @@ export class EsmRenderingFormatter implements RenderingFormatter {
|
||||
|
||||
if (from) {
|
||||
const basePath = stripExtension(from);
|
||||
const relativePath = './' + relative(dirname(entryPointBasePath), basePath);
|
||||
exportFrom = entryPointBasePath !== basePath ? ` from '${relativePath}'` : '';
|
||||
const relativePath = relative(dirname(entryPointBasePath), basePath);
|
||||
const relativeImport = toRelativeImport(relativePath);
|
||||
exportFrom = entryPointBasePath !== basePath ? ` from '${relativeImport}'` : '';
|
||||
}
|
||||
|
||||
const exportStr = `\nexport {${e.identifier}}${exportFrom};`;
|
||||
@ -197,10 +198,10 @@ export class EsmRenderingFormatter implements RenderingFormatter {
|
||||
const ngModuleName = info.ngModule.node.name.text;
|
||||
const declarationFile = absoluteFromSourceFile(info.declaration.getSourceFile());
|
||||
const ngModuleFile = absoluteFromSourceFile(info.ngModule.node.getSourceFile());
|
||||
const relativePath = relative(dirname(declarationFile), ngModuleFile);
|
||||
const relativeImport = toRelativeImport(relativePath);
|
||||
const importPath = info.ngModule.ownedByModuleGuess ||
|
||||
(declarationFile !== ngModuleFile ?
|
||||
stripExtension(`./${relative(dirname(declarationFile), ngModuleFile)}`) :
|
||||
null);
|
||||
(declarationFile !== ngModuleFile ? stripExtension(relativeImport) : null);
|
||||
const ngModule = generateImportString(importManager, importPath, ngModuleName);
|
||||
|
||||
if (info.declaration.type) {
|
||||
|
@ -6,7 +6,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 {absoluteFromSourceFile, AbsoluteFsPath, dirname, FileSystem, join, relative} from '../../../src/ngtsc/file_system';
|
||||
import {absoluteFromSourceFile, AbsoluteFsPath, dirname, FileSystem, isLocalRelativePath, join, relative, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {EntryPoint, EntryPointJsonProperty} from '../packages/entry_point';
|
||||
@ -70,9 +70,9 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
|
||||
bundle: EntryPointBundle, packagePath: AbsoluteFsPath, ngccFolder: AbsoluteFsPath) {
|
||||
bundle.src.program.getSourceFiles().forEach(sourceFile => {
|
||||
const relativePath = relative(packagePath, absoluteFromSourceFile(sourceFile));
|
||||
const isOutsidePackage = relativePath.startsWith('..');
|
||||
if (!sourceFile.isDeclarationFile && !isOutsidePackage) {
|
||||
const newFilePath = join(ngccFolder, relativePath);
|
||||
const isInsidePackage = isLocalRelativePath(relativePath);
|
||||
if (!sourceFile.isDeclarationFile && isInsidePackage) {
|
||||
const newFilePath = resolve(ngccFolder, relativePath);
|
||||
this.fs.ensureDir(dirname(newFilePath));
|
||||
this.fs.copyFile(absoluteFromSourceFile(sourceFile), newFilePath);
|
||||
}
|
||||
@ -86,7 +86,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
|
||||
super.writeFileAndBackup(file);
|
||||
} else {
|
||||
const relativePath = relative(packagePath, file.path);
|
||||
const newFilePath = join(ngccFolder, relativePath);
|
||||
const newFilePath = resolve(ngccFolder, relativePath);
|
||||
this.fs.ensureDir(dirname(newFilePath));
|
||||
this.fs.writeFile(newFilePath, file.contents);
|
||||
}
|
||||
@ -98,7 +98,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
|
||||
super.revertFileAndBackup(filePath);
|
||||
} else if (this.fs.exists(filePath)) {
|
||||
const relativePath = relative(packagePath, filePath);
|
||||
const newFilePath = join(packagePath, NGCC_DIRECTORY, relativePath);
|
||||
const newFilePath = resolve(packagePath, NGCC_DIRECTORY, relativePath);
|
||||
this.fs.removeFile(newFilePath);
|
||||
}
|
||||
}
|
||||
@ -117,8 +117,9 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
|
||||
// All format properties point to the same format-path.
|
||||
const oldFormatProp = formatProperties[0]!;
|
||||
const oldFormatPath = packageJson[oldFormatProp]!;
|
||||
const oldAbsFormatPath = join(entryPoint.path, oldFormatPath);
|
||||
const newAbsFormatPath = join(ngccFolder, relative(entryPoint.packagePath, oldAbsFormatPath));
|
||||
const oldAbsFormatPath = resolve(entryPoint.path, oldFormatPath);
|
||||
const newAbsFormatPath =
|
||||
resolve(ngccFolder, relative(entryPoint.packagePath, oldAbsFormatPath));
|
||||
const newFormatPath = relative(entryPoint.path, newAbsFormatPath);
|
||||
|
||||
// Update all properties in `package.json` (both in memory and on disk).
|
||||
|
Reference in New Issue
Block a user