mirror of
https://github.com/react/react-native.git
synced 2026-09-28 05:13:06 +08:00
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58465 Add `yarn format-python` and `yarn format-check-python` using Ruff, and compose them into the repository-wide commands. The wrapper selects a repository-provided Ruff binary when available or bootstraps pinned Ruff through Python 3 and pip. Missing tools produce environment-specific setup guidance before Python is skipped. Changelog: [Internal] Reviewed By: javache Differential Revision: D119487614 fbshipit-source-id: 4801ae3e565fcaa86a860cc5b8bb3b2d823d48df
206 lines
5.0 KiB
JavaScript
206 lines
5.0 KiB
JavaScript
/**
|
|
* 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.
|
|
*
|
|
* @noflow
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const {IS_META_CHECKOUT, findMetaTool} = require('./format-utils');
|
|
const {spawnSync} = require('node:child_process');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
const RUFF_VERSION = '0.14.0';
|
|
const RUFF_ROOT = path.join(
|
|
REPO_ROOT,
|
|
'node_modules',
|
|
'.cache',
|
|
'react-native-format',
|
|
`ruff-${RUFF_VERSION}`,
|
|
);
|
|
|
|
function run(command, args, options = {}) {
|
|
const environment = options.env ?? process.env;
|
|
const result = spawnSync(command, args, {
|
|
cwd: REPO_ROOT,
|
|
stdio: options.quiet === true ? 'ignore' : 'inherit',
|
|
...options,
|
|
env: {...environment, PWD: REPO_ROOT},
|
|
});
|
|
if (result.error != null) {
|
|
if (options.quiet !== true) {
|
|
console.error(result.error.message);
|
|
}
|
|
return {status: 1};
|
|
}
|
|
if (result.signal != null) {
|
|
process.kill(process.pid, result.signal);
|
|
return {status: 1};
|
|
}
|
|
return {status: result.status ?? 1};
|
|
}
|
|
|
|
function findPython() {
|
|
const candidates =
|
|
process.platform === 'win32'
|
|
? [
|
|
['py', ['-3']],
|
|
['python', []],
|
|
]
|
|
: [
|
|
['python3', []],
|
|
['python', []],
|
|
];
|
|
|
|
for (const [command, prefixArguments] of candidates) {
|
|
if (
|
|
run(
|
|
command,
|
|
[
|
|
...prefixArguments,
|
|
'-c',
|
|
'import sys; raise SystemExit(sys.version_info.major != 3)',
|
|
],
|
|
{quiet: true},
|
|
).status === 0
|
|
) {
|
|
return {command, prefixArguments};
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function warnMissingPython() {
|
|
console.warn(
|
|
'warning: Skipping Python formatting because Python 3 with pip was not found.\n' +
|
|
'Please install Python 3 with pip and make sure `python3` (`py -3` on Windows) and pip are available in your PATH.',
|
|
);
|
|
}
|
|
|
|
function warnMissingMetaRuff() {
|
|
console.warn(
|
|
'warning: Skipping Python formatting because the Meta-managed Ruff tool could not run.\n' +
|
|
'From the fbsource root, run `tools/third-party/ruff/ruff --version`. ' +
|
|
'If that fails, repair your Meta DotSlash setup.',
|
|
);
|
|
}
|
|
|
|
function runRuff(command, prefixArguments, check) {
|
|
if (
|
|
run(command, [...prefixArguments, '--version'], {quiet: true}).status !== 0
|
|
) {
|
|
return false;
|
|
}
|
|
const format = run(command, [
|
|
...prefixArguments,
|
|
'format',
|
|
...(check ? ['--check'] : []),
|
|
'.',
|
|
]);
|
|
process.exit(format.status);
|
|
}
|
|
|
|
function main() {
|
|
const check = process.argv[2] === '--check';
|
|
if (process.env.RUFF != null) {
|
|
if (!runRuff(process.env.RUFF, [], check)) {
|
|
if (IS_META_CHECKOUT) {
|
|
warnMissingMetaRuff();
|
|
} else {
|
|
console.warn(
|
|
'warning: Skipping Python formatting because the configured Ruff command could not run.\n' +
|
|
'Please install Ruff and set RUFF=/path/to/ruff, or unset RUFF to use automatic installation.',
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
const metaRuff = findMetaTool('tools', 'third-party', 'ruff', 'ruff');
|
|
if (metaRuff != null) {
|
|
if (!runRuff(metaRuff.command, metaRuff.prefixArguments, check)) {
|
|
warnMissingMetaRuff();
|
|
}
|
|
return;
|
|
}
|
|
if (IS_META_CHECKOUT) {
|
|
warnMissingMetaRuff();
|
|
return;
|
|
}
|
|
|
|
const python = findPython();
|
|
if (python == null) {
|
|
warnMissingPython();
|
|
return;
|
|
}
|
|
const pythonPath = [RUFF_ROOT, process.env.PYTHONPATH]
|
|
.filter(Boolean)
|
|
.join(path.delimiter);
|
|
const environment = {...process.env, PYTHONPATH: pythonPath};
|
|
|
|
if (
|
|
run(python.command, [...python.prefixArguments, '-c', 'import ruff'], {
|
|
env: environment,
|
|
quiet: true,
|
|
}).status !== 0
|
|
) {
|
|
if (
|
|
run(
|
|
python.command,
|
|
[...python.prefixArguments, '-m', 'pip', '--version'],
|
|
{quiet: true},
|
|
).status !== 0
|
|
) {
|
|
warnMissingPython();
|
|
return;
|
|
}
|
|
try {
|
|
fs.mkdirSync(RUFF_ROOT, {recursive: true});
|
|
} catch (error) {
|
|
console.warn(
|
|
`warning: Skipping Python formatting because the Ruff cache could not be created: ${String(error)}`,
|
|
);
|
|
return;
|
|
}
|
|
const install = run(python.command, [
|
|
...python.prefixArguments,
|
|
'-m',
|
|
'pip',
|
|
'install',
|
|
'--disable-pip-version-check',
|
|
'--only-binary=:all:',
|
|
`--target=${RUFF_ROOT}`,
|
|
`ruff==${RUFF_VERSION}`,
|
|
]);
|
|
if (install.status !== 0) {
|
|
console.warn(
|
|
`warning: Skipping Python formatting because Ruff ${RUFF_VERSION} could not be installed.\n` +
|
|
'Please check your network connection, or install Ruff and set RUFF=/path/to/ruff.',
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
const format = run(
|
|
python.command,
|
|
[
|
|
...python.prefixArguments,
|
|
'-m',
|
|
'ruff',
|
|
'format',
|
|
...(check ? ['--check'] : []),
|
|
'.',
|
|
],
|
|
{env: environment},
|
|
);
|
|
process.exit(format.status);
|
|
}
|
|
|
|
main();
|