Skip to content

Commit

Permalink
Refactor generate-artifacts-executor.js: delete configFilename and co…
Browse files Browse the repository at this point in the history
…nfigKey arguments (#41533)

Summary:
Pull Request resolved: #41533

This diff removes `configFilename` and `configKey` arguments from iOS codegen CLI. Now we always expect them to be `package.json` and `codegenConfig` respectively.

## Motivation

The existing implementation expects every library to have its codegen config in a file with `configFilename` name. `configFilename` is passed as a single CLI argument and applied to every app dependency. I.e. if `configFilename = codegen.config.json` then we expect to find this file in *every* third-party library. That is weird expectation. This customisation option is unsound. Same with `configKey`. It is much simpler to just stick with convention that `configFilename = "package.json"` and `configKey = "codegenConfig"`.

Changelog: [General][Breaking] - Delete `configFilename` and `configKey` arguments from iOS codegen CLI. Now we always expect them to be `package.json` and `codegenConfig` respectively.

Reviewed By: cipolleschi

Differential Revision: D51256486

fbshipit-source-id: fe190b514be7c4e489c7be01294958cf3254602a
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Nov 21, 2023
1 parent d1e03f5 commit 33a44e6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const child_process = require('child_process');
const fs = require('fs');
const path = require('path');

const codegenConfigKey = 'codegenConfig';
const reactNativeDependencyName = 'react-native';
const rootPath = path.join(__dirname, '../../..');

Expand Down Expand Up @@ -85,15 +84,14 @@ describe('extractLibrariesFromJSON', () => {
it('throws if in react-native and no dependencies found', () => {
let configFile = {};
expect(() => {
underTest._extractLibrariesFromJSON(configFile, codegenConfigKey);
underTest._extractLibrariesFromJSON(configFile);
}).toThrow();
});

it('it skips if not into react-native and no dependencies found', () => {
let configFile = {};
let libraries = underTest._extractLibrariesFromJSON(
configFile,
codegenConfigKey,
'some-node-module',
'node_modules/some',
);
Expand All @@ -104,7 +102,6 @@ describe('extractLibrariesFromJSON', () => {
let configFile = fixtures.noLibrariesConfigFile;
let libraries = underTest._extractLibrariesFromJSON(
configFile,
codegenConfigKey,
'my-app',
'.',
);
Expand All @@ -123,7 +120,6 @@ describe('extractLibrariesFromJSON', () => {
const configFile = {codegenConfig: {libraries: []}};
let libraries = underTest._extractLibrariesFromJSON(
configFile,
codegenConfigKey,
reactNativeDependencyName,
rootPath,
);
Expand All @@ -134,7 +130,6 @@ describe('extractLibrariesFromJSON', () => {
const configFile = fixtures.singleLibraryCodegenConfig;
let libraries = underTest._extractLibrariesFromJSON(
configFile,
codegenConfigKey,
reactNativeDependencyName,
rootPath,
);
Expand All @@ -155,7 +150,6 @@ describe('extractLibrariesFromJSON', () => {
const myDependencyPath = path.join(__dirname, myDependency);
let libraries = underTest._extractLibrariesFromJSON(
configFile,
codegenConfigKey,
myDependency,
myDependencyPath,
);
Expand Down
152 changes: 43 additions & 109 deletions packages/react-native/scripts/codegen/generate-artifacts-executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
/**
* This script crawls through a React Native application's dependencies and invokes the codegen
* for any libraries that require it.
* To enable codegen support, the library should include a config in the codegenConfigKey key
* in a codegenConfigFilename file.
* To enable codegen support, the library should include a config in the codegenConfig key
* in a package.json file.
*/

const {execFileSync, execSync} = require('child_process');
Expand All @@ -37,7 +37,7 @@ const CORE_LIBRARIES_WITH_OUTPUT_FOLDER = {
rncore: path.join(REACT_NATIVE_PACKAGE_ROOT_FOLDER, 'ReactCommon'),
FBReactNativeSpec: null,
};
const REACT_NATIVE_DEPENDENCY_NAME = 'react-native';
const REACT_NATIVE = 'react-native';

// HELPERS

Expand All @@ -58,12 +58,16 @@ function isAppRootValid(appRootDir) {
return true;
}

function readPackageJSON(appRootDir) {
return JSON.parse(fs.readFileSync(path.join(appRootDir, 'package.json')));
function readPkgJsonInDirectory(dir) {
const pkgJsonPath = path.join(dir, 'package.json');
if (!fs.existsSync(pkgJsonPath)) {
throw `[Codegen] Error: ${pkgJsonPath} does not exist.`;
}
return JSON.parse(fs.readFileSync(pkgJsonPath));
}

function printDeprecationWarningIfNeeded(dependency) {
if (dependency === REACT_NATIVE_DEPENDENCY_NAME) {
if (dependency === REACT_NATIVE) {
return;
}
console.log(`[Codegen] CodegenConfig Deprecated Setup for ${dependency}.
Expand Down Expand Up @@ -101,44 +105,35 @@ function printDeprecationWarningIfNeeded(dependency) {
}

// Reading Libraries
function extractLibrariesFromConfigurationArray(
configFile,
codegenConfigKey,
dependencyPath,
) {
return configFile[codegenConfigKey].libraries.map(config => {
function extractLibrariesFromConfigurationArray(configFile, dependencyPath) {
return configFile.codegenConfig.libraries.map(config => {
return {
config,
libraryPath: dependencyPath,
};
});
}

function extractLibrariesFromJSON(
configFile,
codegenConfigKey,
dependency,
dependencyPath,
) {
function extractLibrariesFromJSON(configFile, dependency, dependencyPath) {
var isBlocking = false;
if (dependency == null) {
dependency = REACT_NATIVE_DEPENDENCY_NAME;
dependency = REACT_NATIVE;
dependencyPath = REACT_NATIVE_PACKAGE_ROOT_FOLDER;
// If we are exploring the ReactNative libraries, we want to raise an error
// if the codegen is not properly configured.
isBlocking = true;
}

if (configFile[codegenConfigKey] == null) {
if (configFile.codegenConfig == null) {
if (isBlocking) {
throw `[Codegen] Error: Could not find codegen config for ${dependency} .`;
}
return [];
}

console.log(`[Codegen] Found ${dependency}`);
if (configFile[codegenConfigKey].libraries == null) {
var config = configFile[codegenConfigKey];
if (configFile.codegenConfig.libraries == null) {
const config = configFile.codegenConfig;
return [
{
config,
Expand All @@ -147,38 +142,20 @@ function extractLibrariesFromJSON(
];
} else {
printDeprecationWarningIfNeeded(dependency);
return extractLibrariesFromConfigurationArray(
configFile,
codegenConfigKey,
dependencyPath,
);
return extractLibrariesFromConfigurationArray(configFile, dependencyPath);
}
}

function handleReactNativeCoreLibraries(
codegenConfigFilename,
codegenConfigKey,
) {
function handleReactNativeCoreLibraries() {
// Handle react-native core libraries.
// This is required when react-native is outside of node_modules.
console.log('[Codegen] Processing react-native core libraries');
const reactNativePkgJson = path.join(
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
codegenConfigFilename,
return extractLibrariesFromJSON(
readPkgJsonInDirectory(REACT_NATIVE_PACKAGE_ROOT_FOLDER),
);
if (!fs.existsSync(reactNativePkgJson)) {
throw '[Codegen] Error: Could not find config file for react-native.';
}
const reactNativeConfigFile = JSON.parse(fs.readFileSync(reactNativePkgJson));
return extractLibrariesFromJSON(reactNativeConfigFile, codegenConfigKey);
}

function handleThirdPartyLibraries(
baseCodegenConfigFileDir,
dependencies,
codegenConfigFilename,
codegenConfigKey,
) {
function handleThirdPartyLibraries(baseCodegenConfigFileDir, dependencies) {
// Determine which of these are codegen-enabled libraries
const configDir =
baseCodegenConfigFileDir ||
Expand All @@ -189,33 +166,25 @@ function handleThirdPartyLibraries(

// Handle third-party libraries
return Object.keys(dependencies).flatMap(dependency => {
if (dependency === REACT_NATIVE_DEPENDENCY_NAME) {
if (dependency === REACT_NATIVE) {
// react-native should already be added.
return [];
}
const codegenConfigFileDir = path.join(configDir, dependency);
const configFilePath = path.join(
codegenConfigFileDir,
codegenConfigFilename,
);
if (!fs.existsSync(configFilePath)) {
let configFile;
try {
configFile = readPkgJsonInDirectory(codegenConfigFileDir);
} catch {
return [];
}
const configFile = JSON.parse(fs.readFileSync(configFilePath));
return extractLibrariesFromJSON(
configFile,
codegenConfigKey,
dependency,
codegenConfigFileDir,
);
});
}

function handleLibrariesFromReactNativeConfig(
codegenConfigKey,
codegenConfigFilename,
appRootDir,
) {
function handleLibrariesFromReactNativeConfig(appRootDir) {
const rnConfigFileName = 'react-native.config.js';

console.log(
Expand All @@ -242,37 +211,27 @@ function handleLibrariesFromReactNativeConfig(
appRootDir,
dependencyConfig.root,
);
const configFilePath = path.join(
codegenConfigFileDir,
codegenConfigFilename,
);
if (!fs.existsSync(configFilePath)) {
let configFile;
try {
configFile = readPkgJsonInDirectory(codegenConfigFileDir);
} catch {
return [];
}
const pkgJsonPath = path.join(codegenConfigFileDir, 'package.json');
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath));
const configFile = JSON.parse(fs.readFileSync(configFilePath));

return extractLibrariesFromJSON(
configFile,
codegenConfigKey,
pkgJson.name,
configFile.name,
codegenConfigFileDir,
);
});
}

function handleInAppLibraries(pkgJson, codegenConfigKey, appRootDir) {
function handleInAppLibraries(pkgJson, appRootDir) {
console.log(
'\n\n[Codegen] >>>>> Searching for codegen-enabled libraries in the app',
);

return extractLibrariesFromJSON(
pkgJson,
codegenConfigKey,
pkgJson.name,
appRootDir,
);
return extractLibrariesFromJSON(pkgJson, pkgJson.name, appRootDir);
}

// CodeGen
Expand Down Expand Up @@ -417,28 +376,14 @@ function createComponentProvider(schemaPaths, node) {
console.log(`Generated provider in: ${outputDir}`);
}

function findCodegenEnabledLibraries(
appRootDir,
baseCodegenConfigFileDir,
codegenConfigFilename,
codegenConfigKey,
) {
const pkgJson = readPackageJSON(appRootDir);
function findCodegenEnabledLibraries(appRootDir, baseCodegenConfigFileDir) {
const pkgJson = readPkgJsonInDirectory(appRootDir);
const dependencies = {...pkgJson.dependencies, ...pkgJson.devDependencies};
return [
...handleReactNativeCoreLibraries(codegenConfigFilename, codegenConfigKey),
...handleThirdPartyLibraries(
baseCodegenConfigFileDir,
dependencies,
codegenConfigFilename,
codegenConfigKey,
),
...handleLibrariesFromReactNativeConfig(
codegenConfigKey,
codegenConfigFilename,
appRootDir,
),
...handleInAppLibraries(pkgJson, codegenConfigKey, appRootDir),
...handleReactNativeCoreLibraries(),
...handleThirdPartyLibraries(baseCodegenConfigFileDir, dependencies),
...handleLibrariesFromReactNativeConfig(appRootDir),
...handleInAppLibraries(pkgJson, appRootDir),
];
}

Expand Down Expand Up @@ -484,24 +429,15 @@ function cleanupEmptyFilesAndFolders(filepath) {
* - setups the CLI to generate the code
* - generate the code
*
* @parameter appRootDir: the directory with the app source code, where the `codegenConfigFilename` lives.
* @parameter appRootDir: the directory with the app source code, where the package.json lives.
* @parameter outputPath: the base output path for the CodeGen.
* @parameter node: the path to the node executable, used to run the codegen scripts.
* @parameter codegenConfigFilename: the file that contains the codeGen configuration. The default is `package.json`.
* @parameter codegenConfigKey: the key in the codegenConfigFile that controls the codegen.
* @parameter baseCodegenConfigFileDir: the directory of the codeGenConfigFile.
* @throws If it can't find a config file for react-native.
* @throws If it can't find a CodeGen configuration in the file.
* @throws If it can't find a cli for the CodeGen.
*/
function execute(
appRootDir,
outputPath,
node,
codegenConfigFilename,
codegenConfigKey,
baseCodegenConfigFileDir,
) {
function execute(appRootDir, outputPath, node, baseCodegenConfigFileDir) {
if (!isAppRootValid(appRootDir)) {
return;
}
Expand All @@ -510,8 +446,6 @@ function execute(
const libraries = findCodegenEnabledLibraries(
appRootDir,
baseCodegenConfigFileDir,
codegenConfigFilename,
codegenConfigKey,
);

if (libraries.length === 0) {
Expand Down
29 changes: 4 additions & 25 deletions packages/react-native/scripts/generate-codegen-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@ const argv = yargs
alias: 'outputPath',
description: 'Path where generated artifacts will be output to',
})
.option('f', {
alias: 'configFilename',
default: 'package.json',
description: 'The file that contains the codegen configuration.',
})
.option('k', {
alias: 'configKey',
default: 'codegenConfig',
description:
'The key that contains the codegen configuration in the config file.',
})
.option('c', {
alias: 'configFileDir',
default: '',
Expand All @@ -46,19 +35,9 @@ const argv = yargs
.usage('Usage: $0 -p [path to app]')
.demandOption(['p']).argv;

const CODEGEN_CONFIG_FILENAME = argv.f;
const CODEGEN_CONFIG_FILE_DIR = argv.c;
const CODEGEN_CONFIG_KEY = argv.k;
const NODE = argv.n;

const appRoot = argv.path;
const outputPath = argv.outputPath;

executor.execute(
appRoot,
outputPath,
NODE,
CODEGEN_CONFIG_FILENAME,
CODEGEN_CONFIG_KEY,
CODEGEN_CONFIG_FILE_DIR,
argv.path,
argv.outputPath,
argv.nodeBinary,
argv.configFileDir,
);

0 comments on commit 33a44e6

Please sign in to comment.