Skip to content

Commit

Permalink
Introduce "codegenConfig.includesGeneratedCode" property (facebook#41655
Browse files Browse the repository at this point in the history
)

Summary:
Pull Request resolved: facebook#41655

This diff adds support for checked-in codegen artifacts for libraries.
It introduces a new property to `codegenConfig`, called `includesGeneratedCode`. If codegen sees `includesGeneratedCode: true` in a project's dependency, it assumes that the library has codegen artifacts in it, and will not generate any code.

Changelog: [General][Added] - Introduce "codegenConfig.includesGeneratedCode" property.

Differential Revision: D51207265

Reviewed By: cipolleschi

fbshipit-source-id: 5f6822714005c7eb5ee8019f3691d8d79f9d2b66
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Dec 18, 2023
1 parent 63de214 commit 39988a6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,15 @@ class ReactPlugin : Plugin<Project> {
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }

val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
val includesGeneratedCode = parsedPackageJson?.codegenConfig?.includesGeneratedCode
if (jsSrcsDirInPackageJson != null) {
it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
} else {
it.jsRootDir.set(localExtension.jsRootDir)
}
val needsCodegenFromPackageJson =
project.needsCodegenFromPackageJson(rootExtension.root)
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
}

// We create the task to generate Java code from schema.
Expand All @@ -188,7 +189,10 @@ class ReactPlugin : Plugin<Project> {
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
val needsCodegenFromPackageJson =
project.needsCodegenFromPackageJson(rootExtension.root)
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
val packageJson = findPackageJsonFile(project, rootExtension.root)
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
val includesGeneratedCode = parsedPackageJson?.codegenConfig?.includesGeneratedCode
it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
}

// We update the android configuration to include the generated sources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const REACT_NATIVE = 'react-native';

// HELPERS

function includesGeneratedCode(pkgJson) {
return pkgJson.codegenConfig && pkgJson.codegenConfig.includesGeneratedCode;
}

function isReactNativeCoreLibrary(libraryName) {
return libraryName in CORE_LIBRARIES_WITH_OUTPUT_FOLDER;
}
Expand Down Expand Up @@ -195,7 +199,12 @@ function computeOutputPath(projectRoot, baseOutputPath, pkgJson) {
baseOutputPath = projectRoot;
}
}
return path.join(baseOutputPath, 'build', 'generated', 'ios');
if (includesGeneratedCode(pkgJson)) {
// Don't create nested directories for libraries to make importing generated headers easier.
return baseOutputPath;
} else {
return path.join(baseOutputPath, 'build', 'generated', 'ios');
}
}

function generateSchemaInfo(library) {
Expand Down Expand Up @@ -260,6 +269,16 @@ function needsThirdPartyComponentProvider(schemaInfo) {
return !isReactNativeCoreLibrary(schemaInfo.library.config.name);
}

function mustGenerateNativeCode(includeLibraryPath, schemaInfo) {
// If library's 'codegenConfig' sets 'includesGeneratedCode' to 'true',
// then we assume that native code is shipped with the library,
// and we don't need to generate it.
return (
schemaInfo.library.libraryPath === includeLibraryPath ||
!schemaInfo.library.config.includesGeneratedCode
);
}

function createComponentProvider(schemas) {
console.log('\n\n>>>>> Creating component provider');
const outputDir = path.join(
Expand All @@ -281,10 +300,12 @@ function createComponentProvider(schemas) {
}

function findCodegenEnabledLibraries(pkgJson, projectRoot) {
return [
...findExternalLibraries(pkgJson),
...findProjectRootLibraries(pkgJson, projectRoot),
];
const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
if (includesGeneratedCode(pkgJson)) {
return projectLibraries;
} else {
return [...projectLibraries, ...findExternalLibraries(pkgJson)];
}
}

// It removes all the empty files and empty folders
Expand Down Expand Up @@ -355,12 +376,19 @@ function execute(projectRoot, baseOutputPath) {
const outputPath = computeOutputPath(projectRoot, baseOutputPath, pkgJson);

const schemaInfos = generateSchemaInfos(libraries);
generateNativeCode(outputPath, schemaInfos);
generateNativeCode(
outputPath,
schemaInfos.filter(schemaInfo =>
mustGenerateNativeCode(projectRoot, schemaInfo),
),
);

const schemas = schemaInfos
.filter(needsThirdPartyComponentProvider)
.map(schemaInfo => schemaInfo.schema);
createComponentProvider(schemas);
if (!includesGeneratedCode(pkgJson)) {
const schemas = schemaInfos
.filter(needsThirdPartyComponentProvider)
.map(schemaInfo => schemaInfo.schema);
createComponentProvider(schemas);
}
cleanupEmptyFilesAndFolders(outputPath);
} catch (err) {
console.error(err);
Expand Down

0 comments on commit 39988a6

Please sign in to comment.