Add RFC-0759 deprecation logging cli init

Summary:
Implements the RFC which progressively provides warnings to users of the `npx react-native init` command as we gradually deprecate.

Changelog:
[General][Deprecated] - init cli deprecation logging

Reviewed By: cortinico

Differential Revision: D54423109

fbshipit-source-id: 679b6672bdbfc42a9b82a2aad38fd3253c6ea6a2
This commit is contained in:
Blake Friedman
2024-03-14 03:37:44 -07:00
committed by Facebook GitHub Bot
parent 082decb76d
commit 47a3f52007
+103 -3
View File
@@ -11,16 +11,33 @@
'use strict';
const {name, version: currentVersion} = require('./package.json');
const cli = require('@react-native-community/cli');
const chalk = require('chalk');
const {get} = require('https');
const {URL} = require('url');
const deprecated = () => {
throw new Error(
'react-native/cli is deprecated, please use @react-native-community/cli instead',
);
};
let cli = {
bin: '/dev/null',
loadConfig: deprecated,
run: deprecated,
};
const isNpxRuntime = process.env.npm_lifecycle_event === 'npx';
const DEFAULT_REGISTRY_HOST =
process.env.npm_config_registry ?? 'https://registry.npmjs.org/';
const HEAD = '1000.0.0';
// We're going to deprecate the `init` command proxying requests to @react-native-community/cli transparently
// on September 30th, 2024 or 0.76 (whichever arrives first). This is part of work to decouple of community CLI from React Native core.
//
// See https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0759-react-native-frameworks.md
const CLI_DEPRECATION_DATE = new Date('2024-09-30');
async function getLatestVersion(registryHost = DEFAULT_REGISTRY_HOST) {
return new Promise((res, rej) => {
const url = new URL(registryHost);
@@ -41,14 +58,64 @@ async function getLatestVersion(registryHost = DEFAULT_REGISTRY_HOST) {
/**
* Warn when users are using `npx react-native init`, to raise awareness of the changes from RFC 0759.
*
* Phase 1
*
* @see https://github.com/react-native-community/discussions-and-proposals/tree/main/proposals/0759-react-native-frameworks.md
*/
function warnWhenRunningInit() {
if (process.argv[2] === 'init') {
console.warn('\nRunning: npx @react-native-community/cli init\n');
console.warn(
`\nRunning: ${chalk.grey.bold('npx @react-native-community/cli init')}\n`,
);
}
}
/**
* Warn more sternly that the ability to call `npx react-native init` is going away.
*
* Phase 2
*
* @see https://github.com/react-native-community/discussions-and-proposals/tree/main/proposals/0759-react-native-frameworks.md
*/
function warnWithDeprecationSchedule() {
if (process.argv[2] !== 'init') {
return;
}
const daysRemaining = Math.ceil(
(CLI_DEPRECATION_DATE.getTime() - new Date().getTime()) / 86_400_000,
);
const emphasis =
daysRemaining < 10
? chalk.bgRed.white.bold
: daysRemaining < 30
? chalk.red.bold
: daysRemaining < 60
? chalk.green.bold
: chalk.blueBright.bold;
console.warn(`
${chalk.yellow('⚠️')} The \`init\` command is deprecated.
The behavior will be changed on ${chalk.white.bold(CLI_DEPRECATION_DATE.toLocaleDateString())} ${emphasis(`(${daysRemaining} day${daysRemaining > 1 ? 's' : ''})`)}.
- Switch to ${chalk.dim('npx @react-native-community/cli init')} for the identical behavior.
- Refer to the documentation for information about alternative tools: ${chalk.dim('https://reactnative.dev/docs/getting-started')}`);
}
function warnWithDeprecated() {
if (process.argv[2] !== 'init') {
return;
}
console.warn(`
${chalk.yellow('⚠')} The \`init\` command is deprecated.
- Switch to ${chalk.dim('npx @react-native-community/cli init')} for the identical behavior.
- Refer to the documentation for information about alternative tools: ${chalk.dim('https://reactnative.dev/docs/getting-started')}`);
}
/**
* npx react-native -> @react-native-community/cli
*
@@ -77,13 +144,46 @@ async function main() {
}
}
const isDeprecated =
CLI_DEPRECATION_DATE.getTime() <= new Date().getTime() ||
currentVersion.startsWith('0.76');
/**
* This command now fails as it's fully deprecated. It will be entirely removed in 0.77.
*
* Phase 3
*
* @see https://github.com/react-native-community/discussions-and-proposals/tree/main/proposals/0759-react-native-frameworks.md
*/
if (currentVersion !== HEAD && isDeprecated) {
warnWithDeprecated();
process.exit(1);
}
if (currentVersion.startsWith('0.75')) {
warnWithDeprecationSchedule();
}
warnWhenRunningInit();
return cli.run(name);
return require('@react-native-community/cli').run(name);
}
if (require.main === module) {
main();
} else {
try {
cli = require('@react-native-community/cli');
} catch (e) {
// We silence @react-native-community/cli missing as it is no
// longer a dependency
if (
!e.code === 'MODULE_NOT_FOUND' &&
/@react-native-community\/cli/.test(e.message)
) {
throw e;
}
}
}
module.exports = cli;