From 05392bc1e5ff6c2b2572fdc76953e00b576aa047 Mon Sep 17 00:00:00 2001 From: ning Date: Thu, 17 May 2018 19:22:05 +0800 Subject: [PATCH 1/3] Add pre-commit and pre-push lint and test steps Addresses issue #3 --- package.json | 7 ++++ yarn.lock | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f419a3b32a..936803e913 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,12 @@ "test": "react-scripts-ts test --env=jsdom", "update-ui-snapshots": "jest --updateSnapshot" }, + "husky": { + "hooks": { + "pre-commit": "yarn format && CI=true yarn test", + "pre-push": "yarn format && CI=true yarn test" + } + }, "dependencies": { "@blueprintjs/core": "^2.1.1", "normalize.css": "^8.0.0", @@ -48,6 +54,7 @@ "@types/redux-mock-store": "^0.0.13", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", + "husky": "^1.0.0-rc.6", "prettier": "^1.12.0", "react-scripts-ts": "^2.15.1", "react-test-renderer": "^16.3.1", diff --git a/yarn.lock b/yarn.lock index 86de278828..f534eb0bb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1813,6 +1813,15 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + cpx@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/cpx/-/cpx-1.5.0.tgz#185be018511d87270dedccc293171e37655ab88f" @@ -2437,7 +2446,7 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: @@ -2622,6 +2631,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -3509,6 +3530,20 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +husky@^1.0.0-rc.6: + version "1.0.0-rc.6" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.0.0-rc.6.tgz#000f5ffe671015ae8c48da5c52b3390bbba9770d" + dependencies: + cosmiconfig "^4.0.0" + execa "^0.9.0" + find-up "^2.1.0" + is-ci "^1.1.0" + pkg-dir "^2.0.0" + pupa "^1.0.0" + read-pkg "^3.0.0" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -3683,7 +3718,7 @@ is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" -is-ci@^1.0.10: +is-ci@^1.0.10, is-ci@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" dependencies: @@ -4299,7 +4334,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.4.3, js-yaml@^3.7.0: +js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.11.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" dependencies: @@ -4360,6 +4395,10 @@ json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -4497,6 +4536,15 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -5331,6 +5379,13 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -5411,6 +5466,12 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -5879,6 +5940,10 @@ punycode@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" +pupa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-1.0.0.tgz#9a9568a5af7e657b8462a6e9d5328743560ceff6" + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -6184,6 +6249,14 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -6438,6 +6511,10 @@ require-from-string@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -6530,6 +6607,10 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -6734,6 +6815,10 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" From 07115b51ab3f4e8ffae256aefe8f8fb90fd29dd4 Mon Sep 17 00:00:00 2001 From: ning Date: Thu, 17 May 2018 19:24:16 +0800 Subject: [PATCH 2/3] Update test snapshot --- src/reducers/__tests__/__snapshots__/application.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reducers/__tests__/__snapshots__/application.ts.snap b/src/reducers/__tests__/__snapshots__/application.ts.snap index c57267d708..21139a3532 100644 --- a/src/reducers/__tests__/__snapshots__/application.ts.snap +++ b/src/reducers/__tests__/__snapshots__/application.ts.snap @@ -3,6 +3,6 @@ exports[`initial state should match a snapshot 1`] = ` Object { "environment": "test", - "title": "Conveyor", + "title": "Cadet", } `; From 299ae569da5fc1561352ec1689f950200563a8c8 Mon Sep 17 00:00:00 2001 From: ning Date: Thu, 17 May 2018 22:53:55 +0800 Subject: [PATCH 3/3] Add yarn command coverage, and helper script Files ending with *.d.ts in the project directory (excluding node_modules) will cause yarn test --coverage (i.e. yarn react-scripts-ts --coverage) to throw ~100 lines of warning messages. To avoid this, the script coverage-fix.sh temporarily renames all *.d.ts files in the relevant directory ./src/ as *.ts files. Then, it runs just, and allows it to generate the coverage report smoothly. Finally, as clean-up, coverage-fix renames the affected *d.ts files (briefly *.ts) back to their original names. --- package.json | 1 + scripts/coverage-fix.sh | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100755 scripts/coverage-fix.sh diff --git a/package.json b/package.json index 936803e913..c138eab26c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "start": "react-scripts-ts start", "build": "react-scripts-ts build", "test": "react-scripts-ts test --env=jsdom", + "coverage": "./scripts/coverage-fix.sh do && react-scripts-ts test --env=jsdom --coverage && ./scripts/coverage-fix.sh undo", "update-ui-snapshots": "jest --updateSnapshot" }, "husky": { diff --git a/scripts/coverage-fix.sh b/scripts/coverage-fix.sh new file mode 100755 index 0000000000..c82a3b0196 --- /dev/null +++ b/scripts/coverage-fix.sh @@ -0,0 +1,61 @@ +#! /usr/bin/env bash + +DIR_TO_LOOK="./src" + +main() { + # make sure we are in the git root + if [[ $(git rev-parse --show-toplevel 2> /dev/null) = "$PWD" ]]; then + if [ "$1" == "do" ]; then + do_change + elif [ "$1" == "undo" ]; then + undo_change + else + echo "Specify 'do' or 'undo' as argument" + fi + else + echo "Please run this command from the git root directory." + false # exit 1 + fi +} + +do_change() { + # local variables in this function: + # tsd_files: string[] - filenames of *.d.ts + # ts_files: string[] - filenames of tsd_files converted as *.ts + # note that .coverage-fix.tmp is used to keep track of *.ts files that need + # to be renamed back to *.d.ts + local tsd_files=( `find "$DIR_TO_LOOK" -name "*.d.ts"` ) + local ts_files=( `printf '%s\n' "${tsd_files[@]}" | sed -e "s/.d.ts/.ts/g"` ) + printf '%s\n' "${ts_files[@]}" > .coverage-fix.tmp + local number_files=`cat .coverage-fix.tmp | wc -l` + + # because printf %s\n is used to generage .coverage-fix.tmp, + # an empty array of ts_files still generates wc -l -> 1 + # in this case, mv will receive 2 empty arguments "", throwing an error + # to avoid, detect if .coverage-fix.tmp has only one character \n + if [[ `cat .coverage-fix.tmp | wc -m` -ne 1 ]]; then + local last_index=$(( number_files - 1 )) + for i in $(seq 0 $last_index); do + echo Renaming "${tsd_files[$i]}" as "${ts_files[$i]}"... + mv "${tsd_files[$i]}" "${ts_files[$i]}" + done + fi +} + +undo_change() { + local ts_files=( `cat .coverage-fix.tmp` ) + local tsd_files=( `printf '%s\n' "${ts_files[@]}" | sed -e "s/.ts/.d.ts/g"` ) + local number_files=`cat .coverage-fix.tmp | wc -l` + + if [[ `cat .coverage-fix.tmp | wc -m` -ne 1 ]]; then + local last_index=$(( number_files - 1 )) + for i in $(seq 0 $last_index); do + echo Renaming "${ts_files[$i]}" as "${tsd_files[$i]}"... + mv "${ts_files[$i]}" "${tsd_files[$i]}" + done + fi + + rm .coverage-fix.tmp +} + +main $1