From 5669fc73c0d0ac00d744e22b067bcfc3312b8314 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Mon, 14 Aug 2023 19:26:01 -0400 Subject: [PATCH] [snap] Refactor fixture utils to separate package --- Move shared functions to `fixture-test-utils` package. --- .../packages/fixture-test-utils/package.json | 25 +++ .../fixture-test-utils/src/compiler-utils.ts | 122 +++++++++++ .../fixture-test-utils/src/constants.ts | 24 +++ .../fixture-test-utils/src/fixture-utils.ts | 161 ++++++++++++++ .../packages/fixture-test-utils/src/index.ts | 3 + .../packages/fixture-test-utils/tsconfig.json | 20 ++ compiler/forget/packages/snap/package.json | 5 +- .../packages/snap/src/compiler-worker.ts | 198 ++---------------- compiler/forget/packages/snap/src/main.ts | 2 +- compiler/forget/packages/snap/src/runner.ts | 107 +--------- compiler/forget/packages/snap/src/utils.ts | 17 -- 11 files changed, 375 insertions(+), 309 deletions(-) create mode 100644 compiler/forget/packages/fixture-test-utils/package.json create mode 100644 compiler/forget/packages/fixture-test-utils/src/compiler-utils.ts create mode 100644 compiler/forget/packages/fixture-test-utils/src/constants.ts create mode 100644 compiler/forget/packages/fixture-test-utils/src/fixture-utils.ts create mode 100644 compiler/forget/packages/fixture-test-utils/src/index.ts create mode 100644 compiler/forget/packages/fixture-test-utils/tsconfig.json delete mode 100644 compiler/forget/packages/snap/src/utils.ts diff --git a/compiler/forget/packages/fixture-test-utils/package.json b/compiler/forget/packages/fixture-test-utils/package.json new file mode 100644 index 0000000000..6c47e26a5c --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/package.json @@ -0,0 +1,25 @@ +{ + "name": "fixture-test-utils", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "build": "rimraf dist && tsc", + "test": "echo 'no tests'", + "prettier": "prettier --write src" + }, + "dependencies": { + "@parcel/watcher": "^2.1.0", + "chalk": "4", + "readline": "^1.3.0", + "typescript": "^5.1.0", + "yargs": "^17.7.1" + }, + "devDependencies": { + "@types/node": "^18.7.18", + "@typescript-eslint/eslint-plugin": "^5.51.0", + "@typescript-eslint/parser": "^5.51.0", + "prettier": "2.8.8", + "rimraf": "^3.0.2" + } +} diff --git a/compiler/forget/packages/fixture-test-utils/src/compiler-utils.ts b/compiler/forget/packages/fixture-test-utils/src/compiler-utils.ts new file mode 100644 index 0000000000..c9439efe8b --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/src/compiler-utils.ts @@ -0,0 +1,122 @@ +import type { runReactForgetBabelPlugin as RunReactForgetBabelPlugin } from "babel-plugin-react-forget/src/Babel/RunReactForgetBabelPlugin"; +import type { Effect, ValueKind } from "babel-plugin-react-forget/src/HIR"; + +const FlowPragmas = [/\/\/\s@flow$/gm, /\*\s@flow$/gm]; + +export function parseLanguage(source: string): "flow" | "typescript" { + let useFlow = false; + for (const flowPragma of FlowPragmas) { + useFlow ||= !!source.match(flowPragma); + } + return useFlow ? "flow" : "typescript"; +} + +export function transformFixtureInput( + input: string, + basename: string, + pluginFn: typeof RunReactForgetBabelPlugin, + includeAst: boolean = false +) { + // Extract the first line to quickly check for custom test directives + const firstLine = input.substring(0, input.indexOf("\n")); + + let language = parseLanguage(firstLine); + let enableOnlyOnUseForgetDirective = false; + let gating = null; + let instrumentForget = null; + let panicOnBailout = true; + let memoizeJsxElements = true; + let enableAssumeHooksFollowRulesOfReact = false; + let enableTreatHooksAsFunctions = true; + let disableAllMemoization = false; + let validateRefAccessDuringRender = true; + let validateNoSetStateInRender = true; + let enableEmitFreeze = null; + let enableOptimizeFunctionExpressions = true; + let enableOnlyOnReactScript = false; + + if (firstLine.indexOf("@forgetDirective") !== -1) { + enableOnlyOnUseForgetDirective = true; + } + if (firstLine.includes("@gating")) { + gating = { + source: "ReactForgetFeatureFlag", + importSpecifierName: "isForgetEnabled_Fixtures", + }; + } + if (firstLine.includes("@instrumentForget")) { + instrumentForget = { + source: "react-forget-runtime", + importSpecifierName: "useRenderCounter", + }; + } + if (firstLine.includes("@panicOnBailout false")) { + panicOnBailout = false; + } + if (firstLine.includes("@memoizeJsxElements false")) { + memoizeJsxElements = false; + } + if (firstLine.includes("@enableAssumeHooksFollowRulesOfReact true")) { + enableAssumeHooksFollowRulesOfReact = true; + } + if (firstLine.includes("@enableTreatHooksAsFunctions false")) { + enableTreatHooksAsFunctions = false; + } + if (firstLine.includes("@disableAllMemoization true")) { + disableAllMemoization = true; + } + if (firstLine.includes("@validateRefAccessDuringRender false")) { + validateRefAccessDuringRender = false; + } + if (firstLine.includes("@validateNoSetStateInRender false")) { + validateNoSetStateInRender = false; + } + if (firstLine.includes("@enableOptimizeFunctionExpressions false")) { + enableOptimizeFunctionExpressions = false; + } + if (firstLine.includes("@enableEmitFreeze")) { + enableEmitFreeze = { + source: "react-forget-runtime", + importSpecifierName: "makeReadOnly", + }; + } + if (firstLine.indexOf("@reactScriptDirective") !== -1) { + enableOnlyOnReactScript = true; + language = "flow"; + } + + return pluginFn(input, basename, language, { + environment: { + customHooks: new Map([ + [ + "useFreeze", + { + valueKind: "frozen" as ValueKind, + effectKind: "freeze" as Effect, + }, + ], + ]), + enableAssumeHooksFollowRulesOfReact, + enableFunctionCallSignatureOptimizations: true, + disableAllMemoization, + enableTreatHooksAsFunctions, + inlineUseMemo: true, + memoizeJsxElements, + validateHooksUsage: true, + validateRefAccessDuringRender, + validateFrozenLambdas: true, + validateNoSetStateInRender, + enableEmitFreeze, + enableOptimizeFunctionExpressions, + assertValidMutableRanges: true, + }, + enableOnlyOnUseForgetDirective, + enableOnlyOnReactScript, + logger: null, + gating, + instrumentForget, + panicOnBailout, + isDev: true, + noEmit: false, + }); +} diff --git a/compiler/forget/packages/fixture-test-utils/src/constants.ts b/compiler/forget/packages/fixture-test-utils/src/constants.ts new file mode 100644 index 0000000000..a55c2f1b23 --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/src/constants.ts @@ -0,0 +1,24 @@ +import path from "path"; + +// We assume this is run from `babel-plugin-react-forget` +export const COMPILER_PATH = path.join( + process.cwd(), + "dist", + "Babel", + "RunReactForgetBabelPlugin.js" +); +export const LOGGER_PATH = path.join( + process.cwd(), + "dist", + "Utils", + "logger.js" +); +export const FIXTURES_PATH = path.join( + process.cwd(), + "src", + "__tests__", + "fixtures", + "compiler" +); +export const FILTER_FILENAME = "testfilter.txt"; +export const FILTER_PATH = path.join(process.cwd(), FILTER_FILENAME); diff --git a/compiler/forget/packages/fixture-test-utils/src/fixture-utils.ts b/compiler/forget/packages/fixture-test-utils/src/fixture-utils.ts new file mode 100644 index 0000000000..1cc3bfa557 --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/src/fixture-utils.ts @@ -0,0 +1,161 @@ +import fs from "fs/promises"; +import glob from "glob"; +import invariant from "invariant"; +import path from "path"; +import { FILTER_PATH, FIXTURES_PATH } from "./constants"; + +export type TestFilter = + | { + kind: "only"; + paths: Array; + } + | { + kind: "skip"; + paths: Array; + }; + +async function exists(file: string): Promise { + try { + await fs.access(file); + return true; + } catch { + return false; + } +} + +export async function readTestFilter(): Promise { + if (!(await exists(FILTER_PATH))) { + throw new Error(`testfilter file not found at ${FILTER_PATH}`); + } + + const input = await fs.readFile(FILTER_PATH, "utf8"); + const lines = input.trim().split("\n"); + if (lines.length < 2) { + console.warn("Misformed filter file. Expected at least two lines."); + return null; + } + + let filter: "only" | "skip" | null = null; + if (lines[0]!.indexOf("@only") !== -1) { + filter = "only"; + } + if (lines[0]!.indexOf("@skip") !== -1) { + filter = "skip"; + } + if (filter === null) { + console.warn( + "Misformed filter file. Expected first line to contain @only or @skip" + ); + return null; + } + lines.shift(); + return { + kind: filter, + paths: lines, + }; +} + +export type TestFixture = { + basename: string; + inputPath: string; + inputExists: boolean; + outputPath: string; + outputExists: boolean; +}; + +export function getFixtures( + filter: TestFilter | null +): Map { + // search for fixtures within nested directories + const files = glob.sync(`**/*.{js,md}`, { + cwd: FIXTURES_PATH, + }); + const fixtures: Map = new Map(); + + for (const filePath of files) { + const basename = path.basename( + path.basename(filePath, ".js"), + ".expect.md" + ); + // "partial" paths do not include suffixes + const partialRelativePath = path.join(path.dirname(filePath), basename); + // Replicate jest test behavior + if (basename.startsWith("todo.")) { + continue; + } + if (filter) { + if ( + filter.kind === "only" && + filter.paths.indexOf(partialRelativePath) === -1 + ) { + continue; + } else if ( + filter.kind === "skip" && + filter.paths.indexOf(partialRelativePath) !== -1 + ) { + continue; + } + } + + let fixtureInfo = fixtures.get(partialRelativePath); + if (fixtureInfo === undefined) { + const partialAbsolutePath = path.join(FIXTURES_PATH, partialRelativePath); + fixtureInfo = { + basename, + inputPath: `${partialAbsolutePath}.js`, + inputExists: false, + outputPath: `${partialAbsolutePath}.expect.md`, + outputExists: false, + }; + fixtures.set(partialRelativePath, fixtureInfo); + } + + if (filePath.endsWith(".js")) { + fixtureInfo.inputExists = true; + } else { + fixtureInfo.outputExists = true; + } + } + + return fixtures; +} + +function wrapWithTripleBackticks(s: string, ext: string | null = null): string { + return `\`\`\`${ext ?? ""} +${s} +\`\`\``; +} + +export function writeOutputToString( + input: string, + output: string | null, + error: Error | null +) { + // leading newline intentional + let result = ` +## Input + +${wrapWithTripleBackticks(input, "javascript")} +`; // trailing newline + space internional + + if (output != null) { + result += ` +## Code + +${output == null ? "[ none ]" : wrapWithTripleBackticks(output, "javascript")} +`; + } else { + result += "\n"; + } + + if (error != null) { + const errorMessage = error.message.replace(/^\/.*?:\s/, ""); + + result += ` +## Error + +${wrapWithTripleBackticks(errorMessage)} + \n`; + } + return result + ` `; +} diff --git a/compiler/forget/packages/fixture-test-utils/src/index.ts b/compiler/forget/packages/fixture-test-utils/src/index.ts new file mode 100644 index 0000000000..e3a8824c01 --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/src/index.ts @@ -0,0 +1,3 @@ +export * from "./constants"; +export * from "./fixture-utils"; +export * from "./compiler-utils"; diff --git a/compiler/forget/packages/fixture-test-utils/tsconfig.json b/compiler/forget/packages/fixture-test-utils/tsconfig.json new file mode 100644 index 0000000000..4420706d67 --- /dev/null +++ b/compiler/forget/packages/fixture-test-utils/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@tsconfig/node16-strictest/tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "jsx": "react-jsxdev", + + // weaken strictness from preset + "importsNotUsedAsValues": "remove", + "noUncheckedIndexedAccess": false, + "noUnusedParameters": false, + "useUnknownInCatchVariables": false, + "target": "ES2015", + // ideally turn off only during dev, or on a per-file basis + "noUnusedLocals": false, + "sourceMap": true + }, + "exclude": ["node_modules"], + "include": ["src/**/*.ts"] +} diff --git a/compiler/forget/packages/snap/package.json b/compiler/forget/packages/snap/package.json index 4cc6c25e72..c86bfd3b6b 100644 --- a/compiler/forget/packages/snap/package.json +++ b/compiler/forget/packages/snap/package.json @@ -9,7 +9,7 @@ "src" ], "scripts": { - "build": "rimraf dist && tsc", + "build": "yarn workspace fixture-test-utils run build && rimraf dist && tsc", "test": "echo 'no tests'", "lint": "yarn eslint src" }, @@ -22,7 +22,8 @@ "chalk": "4", "readline": "^1.3.0", "typescript": "^5.1.0", - "yargs": "^17.7.1" + "yargs": "^17.7.1", + "fixture-test-utils": "*" }, "devDependencies": { "@types/node": "^18.7.18", diff --git a/compiler/forget/packages/snap/src/compiler-worker.ts b/compiler/forget/packages/snap/src/compiler-worker.ts index f06177ffc6..fd44aaa726 100644 --- a/compiler/forget/packages/snap/src/compiler-worker.ts +++ b/compiler/forget/packages/snap/src/compiler-worker.ts @@ -6,9 +6,8 @@ */ import type { runReactForgetBabelPlugin as RunReactForgetBabelPlugin } from 'babel-plugin-react-forget/src/Babel/RunReactForgetBabelPlugin'; -import type { Effect, ValueKind } from 'babel-plugin-react-forget/src/HIR'; +import { TestFixture, transformFixtureInput, writeOutputToString } from 'fixture-test-utils'; import fs from "fs/promises"; -import { exists } from "./utils"; const originalConsoleError = console.error; @@ -33,12 +32,6 @@ export type TestResult = { unexpectedError: string | null; }; -export type TestFixture = { - basename: string; - inputPath: string; - outputPath: string; -}; - export async function compile( compilerPath: string, loggerPath: string, @@ -54,11 +47,11 @@ export async function compile( clearRequireCache(); } version = compilerVersion; - const { inputPath, outputPath, basename } = fixture; - const input = (await exists(inputPath)) + const { inputPath, inputExists, outputPath, outputExists, basename } = fixture; + const input = inputExists ? await fs.readFile(inputPath, "utf8") : null; - const expected = (await exists(outputPath)) + const expected = outputExists ? await fs.readFile(outputPath, "utf8") : null; @@ -86,108 +79,7 @@ export async function compile( // since console log order is non-deterministic const shouldLogPragma = input.split("\n")[0].includes("@debug"); toggleLogging(isOnlyFixture && shouldLogPragma); - - // Extract the first line to quickly check for custom test directives - const firstLine = input.substring(0, input.indexOf("\n")); - let language = parseLanguage(firstLine); - - let enableOnlyOnUseForgetDirective = false; - let gating = null; - let instrumentForget = null; - let panicOnBailout = true; - let memoizeJsxElements = true; - let enableAssumeHooksFollowRulesOfReact = false; - let enableTreatHooksAsFunctions = true; - let disableAllMemoization = false; - let validateRefAccessDuringRender = true; - let validateNoSetStateInRender = true; - let enableEmitFreeze = null; - let enableOptimizeFunctionExpressions = true; - let enableOnlyOnReactScript = false; - if (firstLine.indexOf("@forgetDirective") !== -1) { - enableOnlyOnUseForgetDirective = true; - } - if (firstLine.includes("@gating")) { - gating = { - source: "ReactForgetFeatureFlag", - importSpecifierName: "isForgetEnabled_Fixtures", - }; - } - if (firstLine.includes("@instrumentForget")) { - instrumentForget = { - source: "react-forget-runtime", - importSpecifierName: "useRenderCounter", - }; - } - if (firstLine.includes("@panicOnBailout false")) { - panicOnBailout = false; - } - if (firstLine.includes("@memoizeJsxElements false")) { - memoizeJsxElements = false; - } - if (firstLine.includes("@enableAssumeHooksFollowRulesOfReact true")) { - enableAssumeHooksFollowRulesOfReact = true; - } - if (firstLine.includes("@enableTreatHooksAsFunctions false")) { - enableTreatHooksAsFunctions = false; - } - if (firstLine.includes("@disableAllMemoization true")) { - disableAllMemoization = true; - } - if (firstLine.includes("@validateRefAccessDuringRender false")) { - validateRefAccessDuringRender = false; - } - if (firstLine.includes("@validateNoSetStateInRender false")) { - validateNoSetStateInRender = false; - } - if (firstLine.includes("@enableOptimizeFunctionExpressions false")) { - enableOptimizeFunctionExpressions = false; - } - if (firstLine.includes("@enableEmitFreeze")) { - enableEmitFreeze = { - source: "react-forget-runtime", - importSpecifierName: "makeReadOnly", - }; - } - if (firstLine.indexOf("@reactScriptDirective") !== -1) { - enableOnlyOnReactScript = true; - language = "flow"; - } - - code = runReactForgetBabelPlugin(input, basename, language, { - environment: { - customHooks: new Map([ - [ - "useFreeze", - { - valueKind: "frozen" as ValueKind, - effectKind: "freeze" as Effect, - }, - ], - ]), - enableAssumeHooksFollowRulesOfReact, - enableFunctionCallSignatureOptimizations: true, - disableAllMemoization, - enableTreatHooksAsFunctions, - inlineUseMemo: true, - memoizeJsxElements, - validateHooksUsage: true, - validateRefAccessDuringRender, - validateFrozenLambdas: true, - validateNoSetStateInRender, - enableEmitFreeze, - enableOptimizeFunctionExpressions, - assertValidMutableRanges: true, - }, - enableOnlyOnUseForgetDirective, - enableOnlyOnReactScript, - logger: null, - gating, - instrumentForget, - panicOnBailout, - isDev: true, - noEmit: false, - }).code; + code = transformFixtureInput(input, basename, runReactForgetBabelPlugin).code; } catch (e) { error = e; } @@ -202,92 +94,28 @@ export async function compile( } } - let output: string; + const output = writeOutputToString(input, code, error); const expectError = basename.startsWith("error."); + let unexpectedError: string | null = null; if (expectError) { if (error === null) { - return { - inputPath, - outputPath, - actual: code, - expected, - unexpectedError: `Expected an error to be thrown for fixture: '${basename}', remove the 'error.' prefix if an error is not expected.`, - }; - } else if (code != null) { - output = `${formatOutput(code)}\n${formatErrorOutput(error)}`; - } else { - output = formatErrorOutput(error); + unexpectedError = `Expected an error to be thrown for fixture: '${basename}', remove the 'error.' prefix if an error is not expected.`; } } else { if (error !== null) { - return { - inputPath, - outputPath, - actual: code, - expected, - unexpectedError: `Expected fixture '${basename}' to succeed but it failed with error:\n\n${error.message}`, - }; + unexpectedError = `Expected fixture '${basename}' to succeed but it failed with error:\n\n${error.message}`; + } else if (code == null || code.length === 0) { + unexpectedError = `Expected output for fixture '${basename}'.`; } - if (code == null || code.length === 0) { - return { - inputPath, - outputPath, - actual: code, - expected, - unexpectedError: `Expected output for fixture '${basename}'.`, - }; - } - output = formatOutput(code); } - // leading newline intentional - const actual = ` -## Input - -${wrapWithTripleBackticks(input, "javascript")} - -${output} - `; // trailing newline + space internional - console.error = originalConsoleError; return { inputPath, outputPath, - actual, + actual: output, expected, - unexpectedError: null, + unexpectedError, }; } - -function formatErrorOutput(error: Error): string { - error.message = error.message.replace(/^\/.*?:\s/, ""); - return ` -## Error - -${wrapWithTripleBackticks(error.message)} - `; -} - -function formatOutput(code: string): string { - return ` -## Code - -${wrapWithTripleBackticks(code, "javascript")} - `.trim(); -} - -function wrapWithTripleBackticks(s: string, ext: string | null = null): string { - return `\`\`\`${ext ?? ""} -${s} -\`\`\``; -} - -const FlowPragmas = [/\/\/\s@flow$/gm, /\*\s@flow$/gm]; -function parseLanguage(source: string): "flow" | "typescript" { - let useFlow = false; - for (const flowPragma of FlowPragmas) { - useFlow ||= !!source.match(flowPragma); - } - return useFlow ? "flow" : "typescript"; -} diff --git a/compiler/forget/packages/snap/src/main.ts b/compiler/forget/packages/snap/src/main.ts index 6ee3f7a806..d1ba9c7e38 100644 --- a/compiler/forget/packages/snap/src/main.ts +++ b/compiler/forget/packages/snap/src/main.ts @@ -17,7 +17,7 @@ if (process.stdin.isTTY) { process.stdin.setRawMode(true); } -process.stdin.on("keypress", function (chunk, key) { +process.stdin.on("keypress", function (_, key) { if (key && key.name === "c" && key.ctrl) { // handle sigint if (childProc) { diff --git a/compiler/forget/packages/snap/src/runner.ts b/compiler/forget/packages/snap/src/runner.ts index 1d945cd8f7..8716c3da0d 100644 --- a/compiler/forget/packages/snap/src/runner.ts +++ b/compiler/forget/packages/snap/src/runner.ts @@ -7,8 +7,8 @@ import watcher from "@parcel/watcher"; import chalk from "chalk"; +import { COMPILER_PATH, LOGGER_PATH, FIXTURES_PATH, FILTER_FILENAME, FILTER_PATH, readTestFilter, TestFilter } from 'fixture-test-utils'; import fs from "fs/promises"; -import glob from "glob"; import invariant from "invariant"; import { diff } from "jest-diff"; import { Worker } from "jest-worker"; @@ -19,26 +19,10 @@ import ts from "typescript"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { TestResult } from "./compiler-worker"; -import * as compiler from "./compiler-worker.js"; -import { exists } from "./utils"; +import * as compiler from "./compiler-worker"; +import {getFixtures} from 'fixture-test-utils'; const WORKER_PATH = require.resolve("./compiler-worker.js"); -const COMPILER_PATH = path.join( - process.cwd(), - "dist", - "Babel", - "RunReactForgetBabelPlugin.js" -); -const LOGGER_PATH = path.join(process.cwd(), "dist", "Utils", "logger.js"); -const FIXTURES_PATH = path.join( - process.cwd(), - "src", - "__tests__", - "fixtures", - "compiler" -); -const FILTER_FILENAME = "testfilter.txt"; -const FILTER_PATH = path.join(process.cwd(), FILTER_FILENAME); readline.emitKeypressEvents(process.stdin); @@ -109,49 +93,6 @@ function clearConsole() { console.log("\u001Bc"); } -function getFixtures( - filter: TestFilter | null -): Map { - // search for fixtures within nested directories - const files = glob.sync(`**/*.{js,md}`, { - cwd: FIXTURES_PATH, - }); - const fixtures = new Map(); - - for (const filePath of files) { - const basename = path.basename( - path.basename(filePath, ".js"), - ".expect.md" - ); - // "partial" paths do not include suffixes - const partialRelativePath = path.join(path.dirname(filePath), basename); - const partialAbsolutePath = path.join(FIXTURES_PATH, partialRelativePath); - // Replicate jest test behavior - if (basename.startsWith("todo.")) { - continue; - } - if (filter) { - if ( - filter.kind === "only" && - filter.paths.indexOf(partialRelativePath) === -1 - ) { - continue; - } else if ( - filter.kind === "skip" && - filter.paths.indexOf(partialRelativePath) !== -1 - ) { - continue; - } - } - fixtures.set(partialRelativePath, { - basename, - inputPath: `${partialAbsolutePath}.js`, - outputPath: `${partialAbsolutePath}.expect.md`, - }); - } - // console.log("fixtures!", JSON.stringify(Array.from(fixtures.keys()))); - return fixtures; -} /** * Do a test run and return the test results */ @@ -395,48 +336,6 @@ enum Mode { Update = "Update", } -type TestFilter = - | { - kind: "only"; - paths: Array; - } - | { - kind: "skip"; - paths: Array; - }; - -async function readTestFilter(): Promise { - if (!(await exists(FILTER_PATH))) { - throw new Error(`testfilter file not found at ${FILTER_PATH}`); - } - - const input = await fs.readFile(FILTER_PATH, "utf8"); - const lines = input.trim().split("\n"); - if (lines.length < 2) { - console.warn("Misformed filter file. Expected at least two lines."); - return null; - } - - let filter: "only" | "skip" | null = null; - if (lines[0]!.indexOf("@only") !== -1) { - filter = "only"; - } - if (lines[0]!.indexOf("@skip") !== -1) { - filter = "skip"; - } - if (filter === null) { - console.warn( - "Misformed filter file. Expected first line to contain @only or @skip" - ); - return null; - } - lines.shift(); - return { - kind: filter, - paths: lines, - }; -} - /** * Runs the compiler in watch or single-execution mode */ diff --git a/compiler/forget/packages/snap/src/utils.ts b/compiler/forget/packages/snap/src/utils.ts deleted file mode 100644 index ef18f7e432..0000000000 --- a/compiler/forget/packages/snap/src/utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import fs from "fs/promises"; - -export async function exists(file: string): Promise { - try { - await fs.access(file); - return true; - } catch { - return false; - } -}