diff --git a/build-system/pr-check/build-targets.js b/build-system/pr-check/build-targets.js index af985276d567..0cce23a8f01e 100644 --- a/build-system/pr-check/build-targets.js +++ b/build-system/pr-check/build-targets.js @@ -14,6 +14,7 @@ const {getLoggingPrefix, logWithoutTimestamp} = require('../common/logging'); const {gitDiffNameOnlyMain} = require('../common/git'); const {ignoreListFiles} = require('../tasks/check-ignore-lists'); const {isCiBuild} = require('../common/ci'); +const {shouldTriggerAva} = require('../tasks/ava'); /** * Used to prevent the repeated recomputing of build targets during PR jobs. @@ -115,16 +116,7 @@ const targetMatchers = { if (isOwnersFile(file)) { return false; } - return ( - file == 'build-system/tasks/ava.js' || - file.startsWith('build-system/release-tagger/') || - file.startsWith('build-system/server/') || - file.startsWith('build-system/tasks/css/') || - file.startsWith('build-system/tasks/get-zindex/') || - file.startsWith('build-system/tasks/make-extension/') || - file.startsWith('build-system/tasks/markdown-toc/') || - file.startsWith('build-system/tasks/prepend-global/') - ); + return shouldTriggerAva(file); }, [Targets.BABEL_PLUGIN]: (file) => { if (isOwnersFile(file)) { diff --git a/build-system/tasks/ava.js b/build-system/tasks/ava.js index 6e56909e8c17..eec6178a4bf2 100644 --- a/build-system/tasks/ava.js +++ b/build-system/tasks/ava.js @@ -1,25 +1,46 @@ 'use strict'; const argv = require('minimist')(process.argv.slice(2)); +const {dirname, relative} = require('path'); const {execOrDie} = require('../common/exec'); +const {sync: globbySync} = require('globby'); + +const testFiles = [ + 'build-system/release-tagger/test/*test*.js', + 'build-system/server/app-index/test/*test*.js', + 'build-system/server/test/app-utils.test.js', + 'build-system/tasks/css/test/bento-css.test.js', + 'build-system/tasks/get-zindex/get-zindex.test.js', + 'build-system/tasks/make-extension/test/test.js', + 'build-system/tasks/markdown-toc/test/test.js', + 'build-system/tasks/prepend-global/prepend-global.test.js', +]; + +let targetFiles; + +/** + * Determines whether to trigger ava by a file change adjacent to a test file. + * Considered adjacent when the file changed is in the same directory as one of + * the listed test files, or its parent if the directory is named `test`. + * @param {string} changedFile + * @return {boolean} + */ +function shouldTriggerAva(changedFile) { + if (!targetFiles) { + const thisFile = relative(process.cwd(), __filename); + const patterns = testFiles.map( + (pattern) => dirname(pattern).replace(/\/test$/, '') + '/' + ); + targetFiles = new Set([thisFile, ...globbySync(patterns)]); + } + return targetFiles.has(changedFile); +} /** * Runs ava tests. * @return {Promise} */ async function ava() { - // These need equivalents for CI in build-system/pr-check/build-targets.js - // (see targetMatchers[Targets.AVA]) - const testFiles = [ - 'build-system/release-tagger/test/*test*.js', - 'build-system/server/app-index/test/*test*.js', - 'build-system/server/test/app-utils.test.js', - 'build-system/tasks/css/test/bento-css.test.js', - 'build-system/tasks/get-zindex/get-zindex.test.js', - 'build-system/tasks/make-extension/test/test.js', - 'build-system/tasks/markdown-toc/test/test.js', - 'build-system/tasks/prepend-global/prepend-global.test.js', - ]; execOrDie( [ 'npx ava', @@ -32,6 +53,7 @@ async function ava() { module.exports = { ava, + shouldTriggerAva, }; ava.description = "Run ava tests for AMP's tasks";