From c47ad100db24fe9e5aacae18a8e2f89542f4c486 Mon Sep 17 00:00:00 2001 From: Steve Hetzel Date: Fri, 20 Oct 2023 11:30:36 -0600 Subject: [PATCH] fix: normalize zip file paths before comparison --- CHANGELOG.md | 2 -- src/client/metadataApiRetrieve.ts | 4 ++-- src/resolve/treeContainers.ts | 8 +++++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23b9976a5e..b6800c97ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,3 @@ -### Bug Fixes - ## [9.7.27](https://github.com/forcedotcom/source-deploy-retrieve/compare/9.7.26...9.7.27) (2023-10-17) ### Bug Fixes diff --git a/src/client/metadataApiRetrieve.ts b/src/client/metadataApiRetrieve.ts index 613024d8a6..e12035019c 100644 --- a/src/client/metadataApiRetrieve.ts +++ b/src/client/metadataApiRetrieve.ts @@ -187,11 +187,11 @@ export class MetadataApiRetrieve extends MetadataTransfer< if (this.options.unzip) { const zip = await JSZip.loadAsync(zipFileContents, { base64: true, createFolders: true }); const extractPath = path.join(this.options.output, path.parse(name).name); - fs.mkdirSync(extractPath); + fs.mkdirSync(extractPath, { recursive: true }); for (const filePath of Object.keys(zip.files)) { const zipObj = zip.file(filePath); if (!zipObj || zipObj?.dir) { - fs.mkdirSync(path.join(extractPath, filePath)); + fs.mkdirSync(path.join(extractPath, filePath), { recursive: true }); } else { // eslint-disable-next-line no-await-in-loop const content = await zipObj?.async('nodebuffer'); diff --git a/src/resolve/treeContainers.ts b/src/resolve/treeContainers.ts index e7ad91b119..54f5bb0a90 100644 --- a/src/resolve/treeContainers.ts +++ b/src/resolve/treeContainers.ts @@ -5,7 +5,7 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ /* eslint-disable class-methods-use-this */ -import { join, dirname, basename, sep } from 'path'; +import { join, dirname, basename, normalize, sep } from 'path'; import { Readable } from 'stream'; import { statSync, existsSync, readdirSync, createReadStream, readFileSync } from 'graceful-fs'; import * as JSZip from 'jszip'; @@ -191,12 +191,14 @@ export class ZipTreeContainer extends TreeContainer { } // Finds a matching entry in the zip by first comparing basenames, then dirnames. + // Note that zip files always use forward slash separators, so paths within the + // zip files are normalized for the OS file system before comparing. private match(fsPath: string): string | undefined { const fsPathBasename = basename(fsPath); const fsPathDirname = dirname(fsPath); return Object.keys(this.zip.files).find((f) => { - if (basename(f) === fsPathBasename || fsPath === '.') { - return dirname(f) === fsPathDirname; + if (normalize(basename(f)) === fsPathBasename || fsPath === '.') { + return normalize(dirname(f)) === fsPathDirname; } }); }