diff --git a/package.json b/package.json index e1387a4881b48..30179b16c05b3 100644 --- a/package.json +++ b/package.json @@ -62,12 +62,16 @@ "@aws-cdk/cloud-assembly-schema/semver/**", "@aws-cdk/cloudformation-include/yaml", "@aws-cdk/cloudformation-include/yaml/**", + "@aws-cdk/core/fs-extra", + "@aws-cdk/core/fs-extra/**", "@aws-cdk/core/minimatch", "@aws-cdk/core/minimatch/**", "@aws-cdk/cx-api/semver", "@aws-cdk/cx-api/semver/**", "monocdk-experiment/case", "monocdk-experiment/case/**", + "monocdk-experiment/fs-extra", + "monocdk-experiment/fs-extra/**", "monocdk-experiment/jsonschema", "monocdk-experiment/jsonschema/**", "monocdk-experiment/minimatch", diff --git a/packages/@aws-cdk/core/lib/asset-staging.ts b/packages/@aws-cdk/core/lib/asset-staging.ts index 460d89d70133b..e25994beeb821 100644 --- a/packages/@aws-cdk/core/lib/asset-staging.ts +++ b/packages/@aws-cdk/core/lib/asset-staging.ts @@ -1,6 +1,6 @@ import * as cxapi from '@aws-cdk/cx-api'; import * as crypto from 'crypto'; -import * as fs from 'fs'; +import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { AssetHashType, AssetOptions } from './assets'; @@ -8,6 +8,8 @@ import { BundlingOptions } from './bundling'; import { Construct, ISynthesisSession } from './construct-compat'; import { FileSystem, FingerprintOptions } from './fs'; +const STAGING_TMP = '.cdk.staging'; + /** * Initialization properties for `AssetStaging`. */ @@ -118,22 +120,9 @@ export class AssetStaging extends Construct { // Asset has been bundled if (this.bundleDir) { - // Try to rename bundling directory to staging directory - try { - fs.renameSync(this.bundleDir, targetPath); - return; - } catch (err) { - // /tmp and cdk.out could be mounted across different mount points - // in this case we will fallback to copying. This can happen in Windows - // Subsystem for Linux (WSL). - if (err.code === 'EXDEV') { - fs.mkdirSync(targetPath); - FileSystem.copyDirectory(this.bundleDir, targetPath, this.fingerprintOptions); - return; - } - - throw err; - } + // Move bundling directory to staging directory + fs.moveSync(this.bundleDir, targetPath); + return; } // Copy file/directory to staging directory @@ -149,8 +138,12 @@ export class AssetStaging extends Construct { } private bundle(options: BundlingOptions): string { - // Create temporary directory for bundling - const bundleDir = FileSystem.mkdtemp('cdk-asset-bundle-'); + // Temp staging directory in the working directory + const stagingTmp = path.join('.', STAGING_TMP); + fs.ensureDirSync(stagingTmp); + + // Create temp directory for bundling inside the temp staging directory + const bundleDir = path.resolve(fs.mkdtempSync(path.join(stagingTmp, 'asset-bundle-'))); let user: string; if (options.user) { diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index a81128bfc2702..0c99c177e2027 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -166,6 +166,7 @@ "ts-mock-imports": "^1.3.0" }, "dependencies": { + "fs-extra": "^9.0.1", "minimatch": "^3.0.4", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/cdk-assets-schema": "0.0.0", @@ -173,6 +174,7 @@ "constructs": "^3.0.2" }, "bundledDependencies": [ + "fs-extra", "minimatch" ], "homepage": "https://github.com/aws/aws-cdk", diff --git a/packages/@aws-cdk/core/test/test.staging.ts b/packages/@aws-cdk/core/test/test.staging.ts index 08e20fa0fbad0..81766f8a34879 100644 --- a/packages/@aws-cdk/core/test/test.staging.ts +++ b/packages/@aws-cdk/core/test/test.staging.ts @@ -1,8 +1,9 @@ import * as cxapi from '@aws-cdk/cx-api'; -import * as fs from 'fs'; +import * as fs from 'fs-extra'; import { Test } from 'nodeunit'; import * as os from 'os'; import * as path from 'path'; +import * as sinon from 'sinon'; import { App, AssetHashType, AssetStaging, BundlingDockerImage, Stack } from '../lib'; const STUB_INPUT_FILE = '/tmp/docker-stub.input'; @@ -26,6 +27,7 @@ export = { fs.unlinkSync(STUB_INPUT_FILE); } cb(); + sinon.restore(); }, 'base case'(test: Test) { @@ -103,6 +105,8 @@ export = { const app = new App(); const stack = new Stack(app, 'stack'); const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + const ensureDirSyncSpy = sinon.spy(fs, 'ensureDirSync'); + const mkdtempSyncSpy = sinon.spy(fs, 'mkdtempSync'); // WHEN new AssetStaging(stack, 'Asset', { @@ -127,6 +131,11 @@ export = { 'tree.json', ]); + // asset is bundled in a directory inside .cdk.staging + const stagingTmp = path.join('.', '.cdk.staging'); + test.ok(ensureDirSyncSpy.calledWith(stagingTmp)); + test.ok(mkdtempSyncSpy.calledWith(sinon.match(path.join(stagingTmp, 'asset-bundle-')))); + test.done(); }, diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 22848a6122c0a..10e68d49cb898 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -81,6 +81,7 @@ "license": "Apache-2.0", "bundledDependencies": [ "case", + "fs-extra", "jsonschema", "minimatch", "semver", @@ -89,6 +90,7 @@ "dependencies": { "case": "1.6.3", "constructs": "^3.0.2", + "fs-extra": "^9.0.1", "jsonschema": "^1.2.5", "minimatch": "^3.0.4", "semver": "^7.2.2",