mirror of
https://github.com/react/react-native.git
synced 2026-09-28 05:13:06 +08:00
Add Kotlin to yarn format (#58462)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58462 Add `yarn format-kotlin` and `yarn format-check-kotlin` using the npm `ktfmt` package and its bundled formatter jar. This adds the offline package mirror and workspace lock entry without changing existing Kotlin source formatting or Gradle configuration. The wrapper discovers a suitable JDK when available and otherwise prints environment-specific Java 17 setup guidance before skipping Kotlin. allow-large-files: The npm package intentionally contains the upstream ktfmt executable jar so offline and public installs use the same formatter. Changelog: [Internal] Reviewed By: javache Differential Revision: D119487612 fbshipit-source-id: cb699a1286cffbf461ef69ed66f694e3f69415d0
This commit is contained in:
committed by
meta-codesync[bot]
parent
ec9952a62d
commit
07e4bf34d0
+5
-4
@@ -14,16 +14,16 @@
|
|||||||
"cxx-api-validate": "python -m scripts.cxx-api.parser --validate",
|
"cxx-api-validate": "python -m scripts.cxx-api.parser --validate",
|
||||||
"flow-check": "flow full-check",
|
"flow-check": "flow full-check",
|
||||||
"flow": "flow",
|
"flow": "flow",
|
||||||
"format-check": "yarn format-check-javascript && yarn format-check-cpp",
|
"format-check": "yarn format-check-javascript && yarn format-check-cpp && yarn format-check-kotlin",
|
||||||
"format-check-cpp": "node ./scripts/clang-format.js --check",
|
"format-check-cpp": "node ./scripts/clang-format.js --check",
|
||||||
"format-check-javascript": "prettier --check \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
"format-check-javascript": "prettier --check \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
||||||
"format": "yarn format-javascript && yarn format-cpp",
|
"format-check-kotlin": "node ./scripts/format-kotlin.js --check",
|
||||||
|
"format": "yarn format-javascript && yarn format-cpp && yarn format-kotlin",
|
||||||
"format-cpp": "node ./scripts/clang-format.js",
|
"format-cpp": "node ./scripts/clang-format.js",
|
||||||
"format-javascript": "prettier --write \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
"format-javascript": "prettier --write \"./**/*.{cjs,cts,flow,js,jsx,md,mjs,mts,ts,tsx,yaml,yml}\"",
|
||||||
|
"format-kotlin": "node ./scripts/format-kotlin.js",
|
||||||
"featureflags": "yarn --cwd packages/react-native featureflags",
|
"featureflags": "yarn --cwd packages/react-native featureflags",
|
||||||
"js-api-diff": "node ./scripts/js-api/diff-api-snapshot",
|
"js-api-diff": "node ./scripts/js-api/diff-api-snapshot",
|
||||||
"lint-kotlin-check": "./gradlew ktfmtCheck",
|
|
||||||
"lint-kotlin": "./gradlew ktfmtFormat",
|
|
||||||
"lint-markdown": "markdownlint-cli2 2>&1",
|
"lint-markdown": "markdownlint-cli2 2>&1",
|
||||||
"lint": "eslint --max-warnings 0 .",
|
"lint": "eslint --max-warnings 0 .",
|
||||||
"preinstall": "node ./scripts/try-set-hermes-compiler-prebuilt.js",
|
"preinstall": "node ./scripts/try-set-hermes-compiler-prebuilt.js",
|
||||||
@@ -101,6 +101,7 @@
|
|||||||
"jest-junit": "^16.0.0",
|
"jest-junit": "^16.0.0",
|
||||||
"jest-snapshot": "^29.7.0",
|
"jest-snapshot": "^29.7.0",
|
||||||
"jsonc-parser": "2.2.1",
|
"jsonc-parser": "2.2.1",
|
||||||
|
"ktfmt": "0.59.0",
|
||||||
"markdownlint-cli2": "^0.17.2",
|
"markdownlint-cli2": "^0.17.2",
|
||||||
"markdownlint-rule-relative-links": "^3.0.0",
|
"markdownlint-rule-relative-links": "^3.0.0",
|
||||||
"memfs": "^4.38.2",
|
"memfs": "^4.38.2",
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* 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 {findJava, warnMissingJava} = require('./format-utils');
|
||||||
|
const {spawnSync} = require('node:child_process');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const {globSync} = require('tinyglobby');
|
||||||
|
|
||||||
|
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||||
|
const KTFMT_JAR = require.resolve('ktfmt/lib/ktfmt.jar');
|
||||||
|
const GENERATED_MARKER = Buffer.from('@' + 'generated');
|
||||||
|
const MINIMUM_JAVA_VERSION = 17;
|
||||||
|
const MAX_FILES_PER_PROCESS = 100;
|
||||||
|
const MAX_HEADER_BYTES = 4096;
|
||||||
|
const IGNORE = [
|
||||||
|
'**/build/**',
|
||||||
|
'**/com/facebook/yoga/**',
|
||||||
|
'**/hermes-engine/**',
|
||||||
|
'**/internal/featureflags/**',
|
||||||
|
'**/node_modules/**',
|
||||||
|
'**/systeminfo/ReactNativeVersion.kt',
|
||||||
|
];
|
||||||
|
|
||||||
|
function isGenerated(file) {
|
||||||
|
const fd = fs.openSync(path.resolve(REPO_ROOT, file), 'r');
|
||||||
|
try {
|
||||||
|
const header = Buffer.alloc(MAX_HEADER_BYTES);
|
||||||
|
const bytesRead = fs.readSync(fd, header, 0, header.length, 0);
|
||||||
|
return header.subarray(0, bytesRead).includes(GENERATED_MARKER);
|
||||||
|
} finally {
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const check = process.argv[2] === '--check';
|
||||||
|
const java = findJava(MINIMUM_JAVA_VERSION);
|
||||||
|
if (java == null) {
|
||||||
|
warnMissingJava('Kotlin');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const files = globSync('**/*.{kt,kts}', {
|
||||||
|
cwd: REPO_ROOT,
|
||||||
|
ignore: IGNORE,
|
||||||
|
}).filter(file => !isGenerated(file));
|
||||||
|
for (let i = 0; i < files.length; i += MAX_FILES_PER_PROCESS) {
|
||||||
|
const result = spawnSync(
|
||||||
|
java,
|
||||||
|
[
|
||||||
|
'-jar',
|
||||||
|
KTFMT_JAR,
|
||||||
|
'--do-not-remove-unused-imports',
|
||||||
|
...(check ? ['--dry-run', '--set-exit-if-changed'] : []),
|
||||||
|
...files.slice(i, i + MAX_FILES_PER_PROCESS),
|
||||||
|
],
|
||||||
|
{cwd: REPO_ROOT, stdio: 'inherit'},
|
||||||
|
);
|
||||||
|
if (result.error != null) {
|
||||||
|
throw result.error;
|
||||||
|
}
|
||||||
|
if (result.signal != null) {
|
||||||
|
process.kill(process.pid, result.signal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result.status !== 0) {
|
||||||
|
process.exit(result.status ?? 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* 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 {spawnSync} = require('node:child_process');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
|
let metaUtils = null;
|
||||||
|
try {
|
||||||
|
metaUtils = require('./format-utils.fb');
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error == null ||
|
||||||
|
typeof error !== 'object' ||
|
||||||
|
error.code !== 'MODULE_NOT_FOUND' ||
|
||||||
|
!String(error.message).includes("'./format-utils.fb'")
|
||||||
|
) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const IS_META_CHECKOUT = metaUtils != null;
|
||||||
|
|
||||||
|
function commandVersion(command, prefixArguments = []) {
|
||||||
|
const result = spawnSync(command, [...prefixArguments, '--version'], {
|
||||||
|
encoding: 'utf8',
|
||||||
|
env: {...process.env, PWD: REPO_ROOT},
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
output: `${result.stdout ?? ''}\n${result.stderr ?? ''}`,
|
||||||
|
status: result.status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function findMetaTool(...relativePath) {
|
||||||
|
return metaUtils?.findMetaTool(...relativePath) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function javaMajorVersion(command) {
|
||||||
|
const result = spawnSync(command, ['-version'], {encoding: 'utf8'});
|
||||||
|
const output = `${result.stdout ?? ''}\n${result.stderr ?? ''}`;
|
||||||
|
const version = /version "(?:1\.)?(\d+)/.exec(output);
|
||||||
|
return result.status === 0 && version != null ? Number(version[1]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findJava(minimumVersion) {
|
||||||
|
if (process.env.JAVA != null && process.env.JAVA !== '') {
|
||||||
|
return javaMajorVersion(process.env.JAVA) >= minimumVersion
|
||||||
|
? process.env.JAVA
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const candidates = [];
|
||||||
|
candidates.push(...(metaUtils?.findJavaCandidates() ?? []));
|
||||||
|
candidates.push('java');
|
||||||
|
|
||||||
|
return (
|
||||||
|
candidates.find(command => javaMajorVersion(command) >= minimumVersion) ??
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function warnMissingJava(language) {
|
||||||
|
const instructions =
|
||||||
|
metaUtils?.missingJavaInstructions() ??
|
||||||
|
'Please install a JDK of your choice with Java 17 or newer and make sure the `java` command is in your PATH, or set JAVA=/path/to/java.';
|
||||||
|
console.warn(
|
||||||
|
`warning: Skipping ${language} formatting because Java 17 or newer was not found.\n${instructions}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
commandVersion,
|
||||||
|
findJava,
|
||||||
|
findMetaTool,
|
||||||
|
IS_META_CHECKOUT,
|
||||||
|
warnMissingJava,
|
||||||
|
};
|
||||||
@@ -6373,6 +6373,11 @@ kleur@^3.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||||
|
|
||||||
|
ktfmt@0.59.0:
|
||||||
|
version "0.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ktfmt/-/ktfmt-0.59.0.tgz#99f98b81dbdc7f1487dfbc9850eb17b3780cf6d5"
|
||||||
|
integrity sha512-lOEn/7y2Ez2/nxDTn5EwJv6BSugB8BtzY2Gn6GvyLIAjdUf3xgKzirIxD57t/vu5I6eybivmVtONI3WGXyZ3lw==
|
||||||
|
|
||||||
language-subtag-registry@^0.3.20:
|
language-subtag-registry@^0.3.20:
|
||||||
version "0.3.23"
|
version "0.3.23"
|
||||||
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7"
|
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7"
|
||||||
|
|||||||
Reference in New Issue
Block a user