2022-11-25 00:56:09 +03:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*
|
2024-02-13 13:32:21 +03:00
|
|
|
* @flow
|
2022-11-25 00:56:09 +03:00
|
|
|
* @format
|
2024-02-13 13:32:21 +03:00
|
|
|
* @oncall react_native
|
2022-11-25 00:56:09 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2023-11-06 23:59:38 +03:00
|
|
|
const {retry} = require('../circleci/retry');
|
2024-02-16 14:21:25 +03:00
|
|
|
const {REPO_ROOT} = require('../consts');
|
2024-02-20 20:55:46 +03:00
|
|
|
const {getPackages} = require('../utils/monorepo');
|
2024-02-16 00:04:00 +03:00
|
|
|
const {
|
|
|
|
VERDACCIO_SERVER_URL,
|
|
|
|
VERDACCIO_STORAGE_PATH,
|
|
|
|
setupVerdaccio,
|
2024-02-16 01:51:48 +03:00
|
|
|
} = require('./utils/verdaccio');
|
2024-02-13 13:32:21 +03:00
|
|
|
const {parseArgs} = require('@pkgjs/parseargs');
|
2024-02-16 00:04:00 +03:00
|
|
|
const chalk = require('chalk');
|
2023-11-06 23:59:38 +03:00
|
|
|
const {execSync} = require('child_process');
|
2024-02-20 20:55:46 +03:00
|
|
|
const path = require('path');
|
2022-11-25 00:56:09 +03:00
|
|
|
|
2024-02-13 13:32:21 +03:00
|
|
|
const config = {
|
|
|
|
options: {
|
|
|
|
projectName: {type: 'string'},
|
|
|
|
templatePath: {type: 'string'},
|
|
|
|
directory: {type: 'string'},
|
2024-02-16 00:04:00 +03:00
|
|
|
verbose: {type: 'boolean', default: false},
|
2024-02-13 13:32:21 +03:00
|
|
|
help: {type: 'boolean'},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
const {
|
2024-02-16 00:04:00 +03:00
|
|
|
values: {help, ...options},
|
2024-02-13 13:32:21 +03:00
|
|
|
} = parseArgs(config);
|
|
|
|
|
|
|
|
if (help) {
|
|
|
|
console.log(`
|
2024-02-16 01:51:48 +03:00
|
|
|
Usage: node ./scripts/e2e/init-template-e2e.js [OPTIONS]
|
2024-02-13 13:32:21 +03:00
|
|
|
|
|
|
|
Bootstraps and runs \`react-native init\`, using the currently checked out
|
|
|
|
repository as the source of truth for the react-native package and
|
|
|
|
dependencies.
|
|
|
|
|
|
|
|
- Configures and starts a local npm proxy (Verdaccio).
|
|
|
|
- Builds and publishes all in-repo dependencies to the local npm proxy.
|
|
|
|
- Runs \`react-native init\` with the local npm proxy configured.
|
|
|
|
- Does NOT install CocoaPods dependencies.
|
|
|
|
|
|
|
|
Note: This script will mutate the contents of some package files, which
|
|
|
|
should not be committed.
|
|
|
|
|
|
|
|
Options:
|
|
|
|
--projectName The name of the new React Native project.
|
|
|
|
--templatePath The absolute path to the folder containing the template.
|
|
|
|
--directory The absolute path to the target project directory.
|
2024-02-16 00:04:00 +03:00
|
|
|
--verbose Print additional output. Default: false.
|
2024-02-13 13:32:21 +03:00
|
|
|
`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-02-16 00:04:00 +03:00
|
|
|
await initNewProjectFromSource(options);
|
2024-02-21 18:51:10 +03:00
|
|
|
|
|
|
|
// TODO(T179377112): Fix memory leak from `spawn` in `setupVerdaccio` (above
|
|
|
|
// kill command does not wait for kill success).
|
|
|
|
process.exit(0);
|
2024-02-16 00:04:00 +03:00
|
|
|
}
|
2024-02-13 13:32:21 +03:00
|
|
|
|
2024-02-16 00:04:00 +03:00
|
|
|
async function initNewProjectFromSource(
|
|
|
|
{
|
|
|
|
projectName,
|
|
|
|
templatePath,
|
|
|
|
directory,
|
|
|
|
verbose = false,
|
|
|
|
} /*: {projectName: string, templatePath: string, directory: string, verbose?: boolean} */,
|
|
|
|
) {
|
|
|
|
console.log('Starting local npm proxy (Verdaccio)');
|
|
|
|
const verdaccioPid = setupVerdaccio();
|
|
|
|
console.log('Done ✅');
|
2023-08-16 18:31:44 +03:00
|
|
|
|
2024-02-16 00:04:00 +03:00
|
|
|
try {
|
2023-08-22 18:08:15 +03:00
|
|
|
execSync('node ./scripts/build/build.js', {
|
|
|
|
cwd: REPO_ROOT,
|
2024-02-16 00:04:00 +03:00
|
|
|
stdio: 'inherit',
|
2023-08-22 18:08:15 +03:00
|
|
|
});
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('\nDone ✅');
|
2023-08-22 18:08:15 +03:00
|
|
|
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('Publishing packages to local npm proxy\n');
|
2024-02-20 20:55:46 +03:00
|
|
|
const packages = await getPackages({
|
|
|
|
includeReactNative: false,
|
|
|
|
includePrivate: false,
|
|
|
|
});
|
|
|
|
|
|
|
|
for (const {path: packagePath, packageJson} of Object.values(packages)) {
|
|
|
|
const desc = `${packageJson.name} (${path.relative(
|
|
|
|
REPO_ROOT,
|
|
|
|
packagePath,
|
|
|
|
)})`;
|
|
|
|
process.stdout.write(
|
|
|
|
`${desc} ${chalk.dim('.').repeat(Math.max(0, 72 - desc.length))} `,
|
|
|
|
);
|
|
|
|
execSync(
|
|
|
|
`npm publish --registry ${VERDACCIO_SERVER_URL} --access public`,
|
|
|
|
{
|
|
|
|
cwd: packagePath,
|
|
|
|
stdio: verbose ? 'inherit' : [process.stderr],
|
|
|
|
},
|
|
|
|
);
|
|
|
|
process.stdout.write(chalk.reset.inverse.bold.green(' DONE ') + '\n');
|
|
|
|
}
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('\nDone ✅');
|
2023-08-16 18:31:44 +03:00
|
|
|
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('Running react-native init without install');
|
2023-08-16 18:31:44 +03:00
|
|
|
execSync(
|
2024-02-16 00:04:00 +03:00
|
|
|
`node ./packages/react-native/cli.js init ${projectName} \
|
2024-02-13 13:32:21 +03:00
|
|
|
--directory ${directory} \
|
|
|
|
--template ${templatePath} \
|
|
|
|
--verbose \
|
2024-03-05 17:18:37 +03:00
|
|
|
--pm npm \
|
|
|
|
--skip-install`,
|
2023-08-16 18:31:44 +03:00
|
|
|
{
|
2024-02-16 00:04:00 +03:00
|
|
|
// Avoid loading packages/react-native/react-native.config.js
|
|
|
|
cwd: REPO_ROOT,
|
2024-02-21 18:51:10 +03:00
|
|
|
stdio: 'inherit',
|
2023-08-16 18:31:44 +03:00
|
|
|
},
|
|
|
|
);
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('\nDone ✅');
|
|
|
|
|
|
|
|
console.log('Installing project dependencies');
|
2024-02-21 18:51:10 +03:00
|
|
|
await installProjectUsingProxy(directory);
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('Done ✅');
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Failed ❌');
|
|
|
|
throw e;
|
|
|
|
} finally {
|
|
|
|
console.log(`Cleanup: Killing Verdaccio process (PID: ${verdaccioPid})`);
|
2024-02-21 18:51:10 +03:00
|
|
|
try {
|
|
|
|
execSync(`kill -9 ${verdaccioPid}`);
|
|
|
|
console.log('Done ✅');
|
|
|
|
} catch {
|
|
|
|
console.warn('Failed to kill Verdaccio process');
|
|
|
|
}
|
2024-02-16 00:04:00 +03:00
|
|
|
console.log('Cleanup: Removing Verdaccio storage directory');
|
|
|
|
execSync(`rm -rf ${VERDACCIO_STORAGE_PATH}`);
|
|
|
|
console.log('Done ✅');
|
2023-08-16 18:31:44 +03:00
|
|
|
}
|
2022-11-25 00:56:09 +03:00
|
|
|
}
|
|
|
|
|
2024-02-21 18:51:10 +03:00
|
|
|
async function installProjectUsingProxy(cwd /*: string */) {
|
2024-02-16 00:04:00 +03:00
|
|
|
const execOptions = {
|
|
|
|
cwd,
|
|
|
|
stdio: 'inherit',
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO(huntie): Review pre-existing retry limit
|
2024-02-21 18:51:10 +03:00
|
|
|
const success = await retry('npm', execOptions, 3, 500, [
|
|
|
|
'install',
|
|
|
|
'--registry',
|
|
|
|
VERDACCIO_SERVER_URL,
|
|
|
|
]);
|
2024-02-16 00:04:00 +03:00
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
throw new Error('Failed to install project dependencies');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
initNewProjectFromSource,
|
|
|
|
};
|
|
|
|
|
2024-02-13 13:32:21 +03:00
|
|
|
if (require.main === module) {
|
|
|
|
// eslint-disable-next-line no-void
|
|
|
|
void main();
|
|
|
|
}
|