From fd8868fee494192c30857c15cc166b0ccfb061f7 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 30 Apr 2020 19:22:51 +0300 Subject: [PATCH 1/2] refactor(core): fold "assets" to "core" Fold the "assets" module, which includes the Staging construct that takes care of staging asset files into the cloud assembly during synthesis into "core". This is in order to allow implementing custom resources that leverage assets throughout the framework. A subsequent commit will add a mini-framework for custom resources that leverages this capability. --- package.json | 4 +- packages/@aws-cdk/assets/README.md | 10 +- .../@aws-cdk/assets/lib/fs/follow-mode.ts | 4 + packages/@aws-cdk/assets/lib/fs/index.ts | 4 - packages/@aws-cdk/assets/lib/fs/options.ts | 2 + packages/@aws-cdk/assets/lib/index.ts | 2 +- packages/@aws-cdk/assets/lib/staging.ts | 112 +++++------------- packages/@aws-cdk/assets/package.json | 18 +-- .../package.json | 2 - packages/@aws-cdk/core/lib/asset-staging.ts | 98 +++++++++++++++ .../@aws-cdk/{assets => core}/lib/fs/copy.ts | 7 +- .../{assets => core}/lib/fs/fingerprint.ts | 5 +- packages/@aws-cdk/core/lib/fs/index.ts | 36 ++++++ packages/@aws-cdk/core/lib/fs/options.ts | 63 ++++++++++ .../@aws-cdk/{assets => core}/lib/fs/utils.ts | 12 +- packages/@aws-cdk/core/lib/index.ts | 2 + packages/@aws-cdk/core/package.json | 13 +- packages/@aws-cdk/core/test/fs/.gitignore | 3 + .../@aws-cdk/core/test/fs/fixtures.tar.gz | Bin 0 -> 1328 bytes .../{assets => core}/test/fs/test.fs-copy.ts | 19 ++- .../test/fs/test.fs-fingerprint.ts | 46 +++---- .../{assets => core}/test/fs/test.utils.ts | 26 ++-- packages/@aws-cdk/core/test/test.staging.ts | 77 ++++++++++++ tools/cdk-build-tools/config/nyc.config.js | 4 +- 24 files changed, 397 insertions(+), 172 deletions(-) delete mode 100644 packages/@aws-cdk/assets/lib/fs/index.ts create mode 100644 packages/@aws-cdk/core/lib/asset-staging.ts rename packages/@aws-cdk/{assets => core}/lib/fs/copy.ts (90%) rename packages/@aws-cdk/{assets => core}/lib/fs/fingerprint.ts (95%) create mode 100644 packages/@aws-cdk/core/lib/fs/index.ts create mode 100644 packages/@aws-cdk/core/lib/fs/options.ts rename packages/@aws-cdk/{assets => core}/lib/fs/utils.ts (83%) create mode 100644 packages/@aws-cdk/core/test/fs/.gitignore create mode 100644 packages/@aws-cdk/core/test/fs/fixtures.tar.gz rename packages/@aws-cdk/{assets => core}/test/fs/test.fs-copy.ts (84%) rename packages/@aws-cdk/{assets => core}/test/fs/test.fs-fingerprint.ts (76%) rename packages/@aws-cdk/{assets => core}/test/fs/test.utils.ts (84%) create mode 100644 packages/@aws-cdk/core/test/test.staging.ts diff --git a/package.json b/package.json index 04fb80b659ee8..900c9ae1bd3c5 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,8 @@ "**/jszip/**", "@aws-cdk/cdk-assets-schema/semver", "@aws-cdk/cdk-assets-schema/semver/**", - "@aws-cdk/assets/minimatch", - "@aws-cdk/assets/minimatch/**", + "@aws-cdk/core/minimatch", + "@aws-cdk/core/minimatch/**", "@aws-cdk/aws-codepipeline-actions/case", "@aws-cdk/aws-codepipeline-actions/case/**", "@aws-cdk/aws-ecr-assets/minimatch", diff --git a/packages/@aws-cdk/assets/README.md b/packages/@aws-cdk/assets/README.md index c7d1ae9654b5c..6ebca5ae0d9e6 100644 --- a/packages/@aws-cdk/assets/README.md +++ b/packages/@aws-cdk/assets/README.md @@ -2,15 +2,11 @@ --- -![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) +![Deprecated](https://img.shields.io/badge/deprecated-critical.svg?style=for-the-badge) -> The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package. +> This API may emit warnings. Backward compatibility is not guaranteed. --- -This module includes core classes for to CDK assets, used for copying asset -files to a staging area. Most CDK users should not need to use the classes in -this package directly. - - +All types moved to @aws-cdk/core. \ No newline at end of file diff --git a/packages/@aws-cdk/assets/lib/fs/follow-mode.ts b/packages/@aws-cdk/assets/lib/fs/follow-mode.ts index 81f81a36eac24..5aca6f8446532 100644 --- a/packages/@aws-cdk/assets/lib/fs/follow-mode.ts +++ b/packages/@aws-cdk/assets/lib/fs/follow-mode.ts @@ -1,3 +1,7 @@ +/** + * Symlink follow mode. + * @deprecated see `core.SymlinkFollowMode` + */ export enum FollowMode { /** * Never follow symlinks. diff --git a/packages/@aws-cdk/assets/lib/fs/index.ts b/packages/@aws-cdk/assets/lib/fs/index.ts deleted file mode 100644 index a1a4c68a83cef..0000000000000 --- a/packages/@aws-cdk/assets/lib/fs/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './copy'; -export * from './fingerprint'; -export * from './follow-mode'; -export * from './options'; diff --git a/packages/@aws-cdk/assets/lib/fs/options.ts b/packages/@aws-cdk/assets/lib/fs/options.ts index 727da36568502..434dd091a7256 100644 --- a/packages/@aws-cdk/assets/lib/fs/options.ts +++ b/packages/@aws-cdk/assets/lib/fs/options.ts @@ -2,6 +2,7 @@ import { FollowMode } from './follow-mode'; /** * Obtains applied when copying directories into the staging location. + * @deprecated see `core.CopyOptions` */ export interface CopyOptions { /** @@ -21,6 +22,7 @@ export interface CopyOptions { /** * Options related to calculating source hash. + * @deprecated see `core.FingerprintOptions` */ export interface FingerprintOptions extends CopyOptions { /** diff --git a/packages/@aws-cdk/assets/lib/index.ts b/packages/@aws-cdk/assets/lib/index.ts index e2a67003867bd..c651e06cc2ac1 100644 --- a/packages/@aws-cdk/assets/lib/index.ts +++ b/packages/@aws-cdk/assets/lib/index.ts @@ -1,4 +1,4 @@ export * from './api'; export * from './fs/follow-mode'; export * from './fs/options'; -export * from './staging'; +export * from './staging'; \ No newline at end of file diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index a95f7e26107a8..4682be5ccb556 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -1,92 +1,44 @@ -import { Construct, ISynthesisSession } from '@aws-cdk/core'; -import * as cxapi from '@aws-cdk/cx-api'; -import * as fs from 'fs'; -import * as path from 'path'; -import { copyDirectory, fingerprint, FingerprintOptions } from './fs'; +import { AssetStaging, Construct, SymlinkFollowMode } from '@aws-cdk/core'; +import { FollowMode } from './fs/follow-mode'; +import { FingerprintOptions } from './fs/options'; +/** + * Deprecated + * @deprecated use `core.AssetStagingProps` + */ export interface StagingProps extends FingerprintOptions { + /** + * Local file or directory to stage. + */ readonly sourcePath: string; } /** - * Stages a file or directory from a location on the file system into a staging - * directory. - * - * This is controlled by the context key 'aws:cdk:asset-staging' and enabled - * by the CLI by default in order to ensure that when the CDK app exists, all - * assets are available for deployment. Otherwise, if an app references assets - * in temporary locations, those will not be available when it exists (see - * https://github.com/aws/aws-cdk/issues/1716). - * - * The `stagedPath` property is a stringified token that represents the location - * of the file or directory after staging. It will be resolved only during the - * "prepare" stage and may be either the original path or the staged path - * depending on the context setting. - * - * The file/directory are staged based on their content hash (fingerprint). This - * means that only if content was changed, copy will happen. + * Deprecated + * @deprecated use `core.AssetStaging` */ -export class Staging extends Construct { - - /** - * The path to the asset (stringinfied token). - * - * If asset staging is disabled, this will just be the original path. - * If asset staging is enabled it will be the staged path. - */ - public readonly stagedPath: string; - - /** - * The path of the asset as it was referenced by the user. - */ - public readonly sourcePath: string; - - /** - * A cryptographic hash of the source document(s). - */ - public readonly sourceHash: string; - - private readonly fingerprintOptions: FingerprintOptions; - - private readonly relativePath?: string; - +export class Staging extends AssetStaging { constructor(scope: Construct, id: string, props: StagingProps) { - super(scope, id); - - this.sourcePath = props.sourcePath; - this.fingerprintOptions = props; - this.sourceHash = fingerprint(this.sourcePath, props); - - const stagingDisabled = this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT); - if (stagingDisabled) { - this.stagedPath = this.sourcePath; - } else { - this.relativePath = 'asset.' + this.sourceHash + path.extname(this.sourcePath); - this.stagedPath = this.relativePath; // always relative to outdir - } + super(scope, id, { + sourcePath: props.sourcePath, + exclude: props.exclude, + extraHash: props.extraHash, + follow: toSymlinkFollow(props.follow), + }); } +} - protected synthesize(session: ISynthesisSession) { - if (!this.relativePath) { - return; - } - - const targetPath = path.join(session.assembly.outdir, this.relativePath); - - // asset already staged - if (fs.existsSync(targetPath)) { - return; - } +function toSymlinkFollow(follow?: FollowMode): SymlinkFollowMode | undefined { + if (!follow) { + return undefined; + } - // copy file/directory to staging directory - const stat = fs.statSync(this.sourcePath); - if (stat.isFile()) { - fs.copyFileSync(this.sourcePath, targetPath); - } else if (stat.isDirectory()) { - fs.mkdirSync(targetPath); - copyDirectory(this.sourcePath, targetPath, this.fingerprintOptions); - } else { - throw new Error(`Unknown file type: ${this.sourcePath}`); - } + switch (follow) { + case FollowMode.NEVER: return SymlinkFollowMode.NEVER; + case FollowMode.ALWAYS: return SymlinkFollowMode.ALWAYS; + case FollowMode.BLOCK_EXTERNAL: return SymlinkFollowMode.BLOCK_EXTERNAL; + case FollowMode.EXTERNAL: return SymlinkFollowMode.EXTERNAL; + default: + throw new Error(`unknown follow mode: ${follow}`); } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/assets/package.json b/packages/@aws-cdk/assets/package.json index 28386204806c3..6d60dba8c1876 100644 --- a/packages/@aws-cdk/assets/package.json +++ b/packages/@aws-cdk/assets/package.json @@ -1,7 +1,7 @@ { "name": "@aws-cdk/assets", "version": "0.0.0", - "description": "Integration of CDK apps with local assets", + "description": "This module is deprecated. All types are now available under the core module", "main": "lib/index.js", "types": "lib/index.d.ts", "jsii": { @@ -64,7 +64,6 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "@types/minimatch": "^3.0.3", "@types/nodeunit": "^0.0.30", "@types/sinon": "^9.0.0", "aws-cdk": "0.0.0", @@ -78,7 +77,6 @@ "dependencies": { "@aws-cdk/core": "0.0.0", "@aws-cdk/cx-api": "0.0.0", - "minimatch": "^3.0.4", "constructs": "^3.0.2" }, "homepage": "https://github.com/aws/aws-cdk", @@ -90,18 +88,8 @@ "engines": { "node": ">= 10.12.0" }, - "bundledDependencies": [ - "minimatch" - ], - "stability": "experimental", - "maturity": "experimental", - "awslint": { - "exclude": [ - "docs-public-apis:@aws-cdk/assets.StagingProps", - "docs-public-apis:@aws-cdk/assets.StagingProps.sourcePath", - "docs-public-apis:@aws-cdk/assets.FollowMode" - ] - }, + "stability": "deprecated", + "maturity": "deprecated", "awscdkio": { "announce": false } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/package.json b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/package.json index 2b0e0dbef3159..941104f60ed2a 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/package.json +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/package.json @@ -84,7 +84,6 @@ "pkglint": "0.0.0" }, "dependencies": { - "@aws-cdk/assets": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", @@ -94,7 +93,6 @@ }, "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { - "@aws-cdk/assets": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", diff --git a/packages/@aws-cdk/core/lib/asset-staging.ts b/packages/@aws-cdk/core/lib/asset-staging.ts new file mode 100644 index 0000000000000..0fb9dc3da8265 --- /dev/null +++ b/packages/@aws-cdk/core/lib/asset-staging.ts @@ -0,0 +1,98 @@ +import * as cxapi from '@aws-cdk/cx-api'; +import * as fs from 'fs'; +import * as path from 'path'; +import { Construct, ISynthesisSession } from './construct-compat'; +import { FileSystem, FingerprintOptions } from './fs'; + +/** + * Initialization properties for `AssetStaging`. + */ +export interface AssetStagingProps extends FingerprintOptions { + /** + * The source file or directory to copy from. + */ + readonly sourcePath: string; +} + +/** + * Stages a file or directory from a location on the file system into a staging + * directory. + * + * This is controlled by the context key 'aws:cdk:asset-staging' and enabled + * by the CLI by default in order to ensure that when the CDK app exists, all + * assets are available for deployment. Otherwise, if an app references assets + * in temporary locations, those will not be available when it exists (see + * https://github.com/aws/aws-cdk/issues/1716). + * + * The `stagedPath` property is a stringified token that represents the location + * of the file or directory after staging. It will be resolved only during the + * "prepare" stage and may be either the original path or the staged path + * depending on the context setting. + * + * The file/directory are staged based on their content hash (fingerprint). This + * means that only if content was changed, copy will happen. + */ +export class AssetStaging extends Construct { + + /** + * The path to the asset (stringinfied token). + * + * If asset staging is disabled, this will just be the original path. + * If asset staging is enabled it will be the staged path. + */ + public readonly stagedPath: string; + + /** + * The path of the asset as it was referenced by the user. + */ + public readonly sourcePath: string; + + /** + * A cryptographic hash of the source document(s). + */ + public readonly sourceHash: string; + + private readonly fingerprintOptions: FingerprintOptions; + + private readonly relativePath?: string; + + constructor(scope: Construct, id: string, props: AssetStagingProps) { + super(scope, id); + + this.sourcePath = props.sourcePath; + this.fingerprintOptions = props; + this.sourceHash = FileSystem.fingerprint(this.sourcePath, props); + + const stagingDisabled = this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT); + if (stagingDisabled) { + this.stagedPath = this.sourcePath; + } else { + this.relativePath = 'asset.' + this.sourceHash + path.extname(this.sourcePath); + this.stagedPath = this.relativePath; // always relative to outdir + } + } + + protected synthesize(session: ISynthesisSession) { + if (!this.relativePath) { + return; + } + + const targetPath = path.join(session.assembly.outdir, this.relativePath); + + // asset already staged + if (fs.existsSync(targetPath)) { + return; + } + + // copy file/directory to staging directory + const stat = fs.statSync(this.sourcePath); + if (stat.isFile()) { + fs.copyFileSync(this.sourcePath, targetPath); + } else if (stat.isDirectory()) { + fs.mkdirSync(targetPath); + FileSystem.copyDirectory(this.sourcePath, targetPath, this.fingerprintOptions); + } else { + throw new Error(`Unknown file type: ${this.sourcePath}`); + } + } +} diff --git a/packages/@aws-cdk/assets/lib/fs/copy.ts b/packages/@aws-cdk/core/lib/fs/copy.ts similarity index 90% rename from packages/@aws-cdk/assets/lib/fs/copy.ts rename to packages/@aws-cdk/core/lib/fs/copy.ts index 01b6c19cc66a6..d4c2841feeb6b 100644 --- a/packages/@aws-cdk/assets/lib/fs/copy.ts +++ b/packages/@aws-cdk/core/lib/fs/copy.ts @@ -1,11 +1,10 @@ import * as fs from 'fs'; import * as path from 'path'; -import { FollowMode } from './follow-mode'; -import { CopyOptions } from './options'; +import { CopyOptions, SymlinkFollowMode } from './options'; import { shouldExclude, shouldFollow } from './utils'; export function copyDirectory(srcDir: string, destDir: string, options: CopyOptions = { }, rootDir?: string) { - const follow = options.follow !== undefined ? options.follow : FollowMode.EXTERNAL; + const follow = options.follow !== undefined ? options.follow : SymlinkFollowMode.EXTERNAL; const exclude = options.exclude || []; rootDir = rootDir || srcDir; @@ -24,7 +23,7 @@ export function copyDirectory(srcDir: string, destDir: string, options: CopyOpti const destFilePath = path.join(destDir, file); - let stat: fs.Stats | undefined = follow === FollowMode.ALWAYS + let stat: fs.Stats | undefined = follow === SymlinkFollowMode.ALWAYS ? fs.statSync(sourceFilePath) : fs.lstatSync(sourceFilePath); diff --git a/packages/@aws-cdk/assets/lib/fs/fingerprint.ts b/packages/@aws-cdk/core/lib/fs/fingerprint.ts similarity index 95% rename from packages/@aws-cdk/assets/lib/fs/fingerprint.ts rename to packages/@aws-cdk/core/lib/fs/fingerprint.ts index 1d75850a17e56..dcac8f5ba5fce 100644 --- a/packages/@aws-cdk/assets/lib/fs/fingerprint.ts +++ b/packages/@aws-cdk/core/lib/fs/fingerprint.ts @@ -1,8 +1,7 @@ import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; -import { FollowMode } from './follow-mode'; -import { FingerprintOptions } from './options'; +import { FingerprintOptions, SymlinkFollowMode } from './options'; import { shouldExclude, shouldFollow } from './utils'; const BUFFER_SIZE = 8 * 1024; @@ -24,7 +23,7 @@ const CTRL_ETX = '\x03'; export function fingerprint(fileOrDirectory: string, options: FingerprintOptions = { }) { const hash = crypto.createHash('sha256'); _hashField(hash, 'options.extra', options.extraHash || ''); - const follow = options.follow || FollowMode.EXTERNAL; + const follow = options.follow || SymlinkFollowMode.EXTERNAL; _hashField(hash, 'options.follow', follow); const rootDirectory = fs.statSync(fileOrDirectory).isDirectory() diff --git a/packages/@aws-cdk/core/lib/fs/index.ts b/packages/@aws-cdk/core/lib/fs/index.ts new file mode 100644 index 0000000000000..ac7f3c9d0f8da --- /dev/null +++ b/packages/@aws-cdk/core/lib/fs/index.ts @@ -0,0 +1,36 @@ +import { copyDirectory } from './copy'; +import { fingerprint } from './fingerprint'; +import { CopyOptions, FingerprintOptions } from './options'; + +export * from './options'; + +/** + * File system utilities. + */ +export class FileSystem { + /** + * Copies an entire directory structure. + * @param srcDir Source directory + * @param destDir Destination directory + * @param options options + * @param rootDir Root directory to calculate exclusions from + */ + public static copyDirectory(srcDir: string, destDir: string, options: CopyOptions = { }, rootDir?: string) { + return copyDirectory(srcDir, destDir, options, rootDir); + } + + /** + * Produces fingerprint based on the contents of a single file or an entire directory tree. + * + * The fingerprint will also include: + * 1. An extra string if defined in `options.extra`. + * 2. The set of exclude patterns, if defined in `options.exclude` + * 3. The symlink follow mode value. + * + * @param fileOrDirectory The directory or file to fingerprint + * @param options Fingerprinting options + */ + public static fingerprint(fileOrDirectory: string, options: FingerprintOptions = { }) { + return fingerprint(fileOrDirectory, options); + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/core/lib/fs/options.ts b/packages/@aws-cdk/core/lib/fs/options.ts new file mode 100644 index 0000000000000..eef3fcc499b08 --- /dev/null +++ b/packages/@aws-cdk/core/lib/fs/options.ts @@ -0,0 +1,63 @@ +/** + * Determines how symlinks are followed. + */ +export enum SymlinkFollowMode { + /** + * Never follow symlinks. + */ + NEVER = 'never', + + /** + * Materialize all symlinks, whether they are internal or external to the source directory. + */ + ALWAYS = 'always', + + /** + * Only follows symlinks that are external to the source directory. + */ + EXTERNAL = 'external', + + /** + * Forbids source from having any symlinks pointing outside of the source + * tree. + * + * This is the safest mode of operation as it ensures that copy operations + * won't materialize files from the user's file system. Internal symlinks are + * not followed. + * + * If the copy operation runs into an external symlink, it will fail. + */ + BLOCK_EXTERNAL = 'internal-only', +} + +/** + * Obtains applied when copying directories into the staging location. + */ +export interface CopyOptions { + /** + * A strategy for how to handle symlinks. + * + * @default SymlinkFollowMode.NEVER + */ + readonly follow?: SymlinkFollowMode; + + /** + * Glob patterns to exclude from the copy. + * + * @default - nothing is excluded + */ + readonly exclude?: string[]; +} + +/** + * Options related to calculating source hash. + */ +export interface FingerprintOptions extends CopyOptions { + /** + * Extra information to encode into the fingerprint (e.g. build instructions + * and other inputs) + * + * @default - hash is only based on source content + */ + readonly extraHash?: string; +} diff --git a/packages/@aws-cdk/assets/lib/fs/utils.ts b/packages/@aws-cdk/core/lib/fs/utils.ts similarity index 83% rename from packages/@aws-cdk/assets/lib/fs/utils.ts rename to packages/@aws-cdk/core/lib/fs/utils.ts index 4e58be4e09866..5624c3448f5ef 100644 --- a/packages/@aws-cdk/assets/lib/fs/utils.ts +++ b/packages/@aws-cdk/core/lib/fs/utils.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as minimatch from 'minimatch'; import * as path from 'path'; -import { FollowMode } from './follow-mode'; +import { SymlinkFollowMode } from './options'; /** * Determines whether a given file should be excluded or not based on given @@ -40,15 +40,15 @@ export function shouldExclude(exclude: string[], filePath: string): boolean { * * @returns true if the link should be followed. */ -export function shouldFollow(mode: FollowMode, sourceRoot: string, realPath: string): boolean { +export function shouldFollow(mode: SymlinkFollowMode, sourceRoot: string, realPath: string): boolean { switch (mode) { - case FollowMode.ALWAYS: + case SymlinkFollowMode.ALWAYS: return fs.existsSync(realPath); - case FollowMode.EXTERNAL: + case SymlinkFollowMode.EXTERNAL: return !_isInternal() && fs.existsSync(realPath); - case FollowMode.BLOCK_EXTERNAL: + case SymlinkFollowMode.BLOCK_EXTERNAL: return _isInternal() && fs.existsSync(realPath); - case FollowMode.NEVER: + case SymlinkFollowMode.NEVER: return false; default: throw new Error(`Unsupported FollowMode: ${mode}`); diff --git a/packages/@aws-cdk/core/lib/index.ts b/packages/@aws-cdk/core/lib/index.ts index 828d9eca25057..5bec1208abd3e 100644 --- a/packages/@aws-cdk/core/lib/index.ts +++ b/packages/@aws-cdk/core/lib/index.ts @@ -43,6 +43,8 @@ export * from './assets'; export * from './tree'; +export * from './asset-staging'; +export * from './fs'; // WARNING: Should not be exported, but currently is because of a bug. See the // class description for more information. export * from './private/intrinsic'; diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index 57232866cdd3b..b3fce8771ae50 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -118,6 +118,11 @@ "build+test": "npm run build && npm test", "compat": "cdk-compat" }, + "cdk-build": { + "pre": [ + "rm -rf test/fs/fixtures && cd test/fs && tar -xzf fixtures.tar.gz" + ] + }, "nyc": { "statements": 55, "lines": 55, @@ -139,18 +144,24 @@ "@types/lodash": "^4.14.150", "@types/node": "^10.17.21", "@types/nodeunit": "^0.0.30", + "@types/minimatch": "^3.0.3", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "fast-check": "^1.24.2", "lodash": "^4.17.15", "nodeunit": "^0.11.3", - "pkglint": "0.0.0" + "pkglint": "0.0.0", + "ts-mock-imports": "^1.3.0" }, "dependencies": { + "minimatch": "^3.0.4", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "constructs": "^3.0.2" }, + "bundledDependencies": [ + "minimatch" + ], "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "@aws-cdk/cx-api": "0.0.0", diff --git a/packages/@aws-cdk/core/test/fs/.gitignore b/packages/@aws-cdk/core/test/fs/.gitignore new file mode 100644 index 0000000000000..b13de5858771b --- /dev/null +++ b/packages/@aws-cdk/core/test/fs/.gitignore @@ -0,0 +1,3 @@ +# codepipeline looses symlinks so we bundled fixtures into a tarball +# and unpack in pre-build script (yak) +fixtures/** diff --git a/packages/@aws-cdk/core/test/fs/fixtures.tar.gz b/packages/@aws-cdk/core/test/fs/fixtures.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..50f5ba0f4a259052109afd4e7aae10087655fec8 GIT binary patch literal 1328 zcmYk4eK=GJ6vih*zS>yDtacemNL$ltHnO`$3X2l0kEt+GR@!2VtnzSuE*YCAN(qbX zHk)ZF**+APXtgO5R^#JgFd0(17-PQfy=NzX?fLUO@AIB>e(#}k^(YA={7?#Yro1zD z$n%qIodh0lwB9Wu>is%KgI=MB!D^4RyIiedd$S_r+f%{U40VQI>!=)4&btQY{G08# zAv>E)xRMPl=rRRY@F^b_@wqHk))Wly(f8E=YW_UKI54YdA| zYfmeTxnVQ$ag{_gU_W@j&ZoTN^fpdO%_DB_k*2F1dq6(lQGp~Ax615d7CK$R`(k?+ z`MYuipr5cNUr~m)Uz^)nx0zz`8X>&uw>i!`S~UN9KW6%^Y#0r8+gZ#`;3I`#flbscjxaEao5&| z5ZsN$w}n8Hs_!8n4I`BuP6*-ad@R2OQht04caq8jE=TpNSplmFgrPl;1Y_{Sl9UmM zln11x0LM3jL}?B)9MANmq9^=>RHTR-UwERvv-6f5Y0b?7b;|{y36JCG2=Hcs61af* z%htal1^O4RgTS`v6uZ#%X7TlKtVrD-)MT){7Cb=^$2=X+dqMcS_bX6+$}GZgo=18U z5=mAz$TRXti<;&mb-<{$g^)fa$F|+xdh^Ea_7)k3>3q?Ny+#Z~TRA_rl28cnbOn~} zFGdfxL%4r8y0h;xy8y0O?Jk`Y1)W`Ix-^Z$YCdSQ(eA^Q)!J`a;d%{ZoA(RYjwFcNDs7Vn&=Qq&5;m*Xhi{Rxt%5E=Tt z6=hHR4vNv*E--t`$^{|s=$lhGz0sv*t4xaeeYPypGT++n^<&3(LL~cd9HnbbAOWut zd1fOScB8pHl?W+W*|LZih-1Ac^U5MeRY)=X^jx<=j(Be&r917xi;QDAi=nGN?N6fO zyBqt5!Ghr%XMUd)D3QXer52(nCkwiMGKA!f#1a{c|C|)^|lH%#d^m z9+$18GqUDEr8JraW2O>$DMd@H-HS;Ke~um2d`&!wIpBk87R^A3hU>{ldKtVlnpQD_ zu<6xS$q*g77KDa^S?C(O%*MdfeUzy9Aj{DhPC-s(H&`S#dJmDD;1r-n8(_$+`{Eb- zy(H0=Cx)7yYG;_}whfS?US?&f&2W_V0aZo{F1%<>Ca(>|m&owJZz;6DaJn?#O4E-U YcO-O8v?>3u=H(>Sn%Y=MsiaW;12WR+@Bjb+ literal 0 HcmV?d00001 diff --git a/packages/@aws-cdk/assets/test/fs/test.fs-copy.ts b/packages/@aws-cdk/core/test/fs/test.fs-copy.ts similarity index 84% rename from packages/@aws-cdk/assets/test/fs/test.fs-copy.ts rename to packages/@aws-cdk/core/test/fs/test.fs-copy.ts index 68cb3dc234d06..47b55842a90c4 100644 --- a/packages/@aws-cdk/assets/test/fs/test.fs-copy.ts +++ b/packages/@aws-cdk/core/test/fs/test.fs-copy.ts @@ -2,8 +2,7 @@ import * as fs from 'fs'; import { Test } from 'nodeunit'; import * as os from 'os'; import * as path from 'path'; -import { copyDirectory } from '../../lib/fs/copy'; -import { FollowMode } from '../../lib/fs/follow-mode'; +import { FileSystem, SymlinkFollowMode } from '../../lib/fs'; export = { 'Default: copies all files and subdirectories, with default follow mode is "External"'(test: Test) { @@ -11,7 +10,7 @@ export = { const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); // WHEN - copyDirectory(path.join(__dirname, 'fixtures', 'test1'), outdir); + FileSystem.copyDirectory(path.join(__dirname, 'fixtures', 'test1'), outdir); // THEN test.deepEqual(tree(outdir), [ @@ -34,8 +33,8 @@ export = { const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); // WHEN - copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { - follow: FollowMode.ALWAYS, + FileSystem.copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { + follow: SymlinkFollowMode.ALWAYS, }); // THEN @@ -59,8 +58,8 @@ export = { const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); // WHEN - copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { - follow: FollowMode.NEVER, + FileSystem.copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { + follow: SymlinkFollowMode.NEVER, }); // THEN @@ -82,8 +81,8 @@ export = { const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); // WHEN - copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { - follow: FollowMode.EXTERNAL, + FileSystem.copyDirectory(path.join(__dirname, 'fixtures', 'symlinks'), outdir, { + follow: SymlinkFollowMode.EXTERNAL, }); // THEN @@ -107,7 +106,7 @@ export = { const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); // WHEN - copyDirectory(path.join(__dirname, 'fixtures', 'test1'), outdir, { + FileSystem.copyDirectory(path.join(__dirname, 'fixtures', 'test1'), outdir, { exclude: [ '*', '!subdir2', diff --git a/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts b/packages/@aws-cdk/core/test/fs/test.fs-fingerprint.ts similarity index 76% rename from packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts rename to packages/@aws-cdk/core/test/fs/test.fs-fingerprint.ts index ea6b10ec250f6..7be40d4b31ad4 100644 --- a/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts +++ b/packages/@aws-cdk/core/test/fs/test.fs-fingerprint.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import { Test } from 'nodeunit'; import * as os from 'os'; import * as path from 'path'; -import * as libfs from '../../lib/fs'; +import { FileSystem, SymlinkFollowMode } from '../../lib/fs'; export = { files: { @@ -18,9 +18,9 @@ export = { fs.writeFileSync(input3, content + '.'); // add one character, hash should be different // WHEN - const hash1 = libfs.fingerprint(input1); - const hash2 = libfs.fingerprint(input2); - const hash3 = libfs.fingerprint(input3); + const hash1 = FileSystem.fingerprint(input1); + const hash2 = FileSystem.fingerprint(input2); + const hash3 = FileSystem.fingerprint(input3); // THEN test.deepEqual(hash1, hash2); @@ -37,8 +37,8 @@ export = { fs.writeFileSync(input2, ''); // WHEN - const hash1 = libfs.fingerprint(input1); - const hash2 = libfs.fingerprint(input2); + const hash1 = FileSystem.fingerprint(input1); + const hash2 = FileSystem.fingerprint(input2); // THEN test.deepEqual(hash1, hash2); @@ -51,11 +51,11 @@ export = { // GIVEN const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); - libfs.copyDirectory(srcdir, outdir); + FileSystem.copyDirectory(srcdir, outdir); // WHEN - const hashSrc = libfs.fingerprint(srcdir); - const hashCopy = libfs.fingerprint(outdir); + const hashSrc = FileSystem.fingerprint(srcdir); + const hashCopy = FileSystem.fingerprint(outdir); // THEN test.deepEqual(hashSrc, hashCopy); @@ -66,13 +66,13 @@ export = { // GIVEN const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); - libfs.copyDirectory(srcdir, outdir); + FileSystem.copyDirectory(srcdir, outdir); // WHEN - const hashSrc = libfs.fingerprint(srcdir, { exclude: ['*.ignoreme'] }); + const hashSrc = FileSystem.fingerprint(srcdir, { exclude: ['*.ignoreme'] }); fs.writeFileSync(path.join(outdir, `${hashSrc}.ignoreme`), 'Ignore me!'); - const hashCopy = libfs.fingerprint(outdir, { exclude: ['*.ignoreme'] }); + const hashCopy = FileSystem.fingerprint(outdir, { exclude: ['*.ignoreme'] }); // THEN test.deepEqual(hashSrc, hashCopy); @@ -83,14 +83,14 @@ export = { // GIVEN const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); const cpydir = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); - libfs.copyDirectory(srcdir, cpydir); + FileSystem.copyDirectory(srcdir, cpydir); // be careful not to break a symlink fs.renameSync(path.join(cpydir, 'normal-dir', 'file-in-subdir.txt'), path.join(cpydir, 'move-me.txt')); // WHEN - const hashSrc = libfs.fingerprint(srcdir); - const hashCopy = libfs.fingerprint(cpydir); + const hashSrc = FileSystem.fingerprint(srcdir); + const hashCopy = FileSystem.fingerprint(cpydir); // THEN test.notDeepEqual(hashSrc, hashCopy); @@ -111,15 +111,15 @@ export = { // now dir2 contains a symlink to a file in dir1 // WHEN - const original = libfs.fingerprint(dir2); + const original = FileSystem.fingerprint(dir2); // now change the contents of the target fs.writeFileSync(target, 'changning you!'); - const afterChange = libfs.fingerprint(dir2); + const afterChange = FileSystem.fingerprint(dir2); // revert the content to original and expect hash to be reverted fs.writeFileSync(target, content); - const afterRevert = libfs.fingerprint(dir2); + const afterRevert = FileSystem.fingerprint(dir2); // THEN test.notDeepEqual(original, afterChange); @@ -139,15 +139,15 @@ export = { // now dir2 contains a symlink to a file in dir1 // WHEN - const original = libfs.fingerprint(dir2, { follow: libfs.FollowMode.NEVER }); + const original = FileSystem.fingerprint(dir2, { follow: SymlinkFollowMode.NEVER }); // now change the contents of the target fs.writeFileSync(target, 'changning you!'); - const afterChange = libfs.fingerprint(dir2, { follow: libfs.FollowMode.NEVER }); + const afterChange = FileSystem.fingerprint(dir2, { follow: SymlinkFollowMode.NEVER }); // revert the content to original and expect hash to be reverted fs.writeFileSync(target, content); - const afterRevert = libfs.fingerprint(dir2, { follow: libfs.FollowMode.NEVER }); + const afterRevert = FileSystem.fingerprint(dir2, { follow: SymlinkFollowMode.NEVER }); // THEN test.deepEqual(original, afterChange); @@ -163,8 +163,8 @@ export = { const options2 = {path: dir, exclude: ['**', '!otherfile.py'], sourcePath: dir}; // WHEN - const f1 = libfs.fingerprint(dir, options1); - const f2 = libfs.fingerprint(dir, options2); + const f1 = FileSystem.fingerprint(dir, options1); + const f2 = FileSystem.fingerprint(dir, options2); // THEN test.notDeepEqual(f1, f2); diff --git a/packages/@aws-cdk/assets/test/fs/test.utils.ts b/packages/@aws-cdk/core/test/fs/test.utils.ts similarity index 84% rename from packages/@aws-cdk/assets/test/fs/test.utils.ts rename to packages/@aws-cdk/core/test/fs/test.utils.ts index 3fe6ab55ab0ac..c8962c7f4022f 100644 --- a/packages/@aws-cdk/assets/test/fs/test.utils.ts +++ b/packages/@aws-cdk/core/test/fs/test.utils.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import { Test } from 'nodeunit'; import * as path from 'path'; import { ImportMock } from 'ts-mock-imports'; -import { FollowMode } from '../../lib/fs'; +import { SymlinkFollowMode } from '../../lib/fs'; import * as util from '../../lib/fs/utils'; export = { @@ -34,7 +34,7 @@ export = { const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', true); try { - test.ok(util.shouldFollow(FollowMode.ALWAYS, sourceRoot, linkTarget)); + test.ok(util.shouldFollow(SymlinkFollowMode.ALWAYS, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -47,7 +47,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', true); try { - test.ok(util.shouldFollow(FollowMode.ALWAYS, sourceRoot, linkTarget)); + test.ok(util.shouldFollow(SymlinkFollowMode.ALWAYS, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -60,7 +60,7 @@ export = { const linkTarget = path.join(sourceRoot, 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', false); try { - test.ok(!util.shouldFollow(FollowMode.ALWAYS, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.ALWAYS, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -73,7 +73,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', false); try { - test.ok(!util.shouldFollow(FollowMode.ALWAYS, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.ALWAYS, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -88,7 +88,7 @@ export = { const linkTarget = path.join(sourceRoot, 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync'); try { - test.ok(!util.shouldFollow(FollowMode.EXTERNAL, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.notCalled); test.done(); } finally { @@ -101,7 +101,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', true); try { - test.ok(util.shouldFollow(FollowMode.EXTERNAL, sourceRoot, linkTarget)); + test.ok(util.shouldFollow(SymlinkFollowMode.EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -114,7 +114,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', false); try { - test.ok(!util.shouldFollow(FollowMode.EXTERNAL, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -129,7 +129,7 @@ export = { const linkTarget = path.join(sourceRoot, 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', true); try { - test.ok(util.shouldFollow(FollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); + test.ok(util.shouldFollow(SymlinkFollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -142,7 +142,7 @@ export = { const linkTarget = path.join(sourceRoot, 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync', false); try { - test.ok(!util.shouldFollow(FollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.calledOnceWith(linkTarget)); test.done(); } finally { @@ -155,7 +155,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync'); try { - test.ok(!util.shouldFollow(FollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.BLOCK_EXTERNAL, sourceRoot, linkTarget)); test.ok(mockFsExists.notCalled); test.done(); } finally { @@ -170,7 +170,7 @@ export = { const linkTarget = path.join(sourceRoot, 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync'); try { - test.ok(!util.shouldFollow(FollowMode.NEVER, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.NEVER, sourceRoot, linkTarget)); test.ok(mockFsExists.notCalled); test.done(); } finally { @@ -183,7 +183,7 @@ export = { const linkTarget = path.join('alternate', 'referent'); const mockFsExists = ImportMock.mockFunction(fs, 'existsSync'); try { - test.ok(!util.shouldFollow(FollowMode.NEVER, sourceRoot, linkTarget)); + test.ok(!util.shouldFollow(SymlinkFollowMode.NEVER, sourceRoot, linkTarget)); test.ok(mockFsExists.notCalled); test.done(); } finally { diff --git a/packages/@aws-cdk/core/test/test.staging.ts b/packages/@aws-cdk/core/test/test.staging.ts new file mode 100644 index 0000000000000..3faeea3e95396 --- /dev/null +++ b/packages/@aws-cdk/core/test/test.staging.ts @@ -0,0 +1,77 @@ +import * as cxapi from '@aws-cdk/cx-api'; +import * as fs from 'fs'; +import { Test } from 'nodeunit'; +import * as path from 'path'; +import { App, AssetStaging, Stack } from '../lib'; + +export = { + 'base case'(test: Test) { + // GIVEN + const stack = new Stack(); + const sourcePath = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + // WHEN + const staging = new AssetStaging(stack, 's1', { sourcePath }); + + test.deepEqual(staging.sourceHash, '2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00'); + test.deepEqual(staging.sourcePath, sourcePath); + test.deepEqual(stack.resolve(staging.stagedPath), 'asset.2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00'); + test.done(); + }, + + 'staging can be disabled through context'(test: Test) { + // GIVEN + const stack = new Stack(); + stack.node.setContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT, true); + const sourcePath = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + // WHEN + const staging = new AssetStaging(stack, 's1', { sourcePath }); + + test.deepEqual(staging.sourceHash, '2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00'); + test.deepEqual(staging.sourcePath, sourcePath); + test.deepEqual(stack.resolve(staging.stagedPath), sourcePath); + test.done(); + }, + + 'files are copied to the output directory during synth'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'stack'); + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + const file = path.join(__dirname, 'fs', 'fixtures.tar.gz'); + + // WHEN + new AssetStaging(stack, 's1', { sourcePath: directory }); + new AssetStaging(stack, 'file', { sourcePath: file }); + + // THEN + const assembly = app.synth(); + test.deepEqual(fs.readdirSync(assembly.directory), [ + 'asset.2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00', + 'asset.af10ac04b3b607b0f8659c8f0cee8c343025ee75baf0b146f10f0e5311d2c46b.gz', + 'cdk.out', + 'manifest.json', + 'stack.template.json', + 'tree.json', + ]); + test.done(); + }, + + 'allow specifying extra data to include in the source hash'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'stack'); + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + // WHEN + const withoutExtra = new AssetStaging(stack, 'withoutExtra', { sourcePath: directory }); + const withExtra = new AssetStaging(stack, 'withExtra', { sourcePath: directory, extraHash: 'boom' }); + + // THEN + test.notEqual(withoutExtra.sourceHash, withExtra.sourceHash); + test.deepEqual(withoutExtra.sourceHash, '2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00'); + test.deepEqual(withExtra.sourceHash, 'c95c915a5722bb9019e2c725d11868e5a619b55f36172f76bcbcaa8bb2d10c5f'); + test.done(); + }, +}; diff --git a/tools/cdk-build-tools/config/nyc.config.js b/tools/cdk-build-tools/config/nyc.config.js index 7704b5dc47e27..985320565879e 100644 --- a/tools/cdk-build-tools/config/nyc.config.js +++ b/tools/cdk-build-tools/config/nyc.config.js @@ -24,7 +24,9 @@ module.exports = { "examples/**", "lambda-packages/**", "lib/*.generated.js", - "build-tools/**" + "build-tools/**", + ".eslintrc.js", + "nyc.config.js" ], // Configuration in package.json supercedes that of the defaults above. ...nycConfig, From f8eafa1c34b207c7100d6805c17c2fc95177a590 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 30 Apr 2020 19:48:19 +0300 Subject: [PATCH 2/2] add coverage to for the compatibility layer --- packages/@aws-cdk/assets/lib/compat.ts | 17 +++++++++++++++++ packages/@aws-cdk/assets/lib/staging.ts | 19 ++----------------- packages/@aws-cdk/assets/test/test.compat.ts | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 packages/@aws-cdk/assets/lib/compat.ts create mode 100644 packages/@aws-cdk/assets/test/test.compat.ts diff --git a/packages/@aws-cdk/assets/lib/compat.ts b/packages/@aws-cdk/assets/lib/compat.ts new file mode 100644 index 0000000000000..07bd050d77f5d --- /dev/null +++ b/packages/@aws-cdk/assets/lib/compat.ts @@ -0,0 +1,17 @@ +import { SymlinkFollowMode } from '@aws-cdk/core'; +import { FollowMode } from './fs/follow-mode'; + +export function toSymlinkFollow(follow?: FollowMode): SymlinkFollowMode | undefined { + if (!follow) { + return undefined; + } + + switch (follow) { + case FollowMode.NEVER: return SymlinkFollowMode.NEVER; + case FollowMode.ALWAYS: return SymlinkFollowMode.ALWAYS; + case FollowMode.BLOCK_EXTERNAL: return SymlinkFollowMode.BLOCK_EXTERNAL; + case FollowMode.EXTERNAL: return SymlinkFollowMode.EXTERNAL; + default: + throw new Error(`unknown follow mode: ${follow}`); + } +} diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index 4682be5ccb556..87800ae8aa40f 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -1,5 +1,5 @@ -import { AssetStaging, Construct, SymlinkFollowMode } from '@aws-cdk/core'; -import { FollowMode } from './fs/follow-mode'; +import { AssetStaging, Construct } from '@aws-cdk/core'; +import { toSymlinkFollow } from './compat'; import { FingerprintOptions } from './fs/options'; /** @@ -27,18 +27,3 @@ export class Staging extends AssetStaging { }); } } - -function toSymlinkFollow(follow?: FollowMode): SymlinkFollowMode | undefined { - if (!follow) { - return undefined; - } - - switch (follow) { - case FollowMode.NEVER: return SymlinkFollowMode.NEVER; - case FollowMode.ALWAYS: return SymlinkFollowMode.ALWAYS; - case FollowMode.BLOCK_EXTERNAL: return SymlinkFollowMode.BLOCK_EXTERNAL; - case FollowMode.EXTERNAL: return SymlinkFollowMode.EXTERNAL; - default: - throw new Error(`unknown follow mode: ${follow}`); - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/assets/test/test.compat.ts b/packages/@aws-cdk/assets/test/test.compat.ts new file mode 100644 index 0000000000000..65b50d0b37daf --- /dev/null +++ b/packages/@aws-cdk/assets/test/test.compat.ts @@ -0,0 +1,15 @@ +import { SymlinkFollowMode } from '@aws-cdk/core'; +import { Test } from 'nodeunit'; +import { FollowMode } from '../lib'; +import { toSymlinkFollow } from '../lib/compat'; + +export = { + 'FollowMode compatibility'(test: Test) { + test.equal(toSymlinkFollow(undefined), null); + test.equal(toSymlinkFollow(FollowMode.ALWAYS), SymlinkFollowMode.ALWAYS); + test.equal(toSymlinkFollow(FollowMode.BLOCK_EXTERNAL), SymlinkFollowMode.BLOCK_EXTERNAL); + test.equal(toSymlinkFollow(FollowMode.EXTERNAL), SymlinkFollowMode.EXTERNAL); + test.equal(toSymlinkFollow(FollowMode.NEVER), SymlinkFollowMode.NEVER); + test.done(); + }, +}; \ No newline at end of file