diff --git a/packages/react-native-codegen/buck_tests/generate-view-configs-cli.js b/packages/react-native-codegen/buck_tests/generate-view-configs-cli.js index 10e2a99c36..cb861a4ba0 100644 --- a/packages/react-native-codegen/buck_tests/generate-view-configs-cli.js +++ b/packages/react-native-codegen/buck_tests/generate-view-configs-cli.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @emails oncall+react_native * @flow * @format */ @@ -12,17 +11,26 @@ 'use strict'; const generate = require('./generate-view-configs'); +const yargs = require('yargs'); -const [fileList] = process.argv.slice(2); +const yargv = yargs.strict().option('t', { + alias: 'test', + describe: 'Test the changes and do not write files', + requiresArg: false, + type: 'boolean', +}); -const CURRENT_VIEW_CONFIG_SCHEMAS = ['SliderSchema.js']; +const argv = yargv.argv; +const fileList = argv._[0].split('\n'); + +const CURRENT_VIEW_CONFIG_SCHEMAS = ['']; generate( - fileList - .split('\n') - .filter(fileName => - CURRENT_VIEW_CONFIG_SCHEMAS.find(supportedFileName => - fileName.endsWith(supportedFileName), - ), + fileList.filter(fileName => + CURRENT_VIEW_CONFIG_SCHEMAS.find(supportedFileName => + fileName.endsWith(supportedFileName), ), + ), + // $FlowFixMe Type argv + argv.test, ); diff --git a/packages/react-native-codegen/buck_tests/generate-view-configs.js b/packages/react-native-codegen/buck_tests/generate-view-configs.js index fe67e0d38f..68171c5b13 100644 --- a/packages/react-native-codegen/buck_tests/generate-view-configs.js +++ b/packages/react-native-codegen/buck_tests/generate-view-configs.js @@ -15,20 +15,54 @@ const RNParser = require('../src/generators/RNParser.js'); const path = require('path'); -function generate(files: Array): void { - files.forEach(filename => { +type Result = $ReadOnly<{| + libraryName: string, + success: boolean, +|}>; + +function generateFilesWithResults( + files: Array, + test: boolean, +): Array { + return files.reduce((aggregated, filename) => { const schema = RNParser.parse(filename); if (schema && schema.modules) { - RNCodegen.generate( + const libraryName = path.basename(filename).replace('Schema.js', ''); + const success = RNCodegen.generate( { schema, + libraryName, outputDirectory: path.dirname(filename), - libraryName: path.basename(filename).replace('Schema.js', ''), }, - {generators: ['view-configs']}, + {generators: ['view-configs'], test}, ); + + aggregated.push({ + libraryName, + success, + }); } - }); + return aggregated; + }, []); +} + +function generate(files: Array, test: boolean): void { + console.log(`${test ? 'Testing' : 'Generating'} view configs`); + + const results = generateFilesWithResults(files, test); + + const failed = results.filter(result => !result.success); + const totalCount = results.length; + + console.log(`\n${test ? 'Tested' : 'Generated'} ${totalCount} view configs`); + + if (failed.length) { + if (test === true) { + console.error(`${failed.length} configs changed`); + console.error("Please re-run 'js1 build viewconfigs'"); + } + process.exit(1); + } } module.exports = generate; diff --git a/packages/react-native-codegen/src/generators/RNCodegen.js b/packages/react-native-codegen/src/generators/RNCodegen.js index cfa70c33b1..ac9383f4f2 100644 --- a/packages/react-native-codegen/src/generators/RNCodegen.js +++ b/packages/react-native-codegen/src/generators/RNCodegen.js @@ -47,6 +47,7 @@ type Generators = type Config = $ReadOnly<{| generators: Array, + test?: boolean, |}>; const GENERATORS = { @@ -61,18 +62,45 @@ const GENERATORS = { 'view-configs': [generateViewConfigJs.generate], }; -function writeMapToFiles(map: Map, outputDirectory: string) { +function writeMapToFiles(map: Map, outputDir: string) { + let success = true; map.forEach((contents: string, fileName: string) => { - const location = path.join(outputDirectory, fileName); - fs.writeFileSync(location, contents); + try { + const location = path.join(outputDir, fileName); + fs.writeFileSync(location, contents); + } catch (error) { + success = false; + console.error(`Failed to write ${fileName} to ${outputDir}`, error); + } }); + + return success; +} + +function checkFilesForChanges( + map: Map, + outputDir: string, +): boolean { + let hasChanged = false; + + map.forEach((contents: string, fileName: string) => { + const location = path.join(outputDir, fileName); + const currentContents = fs.readFileSync(location, 'utf8'); + if (currentContents !== contents) { + console.error(`- ${fileName} has changed`); + + hasChanged = true; + } + }); + + return !hasChanged; } module.exports = { generate( {libraryName, schema, outputDirectory}: Options, - {generators}: Config, - ) { + {generators, test}: Config, + ): boolean { schemaValidator.validate(schema); const generatedFiles = []; @@ -82,6 +110,12 @@ module.exports = { } } - writeMapToFiles(new Map([...generatedFiles]), outputDirectory); + const filesToUpdate = new Map([...generatedFiles]); + + if (test === true) { + return checkFilesForChanges(filesToUpdate, outputDirectory); + } + + return writeMapToFiles(filesToUpdate, outputDirectory); }, };