From 81b9ebc6d7f661c80f78549f4e80ed461b7a2874 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 6 Jan 2022 16:24:42 +0100 Subject: [PATCH] Include invalidation hash in asset content keys (#7526) --- packages/core/core/src/Transformation.js | 21 ++++++--- packages/core/integration-tests/test/cache.js | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/packages/core/core/src/Transformation.js b/packages/core/core/src/Transformation.js index 0b125f29eba..321a327e315 100644 --- a/packages/core/core/src/Transformation.js +++ b/packages/core/core/src/Transformation.js @@ -283,15 +283,21 @@ export default class Transformation { if (!initialCacheEntry) { let pipelineHash = await this.getPipelineHash(pipeline); + let invalidationCacheKey = await getInvalidationHash( + assets.flatMap(asset => asset.getInvalidations()), + this.options, + ); let resultCacheKey = this.getCacheKey( [initialAsset], - await getInvalidationHash( - assets.flatMap(asset => asset.getInvalidations()), - this.options, - ), + invalidationCacheKey, + pipelineHash, + ); + await this.writeToCache( + resultCacheKey, + assets, + invalidationCacheKey, pipelineHash, ); - await this.writeToCache(resultCacheKey, assets, pipelineHash); } else { // See above TODO, this should be per-pipeline for (let i of this.request.invalidations) { @@ -541,9 +547,12 @@ export default class Transformation { async writeToCache( cacheKey: string, assets: Array, + invalidationHash: string, pipelineHash: string, ): Promise { - await Promise.all(assets.map(asset => asset.commit(pipelineHash))); + await Promise.all( + assets.map(asset => asset.commit(invalidationHash + pipelineHash)), + ); this.options.cache.set(cacheKey, { $$raw: true, diff --git a/packages/core/integration-tests/test/cache.js b/packages/core/integration-tests/test/cache.js index 4ddfb121864..d03984b702b 100644 --- a/packages/core/integration-tests/test/cache.js +++ b/packages/core/integration-tests/test/cache.js @@ -5789,6 +5789,53 @@ describe('cache', function () { } }); + it('properly handles included files even after when changing back to a cached state', async function () { + this.timeout(15000); + let subscription; + let fixture = path.join(__dirname, '/integration/included-file'); + try { + let b = bundler(path.join(fixture, 'index.txt'), { + inputFS: overlayFS, + shouldDisableCache: false, + }); + await overlayFS.mkdirp(fixture); + await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'a'); + subscription = await b.watch(); + let event = await getNextBuild(b); + invariant(event.type === 'buildSuccess'); + let output1 = await overlayFS.readFile( + event.bundleGraph.getBundles()[0].filePath, + 'utf8', + ); + assert.strictEqual(output1, 'a'); + + // Change included file + await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'b'); + event = await getNextBuild(b); + invariant(event.type === 'buildSuccess'); + let output2 = await overlayFS.readFile( + event.bundleGraph.getBundles()[0].filePath, + 'utf8', + ); + assert.strictEqual(output2, 'b'); + + // Change included file back + await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'a'); + event = await getNextBuild(b); + invariant(event.type === 'buildSuccess'); + let output3 = await overlayFS.readFile( + event.bundleGraph.getBundles()[0].filePath, + 'utf8', + ); + assert.strictEqual(output3, 'a'); + } finally { + if (subscription) { + await subscription.unsubscribe(); + subscription = null; + } + } + }); + it('should support moving the project root', async function () { // This test relies on the real filesystem because the memory fs doesn't support renames. // But renameSync is broken on windows in CI with EPERM errors. Just skip this test for now.