Files
react-native/packages/react-native/scripts/featureflags/generateFiles.js
T
Rubén NorteandFacebook GitHub Bot 705c675d51 Implement new feature flag system (#42430)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42430

This PR creates a new internal feature flags system for React Native. This is only meant to be used internally within the framework, but we might expose it externally in some form in the future to allow customizing specific feature flags in frameworks and applications.

Features:
* 2 types of flags:
  * Common: can be overridden from native and are accessible from all layers of the stack (Objective-C/Swift, Java/Kotlin, C++ and JavaScript).
  * JS-only: flags that can only be defined and accessed from JS (to allow things like hot reloading without a native build).
* 1 source of truth for each flag.
* Feature flags are application/process scoped (using C++ singletons).

See the `README.md` file in this PR for additional information.

This also adds modifies `run-ci-javascript-tests` to run a new check to make sure that the generate files are in sync with the JSON file that contains the definitions.

Changelog: [internal]

Reviewed By: huntie

Differential Revision: D52806730

fbshipit-source-id: 0ba95803f61ec2f05266ee535921321bf6d3dc6a
2024-01-25 13:55:11 -08:00

83 lines
2.5 KiB
JavaScript

/**
* 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.
*
* @format
*/
const generateAndroidModules = require('./generateAndroidModules');
const generateCommonCxxModules = require('./generateCommonCxxModules');
const generateJavaScriptModules = require('./generateJavaScriptModules');
const fs = require('fs');
module.exports = function generateFiles(generatorConfig, generatorOptions) {
const userDefinedFeatureFlagsConfig = JSON.parse(
fs.readFileSync(generatorConfig.configPath, 'utf8'),
);
const featureFlagsConfig = Object.assign(
{jsOnly: {}, common: {}},
userDefinedFeatureFlagsConfig,
);
fs.mkdirSync(generatorConfig.jsPath, {recursive: true});
fs.mkdirSync(generatorConfig.commonCxxPath, {recursive: true});
fs.mkdirSync(generatorConfig.commonNativeModuleCxxPath, {recursive: true});
fs.mkdirSync(generatorConfig.androidPath, {recursive: true});
fs.mkdirSync(generatorConfig.androidJniPath, {recursive: true});
const jsModules = generateJavaScriptModules(
generatorConfig,
featureFlagsConfig,
);
const commonCxxModules = generateCommonCxxModules(
generatorConfig,
featureFlagsConfig,
);
const androidModules = generateAndroidModules(
generatorConfig,
featureFlagsConfig,
);
const generatedFiles = {...jsModules, ...commonCxxModules, ...androidModules};
if (generatorOptions.verifyUnchanged) {
const existingModules = {};
for (const moduleName of Object.keys(generatedFiles)) {
const existingModule = fs.readFileSync(moduleName, 'utf8');
existingModules[moduleName] = existingModule;
}
const changedFiles = [];
for (const moduleName of Object.keys(generatedFiles)) {
const module = generatedFiles[moduleName];
const existingModule = existingModules[moduleName];
if (module !== existingModule) {
changedFiles.push(moduleName);
}
}
if (changedFiles.length > 0) {
const changedFilesStr = changedFiles
.map(changedFile => ' ' + changedFile)
.join('\n');
throw new Error(
`Detected changes in generated files for feature flags:\n${changedFilesStr}\n\n` +
'Please rerun `yarn featureflags-update` and commit the changes.',
);
}
return;
}
for (const [modulePath, moduleContents] of Object.entries(generatedFiles)) {
fs.writeFileSync(modulePath, moduleContents, 'utf8');
}
};