From d30ce19231f54c1f193c55c9d1b84d57debb0649 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Fri, 6 Oct 2017 15:12:32 -0700 Subject: [PATCH] fix(compiler): correctly calculate the out path on windows (#19601) Fixes #19543 PR Close #19601 --- .../compiler-cli/src/transformers/program.ts | 20 ++++++++++++------- .../test/transformers/program_spec.ts | 12 +++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/compiler-cli/src/transformers/program.ts b/packages/compiler-cli/src/transformers/program.ts index a84fd695d3..a8d2303ded 100644 --- a/packages/compiler-cli/src/transformers/program.ts +++ b/packages/compiler-cli/src/transformers/program.ts @@ -679,31 +679,37 @@ function getNgOptionDiagnostics(options: CompilerOptions): Diagnostic[] { * TODO(tbosch): talk to the TypeScript team to expose their logic for calculating the `rootDir` * if none was specified. * + * Note: This function works on normalized paths from typescript. + * * @param outDir * @param outSrcMappings */ export function createSrcToOutPathMapper( outDir: string | undefined, sampleSrcFileName: string | undefined, - sampleOutFileName: string | undefined): (srcFileName: string) => string { + sampleOutFileName: string | undefined, host: { + dirname: typeof path.dirname, + resolve: typeof path.resolve, + relative: typeof path.relative + } = path): (srcFileName: string) => string { let srcToOutPath: (srcFileName: string) => string; if (outDir) { if (sampleSrcFileName == null || sampleOutFileName == null) { throw new Error(`Can't calculate the rootDir without a sample srcFileName / outFileName. `); } - const srcFileDir = path.dirname(sampleSrcFileName); - const outFileDir = path.dirname(sampleOutFileName); + const srcFileDir = host.dirname(sampleSrcFileName).replace(/\\/g, '/'); + const outFileDir = host.dirname(sampleOutFileName).replace(/\\/g, '/'); if (srcFileDir === outFileDir) { return (srcFileName) => srcFileName; } - const srcDirParts = srcFileDir.split(path.sep); - const outDirParts = outFileDir.split(path.sep); + const srcDirParts = srcFileDir.split('/'); + const outDirParts = outFileDir.split('/'); // calculate the common suffix let i = 0; while (i < Math.min(srcDirParts.length, outDirParts.length) && srcDirParts[srcDirParts.length - 1 - i] === outDirParts[outDirParts.length - 1 - i]) i++; - const rootDir = srcDirParts.slice(0, srcDirParts.length - i).join(path.sep); - srcToOutPath = (srcFileName) => path.resolve(outDir, path.relative(rootDir, srcFileName)); + const rootDir = srcDirParts.slice(0, srcDirParts.length - i).join('/'); + srcToOutPath = (srcFileName) => host.resolve(outDir, host.relative(rootDir, srcFileName)); } else { srcToOutPath = (srcFileName) => srcFileName; } diff --git a/packages/compiler-cli/test/transformers/program_spec.ts b/packages/compiler-cli/test/transformers/program_spec.ts index 907cecaf4f..100d08fa66 100644 --- a/packages/compiler-cli/test/transformers/program_spec.ts +++ b/packages/compiler-cli/test/transformers/program_spec.ts @@ -495,5 +495,17 @@ describe('ng program', () => { const mapper = createSrcToOutPathMapper('/out', '/tmp/a/x.ts', '/a/x.js'); expect(mapper('/tmp/b/y.js')).toBe('/out/b/y.js'); }); + + it('should work on windows with normalized paths', () => { + const mapper = + createSrcToOutPathMapper('c:/tmp/out', 'c:/tmp/a/x.ts', 'c:/tmp/out/a/x.js', path.win32); + expect(mapper('c:/tmp/b/y.js')).toBe('c:\\tmp\\out\\b\\y.js'); + }); + + it('should work on windows with non-normalized paths', () => { + const mapper = createSrcToOutPathMapper( + 'c:\\tmp\\out', 'c:\\tmp\\a\\x.ts', 'c:\\tmp\\out\\a\\x.js', path.win32); + expect(mapper('c:\\tmp\\b\\y.js')).toBe('c:\\tmp\\out\\b\\y.js'); + }); }); });