react-native
Version:
A framework for building native apps using React
104 lines (93 loc) • 3.54 kB
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.
*
* @flow strict-local
* @format
*/
;
const {
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
TEMPLATES_FOLDER_PATH,
packageJson,
} = require('./constants');
const {codegenLog} = require('./utils');
const {execSync} = require('child_process');
const fs = require('fs');
const path = require('path');
const REACT_CODEGEN_PODSPEC_TEMPLATE_PATH = path.join(
TEMPLATES_FOLDER_PATH,
'ReactCodegen.podspec.template',
);
function generateReactCodegenPodspec(
appPath /*: string */,
appPkgJson /*: $FlowFixMe */,
outputPath /*: string */,
baseOutputPath /*: string */,
) {
const inputFiles = getInputFiles(appPath, appPkgJson);
const codegenScript = codegenScripts(appPath, baseOutputPath);
const template = fs.readFileSync(REACT_CODEGEN_PODSPEC_TEMPLATE_PATH, 'utf8');
const finalPodspec = template
.replace(/{react-native-version}/, packageJson.version)
.replace(/{input-files}/, inputFiles)
.replace(/{codegen-script}/, codegenScript);
const finalPathPodspec = path.join(outputPath, 'ReactCodegen.podspec');
fs.writeFileSync(finalPathPodspec, finalPodspec);
codegenLog(`Generated podspec: ${finalPathPodspec}`);
}
function getInputFiles(appPath /*: string */, appPkgJson /*: $FlowFixMe */) {
const jsSrcsDir = appPkgJson.codegenConfig?.jsSrcsDir;
if (!jsSrcsDir) {
return '[]';
}
const xcodeproj = String(
execSync(`find ${appPath} -type d -name "*.xcodeproj"`),
)
.trim()
.split('\n')
.filter(
projectPath =>
!projectPath.includes('/Pods/') && // exclude Pods/Pods.xcodeproj
!projectPath.includes('/node_modules/'), // exclude all the xcodeproj in node_modules of libraries
)[0];
if (!xcodeproj) {
throw new Error(
`Cannot find .xcodeproj file inside ${appPath}. This is required to determine codegen spec paths relative to native project.`,
);
}
const jsFiles = '-name "Native*.js" -or -name "*NativeComponent.js"';
const tsFiles = '-name "Native*.ts" -or -name "*NativeComponent.ts"';
const findCommand = `find ${path.join(appPath, jsSrcsDir)} -type f -not -path "*/__mocks__/*" -and \\( ${jsFiles} -or ${tsFiles} \\)`;
const list = String(execSync(findCommand))
.trim()
.split('\n')
.sort()
.map(filepath => `"\${PODS_ROOT}/${path.relative(xcodeproj, filepath)}"`)
.join(',\n');
return `[${list}]`;
}
function codegenScripts(appPath /*: string */, baseOutputPath /*: string */) {
const relativeAppPath = path.relative(baseOutputPath, appPath);
const relativeReactNativeRootFolder = path.relative(
baseOutputPath,
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
);
return `<<-SCRIPT
pushd "$PODS_ROOT/../" > /dev/null
RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd)
popd >/dev/null
export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeReactNativeRootFolder}"
export RCT_SCRIPT_APP_PATH="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeAppPath.length === 0 ? '.' : relativeAppPath}"
export RCT_SCRIPT_OUTPUT_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT"
export RCT_SCRIPT_TYPE="withCodegenDiscovery"
export SCRIPT_PHASES_SCRIPT="$RCT_SCRIPT_RN_DIR/scripts/react_native_pods_utils/script_phases.sh"
export WITH_ENVIRONMENT="$RCT_SCRIPT_RN_DIR/scripts/xcode/with-environment.sh"
/bin/sh -c '"$WITH_ENVIRONMENT" "$SCRIPT_PHASES_SCRIPT"'
SCRIPT`;
}
module.exports = {
generateReactCodegenPodspec,
};