diff --git a/CHANGELOG.md b/CHANGELOG.md index 590497f93b..adefb991de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- [#2342: Open fewer files at once during migration](https://github.com/alphagov/govuk-prototype-kit/pull/2342) + ## 13.13.2 ### Fixes diff --git a/lib/utils/asyncSerialMap.spec.js b/lib/utils/asyncSerialMap.spec.js new file mode 100644 index 0000000000..d665911a01 --- /dev/null +++ b/lib/utils/asyncSerialMap.spec.js @@ -0,0 +1,64 @@ +const { asyncSeriesMap } = require('./asyncSeriesMap') +describe('asyncSerialMap', () => { + const nextTick = () => new Promise((resolve) => { + process.nextTick(() => resolve()) + }) + + it('should work through an array and return the results', async () => { + const arr = ['abc', 'def', 'ghi'] + const handler = async (item) => `"${item}"` + + const result = await asyncSeriesMap(arr, handler) + + expect(result).toEqual([ + '"abc"', + '"def"', + '"ghi"' + ]) + }) + + it('should work through an array and return the results', async () => { + const arr = ['abc', 'def', 'ghi'] + const handler = async (item, index, array) => `"${item}|${index}|${JSON.stringify(array)}"` + + const result = await asyncSeriesMap(arr, handler) + + expect(result).toEqual([ + '"abc|0|["abc","def","ghi"]"', + '"def|1|["abc","def","ghi"]"', + '"ghi|2|["abc","def","ghi"]"' + ]) + }) + + it('should run these in series', async () => { + let latestResolve + let callCount = 0 + const handler = (item) => new Promise((resolve, reject) => { + callCount++ + latestResolve = resolve + }) + + const resultPromise = asyncSeriesMap(['abc', 'def', 'ghi'], handler) + + await nextTick() + + expect(callCount).toBe(1) + latestResolve('this is the first') + + await nextTick() + + expect(callCount).toBe(2) + latestResolve('this is the second') + + await nextTick() + + expect(callCount).toBe(3) + latestResolve('this is the third') + + expect(await resultPromise).toEqual([ + 'this is the first', + 'this is the second', + 'this is the third' + ]) + }) +}) diff --git a/lib/utils/asyncSeriesMap.js b/lib/utils/asyncSeriesMap.js new file mode 100644 index 0000000000..0c3e7e879d --- /dev/null +++ b/lib/utils/asyncSeriesMap.js @@ -0,0 +1,12 @@ +async function asyncSeriesMap (arr, handler) { + const results = [] + let index = -1 + while (arr.length > ++index) { + results.push(await handler(arr[index], index, arr)) + } + return results +} + +module.exports = { + asyncSeriesMap +} diff --git a/lib/utils/index.js b/lib/utils/index.js index 594172d3ec..9830576e80 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -19,6 +19,7 @@ const plugins = require('../plugins/plugins') const routes = require('../routes/api') const { appDir, projectDir, packageDir } = require('./paths') const fse = require('fs-extra') +const { asyncSeriesMap } = require('./asyncSeriesMap') // Tweak the Markdown renderer const defaultMarkedRenderer = marked.defaults.renderer || new marked.Renderer() @@ -234,7 +235,7 @@ function recursiveDirectoryContentsSync (baseDir) { async function searchAndReplaceFiles (dir, searchText, replaceText, extensions) { const files = await fsp.readdir(dir) - const modifiedFiles = await Promise.all(files.map(async file => { + const modifiedFiles = await asyncSeriesMap(files, async file => { const filePath = path.join(dir, file) const fileStat = await fsp.stat(filePath) @@ -248,7 +249,7 @@ async function searchAndReplaceFiles (dir, searchText, replaceText, extensions) return filePath } } - })) + }) return modifiedFiles.flat().filter(Boolean) } diff --git a/package.json b/package.json index a620067940..1b1e059836 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,6 @@ "/node_modules/", "/tmp/" ], - "testTimeout": 30000 + "testTimeout": 5000 } }