Skip to content

Commit a5c06a3

Browse files
fix(assets): fix(assets): invalid fingerprint when 'exclude' captures root directory name (#7719)
When creating an asset from a directory with certain exclude options, the fingerprint does not change even if the files change. If a fingerprint is calculated over a directory with exclude options `[ '**', '!file' ]`, the code never descends into the directory. This commit skips the exclude check for the root directory, to correctly handle negated expressions in the exclude options. fixes #7718
1 parent 44310c9 commit a5c06a3

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

packages/@aws-cdk/aws-s3-deployment/test/test.bucket-deployment.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export = {
228228
],
229229
},
230230
'SourceBucketNames': [{
231-
'Ref': 'AssetParameterse9b696b2a8a1f93ea8b8a9ce1e4dd4727f9243eba984e50411ca95c6b03d26b6S3Bucket1A1EC3E9',
231+
'Ref': 'AssetParameters86f8bca4f28a0bcafef0a98fe4cea25c0071aca27401e35cfaecd06313373bcaS3BucketB41AE64D',
232232
}],
233233
'SourceObjectKeys': [{
234234
'Fn::Join': [
@@ -241,7 +241,7 @@ export = {
241241
'Fn::Split': [
242242
'||',
243243
{
244-
'Ref': 'AssetParameterse9b696b2a8a1f93ea8b8a9ce1e4dd4727f9243eba984e50411ca95c6b03d26b6S3VersionKeyE46A4824',
244+
'Ref': 'AssetParameters86f8bca4f28a0bcafef0a98fe4cea25c0071aca27401e35cfaecd06313373bcaS3VersionKeyF3CBA38F',
245245
},
246246
],
247247
},
@@ -254,7 +254,7 @@ export = {
254254
'Fn::Split': [
255255
'||',
256256
{
257-
'Ref': 'AssetParameterse9b696b2a8a1f93ea8b8a9ce1e4dd4727f9243eba984e50411ca95c6b03d26b6S3VersionKeyE46A4824',
257+
'Ref': 'AssetParameters86f8bca4f28a0bcafef0a98fe4cea25c0071aca27401e35cfaecd06313373bcaS3VersionKeyF3CBA38F',
258258
},
259259
],
260260
},

packages/@aws-cdk/core/lib/fs/fingerprint.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ export function fingerprint(fileOrDirectory: string, options: FingerprintOptions
3333
if (exclude.length) {
3434
_hashField(hash, 'options.exclude', JSON.stringify(exclude));
3535
}
36-
_processFileOrDirectory(fileOrDirectory);
36+
const isDir = fs.statSync(fileOrDirectory).isDirectory();
37+
_processFileOrDirectory(fileOrDirectory, isDir);
3738

3839
return hash.digest('hex');
3940

40-
function _processFileOrDirectory(symbolicPath: string, realPath = symbolicPath) {
41-
if (shouldExclude(exclude, symbolicPath)) {
41+
function _processFileOrDirectory(symbolicPath: string, isRootDir: boolean = false, realPath = symbolicPath) {
42+
if (!isRootDir && shouldExclude(exclude, symbolicPath)) {
4243
return;
4344
}
4445

@@ -49,15 +50,15 @@ export function fingerprint(fileOrDirectory: string, options: FingerprintOptions
4950
const linkTarget = fs.readlinkSync(realPath);
5051
const resolvedLinkTarget = path.resolve(path.dirname(realPath), linkTarget);
5152
if (shouldFollow(follow, rootDirectory, resolvedLinkTarget)) {
52-
_processFileOrDirectory(symbolicPath, resolvedLinkTarget);
53+
_processFileOrDirectory(symbolicPath, false, resolvedLinkTarget);
5354
} else {
5455
_hashField(hash, `link:${relativePath}`, linkTarget);
5556
}
5657
} else if (stat.isFile()) {
5758
_hashField(hash, `file:${relativePath}`, _contentFingerprint(realPath, stat));
5859
} else if (stat.isDirectory()) {
5960
for (const item of fs.readdirSync(realPath).sort()) {
60-
_processFileOrDirectory(path.join(symbolicPath, item), path.join(realPath, item));
61+
_processFileOrDirectory(path.join(symbolicPath, item), false, path.join(realPath, item));
6162
}
6263
} else {
6364
throw new Error(`Unable to hash ${symbolicPath}: it is neither a file nor a directory`);

packages/@aws-cdk/core/test/fs/test.fs-fingerprint.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,20 @@ export = {
166166
const f1 = FileSystem.fingerprint(dir, options1);
167167
const f2 = FileSystem.fingerprint(dir, options2);
168168

169+
// THEN
170+
test.notDeepEqual(f1, f2);
171+
test.done();
172+
},
173+
'considers negated exclude patterns for fingerprint'(test: Test) {
174+
// GIVEN
175+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests'));
176+
const options = {path: dir, exclude: ['**', '!file.txt'], sourcePath: dir};
177+
178+
// WHEN
179+
const f1 = FileSystem.fingerprint(dir, options);
180+
fs.writeFileSync(path.join(dir, 'file.txt'), 'data');
181+
const f2 = FileSystem.fingerprint(dir, options);
182+
169183
// THEN
170184
test.notDeepEqual(f1, f2);
171185
test.done();

0 commit comments

Comments
 (0)