diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000000..31354ec138 --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..36af219892 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 98b4db777a..0000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - singleQuote: true, - jsxBracketSameLine: true, -}; diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000000..ce36dd446d --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,8 @@ +singleQuote: true +jsxBracketSameLine: true + +overrides: + - files: + - "*.java" + options: + printWidth: 100 \ No newline at end of file diff --git a/package.json b/package.json index c0b677b0b8..07827dc04b 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "test:unit": "jest --passWithNoTests", "format": "yarn format-js && yarn format-android && yarn format-ios && yarn format-windows", "format-js": "prettier --write --list-different './{src,Example}/**/*.{js,ts,tsx}'", - "format-android": "node ./scripts/lint-java.js", + "format-android": "prettier --write --list-different './android/**/*.java'", "format-ios": "find ios/ -iname *.h -o -iname *.m -o -iname *.cpp | xargs clang-format -i", "format-windows": "find windows/ -iname *.h -o -iname *.m -o -iname *.cpp | xargs clang-format -i", "lint": "eslint --ext '.js,.ts,.tsx' --fix src && yarn check-types", "precommit": "yarn format && yarn lint", "release": "npm login && release-it", - "prepare": "bob build" + "prepare": "bob build && husky install" }, "main": "lib/commonjs/index", "module": "lib/module/index", @@ -80,12 +80,13 @@ "eslint-plugin-react": "^7.20.5", "eslint-plugin-react-native": "^3.2.1", "eslint-plugin-standard": "^4.0.1", - "husky": "^0.14.3", + "husky": "^7.0.1", "jest": "^26.2.2", "jest-react-native": "18.0.0", "lint-staged": "^7.1.3", "metro-react-native-babel-preset": "^0.61.0", "prettier": "^2.0.4", + "prettier-plugin-java": "^1.3.1", "react": "^16.13.1", "react-dom": "^16.13.1", "react-native": "^0.63.2", @@ -100,9 +101,9 @@ "lint-staged": { "*.{js,ts,tsx}": [ "eslint --cache --fix", - "prettier --write", - "git add" - ] + "prettier --write './{src,Example}/**/*.{js,ts,tsx}'" + ], + "*.java": "prettier --write './android/**/*.java'" }, "@react-native-community/bob": { "source": "src", diff --git a/scripts/lint-java.js b/scripts/lint-java.js deleted file mode 100644 index f0f423aaf5..0000000000 --- a/scripts/lint-java.js +++ /dev/null @@ -1,197 +0,0 @@ -// code taken from facebook/react-native repo - -'use strict'; - -const {exec} = require('shelljs'); -const https = require('https'); -const fs = require('fs'); -const path = require('path'); -const os = require('os'); -const yargs = require('yargs'); - -const googleJavaFormatUrl = - 'https://github.com/google/google-java-format/releases/download/google-java-format-1.7/google-java-format-1.7-all-deps.jar'; -const googleJavaFormatPath = path.join( - os.tmpdir(), - 'google-java-format-all-deps.jar', -); -const javaFilesCommand = 'find ./android -name "*.java"'; - -function _download(url, downloadPath, resolve, reject, redirectCount) { - https.get(url, response => { - switch (response.statusCode) { - case 302: //Permanent Redirect - if (redirectCount === 0) { - throw new Error( - `Unhandled response code (HTTP${response.statusCode}) while retrieving google-java-format binary from ${url}`, - ); - } - - _download( - response.headers.location, - downloadPath, - resolve, - reject, - redirectCount - 1, - ); - break; - case 200: //OK - const file = fs.createWriteStream(downloadPath); - - response.pipe(file); - file.on('finish', () => file.close(() => resolve())); - break; - default: - reject( - `Unhandled response code (HTTP${response.statusCode}) while retrieving google-java-format binary from ${url}`, - ); - } - }); -} - -function download(url, downloadPath) { - return new Promise((resolve, reject) => { - _download(url, downloadPath, resolve, reject, 1); - }); -} - -function filesWithLintingIssues() { - const proc = exec( - `java -jar ${googleJavaFormatPath} --dry-run $(${javaFilesCommand})`, - {silent: true}, - ); - - if (proc.code !== 0) { - throw new Error(proc.stderr); - } - - return proc.stdout.split('\n').filter(x => x); -} - -function unifiedDiff(file) { - const lintedProc = exec( - `java -jar ${googleJavaFormatPath} --set-exit-if-changed ${file}`, - {silent: true}, - ); - - //Exit code 1 indicates lint violations, which is what we're expecting - if (lintedProc.code !== 1) { - throw new Error(lintedProc.stderr); - } - - const diffProc = lintedProc.exec(`diff -U 0 ${file} -`, {silent: true}); - - //Exit code 0 if inputs are the same, 1 if different, 2 if trouble. - if (diffProc.code !== 0 && diffProc.code !== 1) { - throw new Error(diffProc.stderr); - } - - return { - file, - diff: diffProc.stdout, - }; -} - -function extractRangeInformation(range) { - //eg; - // @@ -54 +54,2 @@ - // @@ -1,3 +1,9 @@ - - const regex = /^@@ [-+](\d+,?\d+) [-+](\d+,?\d+) @@$/; - const match = regex.exec(range); - - if (match) { - const original = match[1].split(','); - const updated = match[2].split(','); - - return { - original: { - line: parseInt(original[0], 10), - lineCount: parseInt(original[1], 10) || 1, - }, - updated: { - line: parseInt(updated[0], 10), - lineCount: parseInt(updated[1], 10) || 1, - }, - }; - } -} - -function parseChanges(file, diff) { - let group = null; - const groups = []; - - diff.split('\n').forEach(line => { - const range = extractRangeInformation(line); - - if (range) { - group = { - range, - description: [line], - }; - groups.push(group); - } else if (group) { - group.description.push(line); - } - }); - - return groups.map(x => ({ - file, - line: x.range.original.line, - lineCount: x.range.original.lineCount, - description: x.description.join('\n'), - })); -} - -async function main() { - const {argv} = yargs - .scriptName('lint-java') - .usage('Usage: $0 [options]') - .command( - '$0', - 'Downloads the google-java-format package and reformats Java source code to comply with Google Java Style.\n\nSee https://github.com/google/google-java-format', - ) - .option('check', { - type: 'boolean', - description: - 'Outputs a list of files with lint violations.\nExit code is set to 1 if there are violations, otherwise 0.\nDoes not reformat lint issues.', - }) - .option('diff', { - type: 'boolean', - description: - 'Outputs a diff of the lint fix changes in json format.\nDoes not reformat lint issues.', - }); - - await download(googleJavaFormatUrl, googleJavaFormatPath); - - if (argv.check) { - const files = filesWithLintingIssues(); - - files.forEach(x => console.log(x)); - - process.exit(files.length === 0 ? 0 : 1); - - } - - if (argv.diff) { - const suggestions = filesWithLintingIssues() - .map(unifiedDiff) - .filter(x => x) - .map(x => parseChanges(x.file, x.diff)) - .reduce((accumulator, current) => accumulator.concat(current), []); - - console.log(JSON.stringify(suggestions)); - - return; - } - - const proc = exec( - `java -jar ${googleJavaFormatPath} --set-exit-if-changed --replace $(${javaFilesCommand})`, - ); - - process.exit(proc.code); -} - -(async () => { - await main(); -})(); diff --git a/yarn.lock b/yarn.lock index 247afeecd1..866d8e44aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4044,10 +4044,12 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +chevrotain@6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/chevrotain/-/chevrotain-6.5.0.tgz#dcbef415516b0af80fd423cc0d96b28d3f11374e" + integrity sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg== + dependencies: + regexp-to-ast "0.4.0" ci-info@^2.0.0: version "2.0.0" @@ -6071,14 +6073,10 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -husky@^0.14.3: - version "0.14.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" - integrity sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA== - dependencies: - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" +husky@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.1.tgz#579f4180b5da4520263e8713cc832942b48e1f1c" + integrity sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA== iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: version "0.4.24" @@ -6315,13 +6313,6 @@ is-ci@2.0.0, is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -6695,6 +6686,14 @@ jake@^10.6.1: filelist "^1.0.1" minimatch "^3.0.4" +java-parser@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/java-parser/-/java-parser-1.3.1.tgz#a1b731f991a663430271ea25ffaf4d249a0b278a" + integrity sha512-CCKO1Fqf72pfLjfBOx94ZDXp1mTztqej1dsBkb98Z3qGMxKHCZrXhi6glx6aX6IrJ5EiY2eMiuuzkVnYWfra1Q== + dependencies: + chevrotain "6.5.0" + lodash "4.17.21" + jest-changed-files@^26.2.0: version "26.2.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.2.0.tgz#b4946201defe0c919a2f3d601e9f98cb21dacc15" @@ -7691,6 +7690,11 @@ lodash@4.17.15, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17. resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + lodash@^4.17.19: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" @@ -8725,11 +8729,6 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= - normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -9335,6 +9334,20 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= +prettier-plugin-java@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-java/-/prettier-plugin-java-1.3.1.tgz#287b94f3bf0a9c2eea80ab7776b319a2b371c40f" + integrity sha512-1/dhvWX/CZHzzMZ4VKfuX9k70L24KvKMLMTghkPRIYax2MP5Znct24AY5Y4BdnmCimjQ9/FT1m2xXtoPAXxdmA== + dependencies: + java-parser "1.3.1" + lodash "4.17.21" + prettier "2.3.1" + +prettier@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" + integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== + prettier@^2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" @@ -9782,6 +9795,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp-to-ast@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz#f3dbcb42726cd71902ba50193f63eab5325cd7cb" + integrity sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw== + regexp.prototype.flags@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" @@ -10729,11 +10747,6 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - strip-json-comments@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"