Remove debugging statements or use a logging library
console.log(`\nEnabling flag "${flagName}" in Environment.ts...`);
1#!/usr/bin/env node2/**3 * Copyright (c) Meta Platforms, Inc. and affiliates.4 *5 * This source code is licensed under the MIT license found in the6 * LICENSE file in the root directory of this source tree.7 */89'use strict';1011const fs = require('fs');12const path = require('path');13const {execSync} = require('child_process');14const yargs = require('yargs/yargs');15const {hideBin} = require('yargs/helpers');1617// Constants18const COMPILER_ROOT = path.resolve(__dirname, '..');19const ENVIRONMENT_TS_PATH = path.join(20 COMPILER_ROOT,21 'packages/babel-plugin-react-compiler/src/HIR/Environment.ts'22);23const FIXTURES_PATH = path.join(24 COMPILER_ROOT,25 'packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler'26);27const FIXTURE_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx'];2829/**30 * Parse command line arguments31 */32function parseArgs() {33 const argv = yargs(hideBin(process.argv))34 .usage('Usage: $0 <flag-name>')35 .command('$0 <flag-name>', 'Enable a feature flag by default', yargs => {36 yargs.positional('flag-name', {37 describe: 'Name of the feature flag to enable',38 type: 'string',39 });40 })41 .example(42 '$0 validateExhaustiveMemoizationDependencies',43 'Enable the validateExhaustiveMemoizationDependencies flag'44 )45 .help('h')46 .alias('h', 'help')47 .strict()48 .parseSync();4950 return argv['flag-name'];51}5253/**54 * Enable a feature flag in Environment.ts by changing default(false) to default(true)55 */56function enableFlagInEnvironment(flagName) {57 console.log(`\nEnabling flag "${flagName}" in Environment.ts...`);5859 const content = fs.readFileSync(ENVIRONMENT_TS_PATH, 'utf8');6061 // Check if the flag exists with default(false)62 const flagPatternFalse = new RegExp(63 `(${escapeRegex(flagName)}:\\s*z\\.boolean\\(\\)\\.default\\()false(\\))`,64 'g'65 );6667 if (!flagPatternFalse.test(content)) {68 // Check if flag exists at all69 const flagExistsPattern = new RegExp(70 `${escapeRegex(flagName)}:\\s*z\\.boolean\\(\\)`,71 'g'72 );73 if (flagExistsPattern.test(content)) {74 // Check if it's already true75 const flagPatternTrue = new RegExp(76 `${escapeRegex(flagName)}:\\s*z\\.boolean\\(\\)\\.default\\(true\\)`,77 'g'78 );79 if (flagPatternTrue.test(content)) {80 console.error(`Error: Flag "${flagName}" already has default(true)`);81 process.exit(1);82 }83 console.error(84 `Error: Flag "${flagName}" exists but doesn't have default(false)`85 );86 process.exit(1);87 }88 console.error(`Error: Flag "${flagName}" not found in Environment.ts`);89 process.exit(1);90 }9192 // Perform the replacement93 const newContent = content.replace(flagPatternFalse, '$1true$2');9495 // Verify the replacement worked96 if (content === newContent) {97 console.error(`Error: Failed to replace flag "${flagName}"`);98 process.exit(1);99 }100101 fs.writeFileSync(ENVIRONMENT_TS_PATH, newContent, 'utf8');102 console.log(`Successfully enabled "${flagName}" in Environment.ts`);103}104105/**106 * Helper to escape regex special characters107 */108function escapeRegex(string) {109 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');110}111112/**113 * Run yarn snap and capture output114 */115function runTests() {116 console.log('\nRunning test suite (yarn snap)...');117118 try {119 const output = execSync('yarn snap', {120 cwd: COMPILER_ROOT,121 encoding: 'utf8',122 stdio: 'pipe',123 maxBuffer: 10 * 1024 * 1024, // 10MB buffer124 });125 return {success: true, output};126 } catch (error) {127 // yarn snap exits with code 1 when tests fail, which throws an error128 return {success: false, output: error.stdout || error.message};129 }130}131132/**133 * Parse failing test names from test output134 */135function parseFailingTests(output) {136 const failingTests = [];137138 // Look for lines that contain "FAIL:" followed by the test name139 // Format: "FAIL: test-name" or with ANSI codes140 const lines = output.split('\n');141 for (const line of lines) {142 // Remove ANSI codes for easier parsing143 const cleanLine = line.replace(/\x1b\[[0-9;]*m/g, '');144145 // Match "FAIL: test-name"146 const match = cleanLine.match(/^FAIL:\s*(.+)$/);147 if (match) {148 failingTests.push(match[1].trim());149 }150 }151152 return failingTests;153}154155/**156 * Find the fixture file for a given test name157 */158function findFixtureFile(testName) {159 const basePath = path.join(FIXTURES_PATH, testName);160161 for (const ext of FIXTURE_EXTENSIONS) {162 const filePath = basePath + ext;163 if (fs.existsSync(filePath)) {164 return filePath;165 }166 }167168 return null;169}170171/**172 * Add pragma to disable the feature flag in a fixture file173 */174function addPragmaToFixture(filePath, flagName) {175 const content = fs.readFileSync(filePath, 'utf8');176 const lines = content.split('\n');177178 if (lines.length === 0) {179 console.warn(`Warning: Empty file ${filePath}`);180 return false;181 }182183 const firstLine = lines[0];184 const pragma = `@${flagName}:false`;185186 // Check if pragma already exists187 if (firstLine.includes(pragma)) {188 return false; // Already has the pragma189 }190191 // Check if first line is a single-line comment192 if (firstLine.trim().startsWith('//')) {193 // Append pragma to existing comment194 lines[0] = firstLine + ' ' + pragma;195 } else if (firstLine.trim().startsWith('/*')) {196 // Multi-line comment - insert new line before it197 lines.unshift('// ' + pragma);198 } else {199 // No comment - insert new comment as first line200 lines.unshift('// ' + pragma);201 }202203 fs.writeFileSync(filePath, lines.join('\n'), 'utf8');204 return true;205}206207/**208 * Update snapshot files209 */210function updateSnapshots() {211 console.log('\nUpdating snapshots (yarn snap -u)...');212213 try {214 execSync('yarn snap -u', {215 cwd: COMPILER_ROOT,216 encoding: 'utf8',217 stdio: 'pipe',218 maxBuffer: 10 * 1024 * 1024,219 });220 console.log('Snapshots updated successfully');221 return true;222 } catch (error) {223 console.error('Error updating snapshots:', error.message);224 return false;225 }226}227228/**229 * Verify all tests pass230 */231function verifyAllTestsPass() {232 console.log('\nRunning final verification (yarn snap)...');233234 const {success, output} = runTests();235236 // Parse summary line: "N Tests, N Passed, N Failed"237 const summaryMatch = output.match(238 /(\d+)\s+Tests,\s+(\d+)\s+Passed,\s+(\d+)\s+Failed/239 );240241 if (summaryMatch) {242 const [, total, passed, failed] = summaryMatch;243 console.log(244 `\nTest Results: ${total} Tests, ${passed} Passed, ${failed} Failed`245 );246247 if (failed === '0') {248 console.log('All tests passed!');249 return true;250 } else {251 console.error(`${failed} tests still failing`);252 const failingTests = parseFailingTests(output);253 if (failingTests.length > 0) {254 console.error('\nFailing tests:');255 failingTests.forEach(test => console.error(` - ${test}`));256 }257 return false;258 }259 }260261 return success;262}263264/**265 * Main function266 */267async function main() {268 const flagName = parseArgs();269270 console.log(`\nEnabling flag: '${flagName}'`);271272 try {273 // Step 1: Enable flag in Environment.ts274 enableFlagInEnvironment(flagName);275276 // Step 2: Run tests to find failures277 const {output} = runTests();278 const failingTests = parseFailingTests(output);279280 console.log(`\nFound ${failingTests.length} failing tests`);281282 if (failingTests.length === 0) {283 console.log('No failing tests! Feature flag enabled successfully.');284 process.exit(0);285 }286287 // Step 3: Add pragma to each failing fixture288 console.log(`\nAdding '@${flagName}:false' pragma to failing fixtures...`);289290 const notFound = [];291 let notFoundCount = 0;292293 for (const testName of failingTests) {294 const fixturePath = findFixtureFile(testName);295296 if (!fixturePath) {297 console.warn(`Could not find fixture file for: ${testName}`);298 notFound.push(fixturePath);299 continue;300 }301302 const updated = addPragmaToFixture(fixturePath, flagName);303 if (updated) {304 updatedCount++;305 console.log(` Updated: ${testName}`);306 }307 }308309 console.log(310 `\nSummary: Updated ${updatedCount} fixtures, ${notFoundCount} not found`311 );312313 if (notFoundCount.length !== 0) {314 console.error(315 '\nFailed to update snapshots, could not find:\n' + notFound.join('\n')316 );317 process.exit(1);318 }319320 // Step 4: Update snapshots321 if (!updateSnapshots()) {322 console.error('\nFailed to update snapshots');323 process.exit(1);324 }325326 // Step 5: Verify all tests pass327 if (!verifyAllTestsPass()) {328 console.error('\nVerification failed: Some tests are still failing');329 process.exit(1);330 }331332 console.log('\nSuccess! Feature flag enabled and all tests passing.');333 console.log(`\nSummary:`);334 console.log(` - Enabled "${flagName}" in Environment.ts`);335 console.log(` - Updated ${updatedCount} fixture files with pragma`);336 console.log(` - All tests passing`);337338 process.exit(0);339 } catch (error) {340 console.error('\nFatal error:', error.message);341 console.error(error.stack);342 process.exit(1);343 }344}345346// Run the script347main();
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.