Remove flags to turn on/off the new architecture (#39780)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39780

This diff removes flags and setups from the files to turn on and off the new architecture. The script is meant to run only on pre-alpha builds.

## Changelog:
[Internal] - Add script to remove prealpha flags

Reviewed By: cortinico

Differential Revision: D49376471

fbshipit-source-id: 754bf6f9d5b94da77111798200bbaaa3347fb678
This commit is contained in:
Riccardo Cipolleschi 2023-10-05 07:40:50 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 48dcfa1718
Коммит 46d541f7b3
3 изменённых файлов: 335 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,92 @@
/**
* 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
* @oncall react-native
*/
const validReactNativePodsFile = `
def use_react_native! (
path: "../node_modules/react-native",
fabric_enabled: false,
new_arch_enabled: NewArchitectureHelper.new_arch_enabled,
production: false, # deprecated
hermes_enabled: ENV['USE_HERMES'] && ENV['USE_HERMES'] == '0' ? false : true,
flipper_configuration: FlipperConfiguration.disabled,
app_path: '..',
config_file_dir: '',
ios_folder: 'ios'
)
end
`;
const invalidReactNativePodsFile = `
def use_react_native! (
path: "../node_modules/react-native",
fabric_enabled: false,
production: false, # deprecated
hermes_enabled: ENV['USE_HERMES'] && ENV['USE_HERMES'] == '0' ? false : true,
flipper_configuration: FlipperConfiguration.disabled,
app_path: '..',
config_file_dir: '',
ios_folder: 'ios'
)
end
`;
const expectedReactNativePodsFile = `
def use_react_native! (
path: "../node_modules/react-native",
production: false, # deprecated
hermes_enabled: ENV['USE_HERMES'] && ENV['USE_HERMES'] == '0' ? false : true,
flipper_configuration: FlipperConfiguration.disabled,
app_path: '..',
config_file_dir: '',
ios_folder: 'ios'
)
end
`;
const validGradlePropertiesFile = `
# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
`;
const invalidGradlePropertiesFile = `
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
`;
const expectedGradlePropertiesFile = `
# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=true
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
`;
module.exports = {
validReactNativePodsFile,
invalidReactNativePodsFile,
expectedReactNativePodsFile,
validGradlePropertiesFile,
invalidGradlePropertiesFile,
expectedGradlePropertiesFile,
};

Просмотреть файл

@ -0,0 +1,135 @@
/**
* 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
* @oncall react-native
*/
const fs = require('fs');
const path = require('path');
const removeNewArchFlags = require('../remove-new-arch-flags');
const {
validReactNativePodsFile,
invalidReactNativePodsFile,
expectedReactNativePodsFile,
validGradlePropertiesFile,
invalidGradlePropertiesFile,
expectedGradlePropertiesFile,
} = require('./__fixtures__/remove-new-arch-flags-fixture');
describe('removeNewArchFlags', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('throws an exception if not run from react-native-github', async () => {
jest.spyOn(process, 'cwd').mockReturnValue('/path/to/react-native');
expect(removeNewArchFlags).toThrow();
});
it('it updates the required files', async () => {
const cwd = '/path/to/react-native-github';
const reactNativePodsPath =
'/packages/react-native/scripts/react_native_pods.rb';
const templateGradlePropertiesPath =
'/packages/react-native/template/android/gradle.properties';
jest.spyOn(process, 'cwd').mockReturnValue(cwd);
jest.spyOn(fs, 'readFileSync').mockImplementation(filename => {
if (filename === path.join(cwd, reactNativePodsPath)) {
return validReactNativePodsFile;
} else if (filename === path.join(cwd, templateGradlePropertiesPath)) {
return validGradlePropertiesFile;
} else {
throw new Error(`Unexpected call to fs.readFileSync(${filename}).`);
}
});
let returnedReactNativePodsBackup = '';
let returnedReactNativePods = '';
let returnedGradlePropertiesBackup = '';
let returnedGradleProperties = '';
jest.spyOn(fs, 'writeFileSync').mockImplementation((filename, content) => {
if (filename === path.join(cwd, `${reactNativePodsPath}.bak`)) {
returnedReactNativePodsBackup = content;
} else if (filename === path.join(cwd, reactNativePodsPath)) {
returnedReactNativePods = content;
} else if (
filename === path.join(cwd, `${templateGradlePropertiesPath}.bak`)
) {
returnedGradlePropertiesBackup = content;
} else if (filename === path.join(cwd, templateGradlePropertiesPath)) {
returnedGradleProperties = content;
} else {
throw new Error(`Unexpected call to fs.writeFileSync(${filename}).`);
}
});
let deletedFiles = [];
jest.spyOn(fs, 'unlinkSync').mockImplementation(filename => {
deletedFiles.push(filename);
});
removeNewArchFlags();
expect(returnedReactNativePodsBackup).toEqual(validReactNativePodsFile);
expect(returnedReactNativePods).toEqual(expectedReactNativePodsFile);
expect(returnedGradlePropertiesBackup).toEqual(validGradlePropertiesFile);
expect(returnedGradleProperties).toEqual(expectedGradlePropertiesFile);
expect(deletedFiles).toEqual([
path.join(cwd, `${reactNativePodsPath}.bak`),
path.join(cwd, `${templateGradlePropertiesPath}.bak`),
]);
});
it('does not update the required files if they are not valid', async () => {
const cwd = '/path/to/react-native-github';
const reactNativePodsPath =
'/packages/react-native/scripts/react_native_pods.rb';
const templateGradlePropertiesPath =
'/packages/react-native/template/android/gradle.properties';
jest.spyOn(process, 'cwd').mockReturnValue(cwd);
jest.spyOn(fs, 'readFileSync').mockImplementation(filename => {
if (filename === path.join(cwd, reactNativePodsPath)) {
return invalidReactNativePodsFile;
} else if (filename === path.join(cwd, templateGradlePropertiesPath)) {
return invalidGradlePropertiesFile;
} else {
throw new Error(`Unexpected call to fs.readFileSync(${filename}).`);
}
});
let returnedReactNativePodsBackup = '';
let returnedReactNativePods = '';
let returnedGradlePropertiesBackup = '';
let returnedGradleProperties = '';
jest.spyOn(fs, 'writeFileSync').mockImplementation((filename, content) => {
if (filename === path.join(cwd, `${reactNativePodsPath}.bak`)) {
returnedReactNativePodsBackup = content;
} else if (filename === path.join(cwd, reactNativePodsPath)) {
returnedReactNativePods = content;
} else if (
filename === path.join(cwd, `${templateGradlePropertiesPath}.bak`)
) {
returnedGradlePropertiesBackup = content;
} else if (filename === path.join(cwd, templateGradlePropertiesPath)) {
returnedGradleProperties = content;
} else {
throw new Error(`Unexpected call to fs.writeFileSync(${filename}).`);
}
});
let deletedFiles = [];
jest.spyOn(fs, 'unlinkSync').mockImplementation(filename => {
deletedFiles.push(filename);
});
removeNewArchFlags();
expect(returnedReactNativePodsBackup).toEqual(invalidReactNativePodsFile);
expect(returnedReactNativePods).toEqual(invalidReactNativePodsFile);
expect(returnedGradlePropertiesBackup).toEqual(invalidGradlePropertiesFile);
expect(returnedGradleProperties).toEqual(invalidGradlePropertiesFile);
expect(deletedFiles).toEqual([
path.join(cwd, `${reactNativePodsPath}.bak`),
path.join(cwd, `${templateGradlePropertiesPath}.bak`),
]);
});
});

Просмотреть файл

@ -0,0 +1,108 @@
/**
* 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.
*
* @flow
* @format
* @oncall react-native
*/
'use strict';
const fs = require('fs');
const path = require('path');
function removeNewArchFlags() {
console.log('Removing new arch flags');
const cwd = getValidCwd();
const iosBackups = removeFlagsForiOS(cwd);
const androidBackups = flipNewArchFlagForAndroid(cwd);
iosBackups.concat(androidBackups).forEach(file => {
fs.unlinkSync(file);
});
}
// === Helpers ===
function getValidCwd() /*: string*/ {
const cwd = process.cwd();
if (!cwd.endsWith('react-native-github')) {
throw new Error(
`Please call this script from react-native root folder. Current path: ${cwd}`,
);
}
return cwd;
}
function replaceContentsOfFile(
contentToBeReplaced /*: string | RegExp*/,
replacement /*: string*/,
filepath /*: string*/,
) /*: string*/ {
const content = fs.readFileSync(filepath, 'utf8');
const backupPath = `${filepath}.bak`;
fs.writeFileSync(backupPath, content, 'utf8');
let newContent = content.replaceAll(contentToBeReplaced, replacement);
fs.writeFileSync(filepath, newContent, 'utf8');
return backupPath;
}
function removeContentsFromFile(
contentToBeRemoved /*: string | RegExp*/,
filepath /*: string*/,
) /*: string*/ {
return replaceContentsOfFile(contentToBeRemoved, '', filepath);
}
function removeFlagsForiOS(cwd /*: string*/) /*: $ReadOnlyArray<string>*/ {
let backupPath /*: Array<string>*/ = [];
const iosPath = path.join(
cwd,
'/packages/react-native/scripts/react_native_pods.rb',
);
backupPath.push(
removeContentsFromFile(
/ {2}fabric_enabled: false,\n {2}new_arch_enabled: NewArchitectureHelper.new_arch_enabled,\n/g,
iosPath,
),
);
return backupPath;
}
function newArchEnabledGradleProps(boolValue /*: boolean*/) /*: string */ {
return `newArchEnabled=${boolValue.toString()}`;
}
function flipNewArchFlagForAndroid(
cwd /*: string */,
) /*: $ReadOnlyArray<string>*/ {
let backupPath /*: Array<string> */ = [];
// Gradle.properties
const gradlePropertiesPath = path.join(
cwd,
'/packages/react-native/template/android/gradle.properties',
);
backupPath.push(
replaceContentsOfFile(
new RegExp(newArchEnabledGradleProps(false), 'g'),
newArchEnabledGradleProps(true),
gradlePropertiesPath,
),
);
return backupPath;
}
// ===============
module.exports = removeNewArchFlags;
if (require.main === module) {
removeNewArchFlags();
}