Skip to content

Commit

Permalink
Add a phase to build third party component provider
Browse files Browse the repository at this point in the history
Summary:
Adds a phase to generate-artifacts.js to generate the third party components provider for fabric. The output path needs to align with where the rest of generated files go (the work is wip).

Changelog:[internal]

Reviewed By: hramos

Differential Revision: D32128834

fbshipit-source-id: 8721b8a19bcf01bb388a293ce17162b4e578a72a
  • Loading branch information
sota000 authored and facebook-github-bot committed Nov 11, 2021
1 parent 037e346 commit 4ff16c6
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
39 changes: 39 additions & 0 deletions scripts/generate-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ const CODEGEN_CONFIG_FILENAME = argv.f;
const CODEGEN_CONFIG_KEY = argv.k;
const CODEGEN_REPO_PATH = `${RN_ROOT}/packages/react-native-codegen`;
const CODEGEN_NPM_PATH = `${RN_ROOT}/../react-native-codegen`;
const CORE_LIBRARIES = new Set(['rncore', 'FBReactNativeSpec']);

function isReactNativeCoreLibrary(libraryName) {
return CORE_LIBRARIES.has(libraryName);
}

function main(appRootDir, outputPath) {
if (appRootDir == null) {
Expand Down Expand Up @@ -148,6 +153,8 @@ function main(appRootDir, outputPath) {
throw "error: Could not determine react-native-codegen location. Try running 'yarn install' or 'npm install' in your project root.";
}

const schemaPaths = {};

// 5. For each codegen-enabled library, generate the native code spec files
libraries.forEach(library => {
const tmpDir = fs.mkdtempSync(
Expand Down Expand Up @@ -198,7 +205,39 @@ function main(appRootDir, outputPath) {
fs.mkdirSync(pathToOutputDirIOS, {recursive: true});
execSync(`cp -R ${pathToTempOutputDir}/* ${pathToOutputDirIOS}`);
console.log(`[Codegen] Generated artifacts: ${pathToOutputDirIOS}`);

// Filter the react native core library out.
// In the future, core library and third party library should
// use the same way to generate/register the fabric components.
if (!isReactNativeCoreLibrary(library.config.name)) {
schemaPaths[library.config.name] = pathToSchema;
}
});

console.log('\n\n>>>>> Creating component provider');
// Save the list of spec paths to a temp file.
const schemaListTmpPath = `${os.tmpdir()}/rn-tmp-schema-list.json`;
const fd = fs.openSync(schemaListTmpPath, 'w');
fs.writeSync(fd, JSON.stringify(schemaPaths));
fs.closeSync(fd);
console.log(`Generated schema list: ${schemaListTmpPath}`);

// Generate FabricComponentProvider.
// Only for iOS at this moment.
const providerOutputPathIOS = path.join(
appRootDir,
'build',
'generated',
'ios',
);
execSync(
`node ${path.join(
RN_ROOT,
'scripts',
'generate-provider-cli.js',
)} --platform ios --schemaListPath "${schemaListTmpPath}" --outputDir ${providerOutputPathIOS}`,
);
console.log(`Generated provider in: ${providerOutputPathIOS}`);
} catch (err) {
console.error(err);
process.exitCode = 1;
Expand Down
99 changes: 99 additions & 0 deletions scripts/generate-provider-cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

'use strict';

let RNCodegen;
try {
RNCodegen = require('../packages/react-native-codegen/lib/generators/RNCodegen.js');
} catch (e) {
RNCodegen = require('react-native-codegen/lib/generators/RNCodegen.js');
if (!RNCodegen) {
throw 'RNCodegen not found.';
}
}

const fs = require('fs');
const mkdirp = require('mkdirp');
const yargs = require('yargs');

const argv = yargs
.option('p', {
alias: 'platform',
describe: 'Platform to generate native code artifacts for.',
})
.option('s', {
alias: 'schemaListPath',
describe: 'The path to the schema list file.',
})
.option('o', {
alias: 'outputDir',
describe:
'Path to directory where native code source files should be saved.',
})
.usage('Usage: $0 <args>')
.demandOption(
['platform', 'schemaListPath', 'outputDir'],
'Please provide platform, schema path, and output directory.',
).argv;

const GENERATORS = {
android: [],
ios: ['providerIOS'],
};

function generateProvider(platform, schemaListPath, outputDirectory) {
const schemaListText = fs.readFileSync(schemaListPath, 'utf-8');

if (schemaListText == null) {
throw new Error(`Can't find schema list file at ${schemaListPath}`);
}

if (!outputDirectory) {
throw new Error('outputDir is required');
}
mkdirp.sync(outputDirectory);

let schemaPaths;
try {
schemaPaths = JSON.parse(schemaListText);
} catch (err) {
throw new Error(`Can't parse schema to JSON. ${schemaListPath}`);
}

const schemas = {};
try {
for (const libraryName of Object.keys(schemaPaths)) {
const tmpSchemaText = fs.readFileSync(schemaPaths[libraryName], 'utf-8');
schemas[libraryName] = JSON.parse(tmpSchemaText);
}
} catch (err) {
throw new Error(`Failed to read schema file. ${err.message}`);
}

if (GENERATORS[platform] == null) {
throw new Error(`Invalid platform type. ${platform}`);
}

RNCodegen.generateFromSchemas(
{
schemas,
outputDirectory,
},
{
generators: GENERATORS[platform],
},
);
}

function main() {
generateProvider(argv.platform, argv.schemaListPath, argv.outputDir);
}

main();

0 comments on commit 4ff16c6

Please sign in to comment.