const chokidar = require('chokidar') const path = require('path') const fs = require('fs-extra') const _ = require('lodash') const minimist = require('minimist') const toolingRoot = path.join(__dirname, '..') const PROJECT_FIXTURE_DIRECTORY = 'projects' const DIR_PATH = path.join(toolingRoot, PROJECT_FIXTURE_DIRECTORY) const OUTPUT_PATH = path.join(toolingRoot, 'lib/fixtureDirs.ts') async function e2eTestScaffold () { return _e2eTestScaffold(true) } async function _e2eTestScaffold (cleanupEmpty = true) { const possibleDirectories = await fs.readdir(DIR_PATH) const dirs = await Promise.all(possibleDirectories.map(async (dir) => { const fullPath = path.join(DIR_PATH, dir) const stat = await fs.stat(fullPath) if (stat.isDirectory()) { if (await hasVisibleFileRecursive(fullPath)) { return fullPath } if (cleanupEmpty) { await fs.remove(fullPath) } return null } })) const allDirs = dirs.filter((dir) => dir) await fs.writeFile( OUTPUT_PATH, `/* eslint-disable */ // Auto-generated by ${path.basename(__filename)} (run yarn gulp e2eTestScaffold) export const fixtureDirs = [ ${allDirs .map((dir) => ` '${path.basename(dir)}'`).join(',\n')} ] as const export type ProjectFixtureDir = typeof fixtureDirs[number] `, ) return allDirs } async function e2eTestScaffoldWatch () { const fixtureWatcher = chokidar.watch(PROJECT_FIXTURE_DIRECTORY, { cwd: toolingRoot, // ignoreInitial: true, depth: 0, }) fixtureWatcher.on('unlinkDir', () => { e2eTestScaffold() }) fixtureWatcher.on('addDir', _.debounce(() => { _e2eTestScaffold(false) })) await e2eTestScaffold() } /** * From the basePath, checks for a valid file within that directory. Used to ignore empty * system tests directories left over from switching branches */ async function hasVisibleFileRecursive (basePath) { if (basePath.endsWith('node_modules')) { return false } const files = await fs.readdir(basePath) const toCheck = await Promise.all(files.filter((f) => !f.startsWith('.')).map(async (f) => { try { return { file: f, stat: await fs.stat(path.join(basePath, f)), } } catch { return null } })) if (toCheck.some((f) => f?.stat.isFile())) { return true } const directories = toCheck.filter((f) => f?.stat.isDirectory()) if (directories.length) { for (const dir of directories) { if (dir?.file && await hasVisibleFileRecursive(path.join(basePath, dir?.file))) { return true } } } return false } const options = minimist(process.argv) if (options.watch) { e2eTestScaffoldWatch() } else { e2eTestScaffold() }