diff --git a/change/@react-native-windows-codegen-1674ebdb-ad8f-432b-bcbc-15b049d1fcc0.json b/change/@react-native-windows-codegen-1674ebdb-ad8f-432b-bcbc-15b049d1fcc0.json new file mode 100644 index 00000000000..29670771ab9 --- /dev/null +++ b/change/@react-native-windows-codegen-1674ebdb-ad8f-432b-bcbc-15b049d1fcc0.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "codegen-windows --check always fails", + "packageName": "@react-native-windows/codegen", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/react-native-windows-bd661950-16e7-4ff2-bb7a-6927dddb2a28.json b/change/react-native-windows-bd661950-16e7-4ff2-bb7a-6927dddb2a28.json new file mode 100644 index 00000000000..acb7639a204 --- /dev/null +++ b/change/react-native-windows-bd661950-16e7-4ff2-bb7a-6927dddb2a28.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Update generated code", + "packageName": "react-native-windows", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/@react-native-windows/codegen/src/Cli.ts b/packages/@react-native-windows/codegen/src/Cli.ts index 377c8e61371..e3d4cc7453f 100644 --- a/packages/@react-native-windows/codegen/src/Cli.ts +++ b/packages/@react-native-windows/codegen/src/Cli.ts @@ -65,4 +65,11 @@ if ((argv.file && argv.files) || (!argv.file && !argv.files)) { process.exit(1); } -runCodeGen(argv); +const changesNecessary = runCodeGen(argv); + +if (argv.test && changesNecessary) { + console.error( + 'There is a change in the output of codegen. Rerun "react-native codegen-windows" to regenerate.', + ); + process.exit(2); +} diff --git a/packages/@react-native-windows/codegen/src/index.ts b/packages/@react-native-windows/codegen/src/index.ts index 479e56c893f..bb591169aee 100644 --- a/packages/@react-native-windows/codegen/src/index.ts +++ b/packages/@react-native-windows/codegen/src/index.ts @@ -65,15 +65,20 @@ function checkFilesForChanges( ): boolean { let hasChanges = false; + outputDir = path.resolve(outputDir); + const globbyDir = outputDir.replace(/\\/g, '/'); const allExistingFiles = globby - .sync(`${outputDir}/**`) - .map(_ => path.normalize(_)) - .sort(); + .sync([`${globbyDir}/**`, `${globbyDir}/**/.*`], {absolute: true}) + .map(_ => path.normalize(_)); const allGeneratedFiles = [...map.keys()].map(_ => path.normalize(_)).sort(); if ( allExistingFiles.length !== allGeneratedFiles.length || - !allExistingFiles.every((val, index) => val === allGeneratedFiles[index]) + !allGeneratedFiles.every(filepath => + allExistingFiles.includes( + path.normalize(path.resolve(process.cwd(), filepath)), + ), + ) ) return true; @@ -97,10 +102,19 @@ function checkFilesForChanges( function writeMapToFiles(map: Map, outputDir: string) { let success = true; + outputDir = path.resolve(outputDir); + const globbyDir = outputDir.replace(/\\/g, '/'); + // This ensures that we delete any generated files from modules that have been deleted - const allExistingFiles = globby.sync(`${outputDir}/**`); + const allExistingFiles = globby.sync( + [`${globbyDir}/**`, `${globbyDir}/**/.*`], + {absolute: true}, + ); + + const allGeneratedFiles = [...map.keys()].map(_ => path.normalize(_)).sort(); allExistingFiles.forEach(existingFile => { - if (!map.has(path.normalize(existingFile))) { + if (!allGeneratedFiles.includes(path.normalize(existingFile))) { + console.log('Deleting ', existingFile); fs.unlinkSync(existingFile); } }); @@ -117,6 +131,7 @@ function writeMapToFiles(map: Map, outputDir: string) { } } + console.log('Writing ', fileName); fs.writeFileSync(fileName, contents); } catch (error) { success = false; diff --git a/packages/sample-apps/just-task.js b/packages/sample-apps/just-task.js index 38d106559f1..e1c1c7e8715 100644 --- a/packages/sample-apps/just-task.js +++ b/packages/sample-apps/just-task.js @@ -5,7 +5,7 @@ * @ts-check */ -const {task, series} = require('just-scripts'); +const {task, series, parallel} = require('just-scripts'); const fs = require('fs'); const {execSync} = require('child_process'); @@ -16,6 +16,12 @@ task('codegen', () => { execSync('npx react-native codegen-windows --logging', {env: process.env}); }); +task('codegen:check', () => { + execSync('npx react-native codegen-windows --logging --check', { + env: process.env, + }); +}); + task('prepareBundle', () => { fs.mkdirSync('windows/SampleAppCS/Bundle', {recursive: true}); fs.mkdirSync('windows/SampleAppCPP/Bundle', {recursive: true}); diff --git a/vnext/just-task.js b/vnext/just-task.js index 4ed56d4e1f7..a5d456e315b 100644 --- a/vnext/just-task.js +++ b/vnext/just-task.js @@ -25,16 +25,23 @@ const fs = require('fs'); option('production'); option('clean'); -task('codegen', () => { +function codegen(test) { execSync( - 'react-native-windows-codegen --files Libraries/**/*Native*.js --namespace Microsoft::ReactNativeSpecs --libraryName rnwcore --modulesWindows --modulesCxx', + `react-native-windows-codegen --files Libraries/**/*Native*.js --namespace Microsoft::ReactNativeSpecs --libraryName rnwcore --modulesWindows --modulesCxx${ + test ? ' --test' : '' + }`, {env: process.env}, ); execSync( - 'react-native-windows-codegen --files Microsoft.ReactNative.IntegrationTests/**/*Native*.js --namespace Microsoft::ReactNativeIntegrationTestSpecs --libraryName msrnIntegrationTests --modulesCxx --outputDirectory Microsoft.ReactNative.IntegrationTests/codegen', + `react-native-windows-codegen --files Microsoft.ReactNative.IntegrationTests/**/*Native*.js --namespace Microsoft::ReactNativeIntegrationTestSpecs --libraryName msrnIntegrationTests --modulesCxx --outputDirectory Microsoft.ReactNative.IntegrationTests/codegen${ + test ? ' --test' : '' + }`, {env: process.env}, ); -}); +} + +task('codegen', () => codegen(false)); +task('codegen:check', () => codegen(true)); task('copyReadmeAndLicenseFromRoot', () => { fs.copyFileSync( @@ -62,4 +69,4 @@ task( task('clean', series('cleanRNLibraries')); -task('lint', series('eslint', 'flow-check')); +task('lint', series('eslint', 'codegen:check', 'flow-check'));