From 78491fdabf73047fd1fb1b78f22db6b54455676b Mon Sep 17 00:00:00 2001 From: aereal Date: Wed, 24 Jul 2019 18:56:22 +0900 Subject: [PATCH 1/3] refactor(toolkit): awaits all of files to be appended --- packages/aws-cdk/lib/archive.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/aws-cdk/lib/archive.ts b/packages/aws-cdk/lib/archive.ts index a5994ea035369..cf15a9dd6c18e 100644 --- a/packages/aws-cdk/lib/archive.ts +++ b/packages/aws-cdk/lib/archive.ts @@ -4,6 +4,15 @@ import fs = require('fs-extra'); import glob = require('glob'); import path = require('path'); +const appendFiles = async (directory: string, files: string[], archive: archiver.Archiver): Promise => { + await Promise.all(files.map(async file => { + archive.append(fs.createReadStream(path.join(directory, file)), { + name: file, + date: new Date('1980-01-01T00:00:00.000Z'), // reset dates to get the same hash for the same content + }); + })); +}; + export function zipDirectory(directory: string, outputFile: string): Promise { return new Promise((ok, fail) => { // The below options are needed to support following symlinks when building zip files: @@ -24,17 +33,12 @@ export function zipDirectory(directory: string, outputFile: string): Promise { // Append files serially to ensure file order - archive.append(fs.createReadStream(path.join(directory, file)), { - name: file, - date: new Date('1980-01-01T00:00:00.000Z'), // reset dates to get the same hash for the same content - }); - }); + appendFiles(directory, files, archive).then(() => { + archive.finalize(); - archive.finalize(); - - // archive has been finalized and the output file descriptor has closed, resolve promise - output.once('close', () => ok()); + // archive has been finalized and the output file descriptor has closed, resolve promise + output.once('close', () => ok()); + }); }); } From e7adb6bd5ccdfa2eddc7920403a49032361a54ce Mon Sep 17 00:00:00 2001 From: aereal Date: Wed, 24 Jul 2019 19:02:59 +0900 Subject: [PATCH 2/3] fix(toolkit): preserve mode of source files --- packages/aws-cdk/lib/archive.ts | 5 ++- .../test/test-archive-mode/executable.txt | 2 ++ .../test/test-archive-mode/readable.txt | 1 + packages/aws-cdk/test/test.archive.ts | 36 ++++++++++++++++++- 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100755 packages/aws-cdk/test/test-archive-mode/executable.txt create mode 100644 packages/aws-cdk/test/test-archive-mode/readable.txt diff --git a/packages/aws-cdk/lib/archive.ts b/packages/aws-cdk/lib/archive.ts index cf15a9dd6c18e..2be7eeff78ad7 100644 --- a/packages/aws-cdk/lib/archive.ts +++ b/packages/aws-cdk/lib/archive.ts @@ -6,7 +6,10 @@ import path = require('path'); const appendFiles = async (directory: string, files: string[], archive: archiver.Archiver): Promise => { await Promise.all(files.map(async file => { - archive.append(fs.createReadStream(path.join(directory, file)), { + const srcPath = path.join(directory, file); + const stat = await fs.stat(srcPath); + archive.append(fs.createReadStream(srcPath), { + mode: stat.mode, name: file, date: new Date('1980-01-01T00:00:00.000Z'), // reset dates to get the same hash for the same content }); diff --git a/packages/aws-cdk/test/test-archive-mode/executable.txt b/packages/aws-cdk/test/test-archive-mode/executable.txt new file mode 100755 index 0000000000000..ccb69856e7157 --- /dev/null +++ b/packages/aws-cdk/test/test-archive-mode/executable.txt @@ -0,0 +1,2 @@ +I am file2 +BLA! \ No newline at end of file diff --git a/packages/aws-cdk/test/test-archive-mode/readable.txt b/packages/aws-cdk/test/test-archive-mode/readable.txt new file mode 100644 index 0000000000000..7bb7edbd4b634 --- /dev/null +++ b/packages/aws-cdk/test/test-archive-mode/readable.txt @@ -0,0 +1 @@ +I am file1 \ No newline at end of file diff --git a/packages/aws-cdk/test/test.archive.ts b/packages/aws-cdk/test/test.archive.ts index c709cce749765..20fb6d23ed22d 100644 --- a/packages/aws-cdk/test/test.archive.ts +++ b/packages/aws-cdk/test/test.archive.ts @@ -70,5 +70,39 @@ export = { await fs.remove(stagingDir); await fs.remove(extractDir); test.done(); - } + }, + + async 'zipDirectory preserves mode of source files'(test: Test) { + const stagingDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive')); + const zipFile = path.join(stagingDir, 'output.zip'); + const originalDir = path.join(__dirname, 'test-archive-mode'); + const extractDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive.mode')); + await zipDirectory(originalDir, zipFile); + + // unzip and verify that the resulting tree is the same + await exec(`unzip ${zipFile}`, { cwd: extractDir }); + + // tslint:disable-next-line:no-bitwise + const beExecutable = fs.constants.S_IXGRP | fs.constants.S_IXOTH | fs.constants.S_IXUSR; + + let readable = true; + try { + await fs.access(path.join(extractDir, 'readable.txt')); + } catch { + readable = false; + } + test.ok(readable, 'extracted readable.txt cannot be accessed'); + + let executable = true; + try { + await fs.access(path.join(extractDir, 'executable.txt'), beExecutable); + } catch { + executable = false; + } + test.ok(executable, 'extracted executable.txt cannot be executable'); + + await fs.remove(stagingDir); + await fs.remove(extractDir); + test.done(); + }, }; From a0672dc794e222719abdd27ad611971d3a53a179 Mon Sep 17 00:00:00 2001 From: aereal Date: Thu, 25 Jul 2019 10:56:34 +0900 Subject: [PATCH 3/3] fix(toolkit): force adding files sequentially --- packages/aws-cdk/lib/archive.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/archive.ts b/packages/aws-cdk/lib/archive.ts index 2be7eeff78ad7..04de202e868f1 100644 --- a/packages/aws-cdk/lib/archive.ts +++ b/packages/aws-cdk/lib/archive.ts @@ -5,7 +5,7 @@ import glob = require('glob'); import path = require('path'); const appendFiles = async (directory: string, files: string[], archive: archiver.Archiver): Promise => { - await Promise.all(files.map(async file => { + for (const file of files) { const srcPath = path.join(directory, file); const stat = await fs.stat(srcPath); archive.append(fs.createReadStream(srcPath), { @@ -13,7 +13,7 @@ const appendFiles = async (directory: string, files: string[], archive: archiver name: file, date: new Date('1980-01-01T00:00:00.000Z'), // reset dates to get the same hash for the same content }); - })); + } }; export function zipDirectory(directory: string, outputFile: string): Promise {