mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Add Python to yarn format (#58465)
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
This commit is contained in:
committed by
meta-codesync[bot]
parent
c9c293d061
commit
2334bf755d
+4
-2
@@ -14,16 +14,18 @@
|
||||
"cxx-api-validate": "python -m scripts.cxx-api.parser --validate",
|
||||
"flow-check": "flow full-check",
|
||||
"flow": "flow",
|
||||
"format-check": "yarn format-check-javascript && yarn format-check-cpp && yarn format-check-kotlin && yarn format-check-java",
|
||||
"format-check": "yarn format-check-javascript && yarn format-check-cpp && yarn format-check-kotlin && yarn format-check-java && yarn format-check-python",
|
||||
"format-check-cpp": "node ./scripts/clang-format.js --check",
|
||||
"format-check-java": "node ./scripts/format-java.js --check",
|
||||
"format-check-javascript": "prettier --check \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
||||
"format-check-kotlin": "node ./scripts/format-kotlin.js --check",
|
||||
"format": "yarn format-javascript && yarn format-cpp && yarn format-kotlin && yarn format-java",
|
||||
"format-check-python": "node ./scripts/format-python.js --check",
|
||||
"format": "yarn format-javascript && yarn format-cpp && yarn format-kotlin && yarn format-java && yarn format-python",
|
||||
"format-cpp": "node ./scripts/clang-format.js",
|
||||
"format-java": "node ./scripts/format-java.js",
|
||||
"format-javascript": "prettier --write \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
||||
"format-kotlin": "node ./scripts/format-kotlin.js",
|
||||
"format-python": "node ./scripts/format-python.js",
|
||||
"featureflags": "yarn --cwd packages/react-native featureflags",
|
||||
"js-api-diff": "node ./scripts/js-api/diff-api-snapshot",
|
||||
"lint-markdown": "markdownlint-cli2 2>&1",
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* 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();
|
||||
Reference in New Issue
Block a user