From 08b6744991631730bbea31b3308b5422ed50d639 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Mon, 9 Sep 2019 23:32:39 -0700 Subject: [PATCH 01/37] First iteration of the observer CLI --- package.json | 7 +- scripts/observer/.eslintrc | 5 ++ scripts/observer/README.md | 3 + scripts/observer/index.tsx | 126 +++++++++++++++++++++++++++++++++ yarn.lock | 141 +++++++++++++++++++++++++++++++++++-- 5 files changed, 276 insertions(+), 6 deletions(-) create mode 100644 scripts/observer/.eslintrc create mode 100644 scripts/observer/README.md create mode 100644 scripts/observer/index.tsx diff --git a/package.json b/package.json index 324680a18af..375e603ff66 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,8 @@ "readme-update-version": "node ./scripts/readme-update-version", "version": "yarn run readme-update-version", "storybook": "start-storybook -p 6006 --quiet", - "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static" + "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static", + "observer": "babel-node --extensions '.tsx' ./scripts/observer/index.tsx" }, "stylelint": { "extends": [ @@ -89,6 +90,7 @@ ], "devDependencies": { "@babel/core": "^7.4.3", + "@babel/node": "^7.6.1", "@percy/storybook": "^3.0.2", "@shopify/jest-dom-mocks": "^2.1.1", "@shopify/react-testing": "^1.7.3", @@ -105,6 +107,7 @@ "@types/enzyme-adapter-react-16": "^1.0.5", "@types/lodash": "^4.14.108", "@types/node": "^11.13.8", + "@types/tinycolor2": "^1.4.2", "archiver": "^3.0.0", "babel-core": "7.0.0-bridge.0", "babel-loader": "^8.0.5", @@ -121,6 +124,7 @@ "glob": "^7.1.3", "gray-matter": "^4.0.2", "in-publish": "^2.0.0", + "ink": "^2.3.0", "isomorphic-fetch": "^2.2.1", "js-yaml": "^3.13.1", "marked": "^0.6.2", @@ -153,6 +157,7 @@ "shx": "^0.3.2", "storybook-chroma": "^2.1.1", "svgo": "^1.2.2", + "tinycolor2": "^1.4.1", "typescript": "~3.5.1", "yargs": "^13.2.2" }, diff --git a/scripts/observer/.eslintrc b/scripts/observer/.eslintrc new file mode 100644 index 00000000000..d2c6d2560a7 --- /dev/null +++ b/scripts/observer/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "jsx-a11y/accessible-emoji": "off" + } +} diff --git a/scripts/observer/README.md b/scripts/observer/README.md new file mode 100644 index 00000000000..af6b2d36594 --- /dev/null +++ b/scripts/observer/README.md @@ -0,0 +1,3 @@ +# `yarn observer` + +A command-line interface to observe the impact of a change across the component library. diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx new file mode 100644 index 00000000000..be0c11f2457 --- /dev/null +++ b/scripts/observer/index.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import tinycolor from 'tinycolor2'; +import tokens from '@shopify/polaris-tokens'; +import {Box, Text, render, Color} from 'ink'; + +const data = [ + { + path: 'src/components/Button/', + filename: 'Button.tsx', + componentsAffected: [ + {path: 'src/components/ButtonGroup/', filename: 'ButtonGroup.tsx'}, + {path: 'src/components/CalloutCard/', filename: 'CalloutCard.tsx'}, + {path: 'src/components/Caption/', filename: 'Caption.tsx'}, + {path: 'src/components/TopBar/', filename: 'TopBar.tsx'}, + ], + }, + { + path: 'src/components/Button/', + filename: 'Button.scss', + componentsAffected: [ + {path: 'src/components/ButtonGroup/', filename: 'ButtonGroup.tsx'}, + {path: 'src/components/Caption/', filename: 'Caption.tsx'}, + {path: 'src/components/Button/', filename: 'Button.tsx'}, + ], + }, + { + path: 'src/components/Checkbox/', + filename: 'Checkbox.tsx', + componentsAffected: [ + { + path: 'src/components/ContextualSaveBar/', + filename: 'ContextualSaveBar.tsx', + }, + { + path: 'src/components/EmptySearchResult/', + filename: 'EmptySearchResult.tsx', + }, + {path: 'src/components/Labelled/', filename: 'Labelled.tsx'}, + {path: 'src/components/Button/', filename: 'Button.tsx'}, + ], + }, +]; + +const Component = ({path, filename, componentsAffected}) => ( + + + {filename.endsWith('tsx') ? '🧩 ' : '💅 '} + + {path} + {filename} + + + Affected files: + {componentsAffected.map(({path, filename}) => ( + + + {path} + {filename} + + + ))} + +); + +const Components = ({components}) => ( + + {components.map(({path, filename, componentsAffected}) => ( + + ))} + +); + +const Summary = ({ + componentsModified, + componentsAffected, +}: { + componentsModified: number; + componentsAffected: number; +}) => ( + + + + Components modified: + + {componentsModified} + + + + Components affected: + + {componentsAffected} + + +); + +render( + + + 💡 tip: command + click file paths to open them in your text editor + + + [path, path + filename]), + ...data.reduce( + (val, curr) => + val.concat( + curr.componentsAffected.map(({path}) => [ + path, + curr.path + curr.filename, + ]), + ), + [], + ), + ]).size + } + /> + , +); diff --git a/yarn.lock b/yarn.lock index 1f49d2fce10..8d34be58a0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -284,6 +284,18 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/node@^7.6.1": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.6.1.tgz#84f8f4f1d86647d99537a681f32e65e70bb59f19" + integrity sha512-q2sJw+7aES/5wwjccECJfOuIgM1XIbZcn7b63JZM6VpaZwvOq913jL+tXRIn41Eg/Hr+BeIGWnvnjLTuT579pA== + dependencies: + "@babel/polyfill" "^7.6.0" + "@babel/register" "^7.6.0" + commander "^2.8.1" + lodash "^4.17.13" + node-environment-flags "^1.0.5" + v8flags "^3.1.1" + "@babel/parser@^7.0.0", "@babel/parser@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" @@ -802,6 +814,14 @@ core-js "^2.6.5" regenerator-runtime "^0.13.2" +"@babel/polyfill@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.6.0.tgz#6d89203f8b6cd323e8d946e47774ea35dc0619cc" + integrity sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.2" + "@babel/preset-env@7.4.3": version "7.4.3" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.3.tgz#e71e16e123dc0fbf65a52cbcbcefd072fbd02880" @@ -937,6 +957,17 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript" "^7.3.2" +"@babel/register@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.0.tgz#76b6f466714680f4becafd45beeb2a7b87431abf" + integrity sha512-78BomdN8el+x/nkup9KwtjJXuptW5oXMFmP11WoM2VJBjxrKv4grC3qjpLL8RGGUYUGsm57xnjYFM2uom+jWUQ== + dependencies: + find-cache-dir "^2.0.0" + lodash "^4.17.13" + mkdirp "^0.5.1" + pirates "^4.0.0" + source-map-support "^0.5.9" + "@babel/runtime@7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83" @@ -2382,6 +2413,14 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/react@^16.8.12", "@types/react@^16.8.6": + version "16.9.2" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.2.tgz#6d1765431a1ad1877979013906731aae373de268" + integrity sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -2399,6 +2438,11 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== +"@types/tinycolor2@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf" + integrity sha512-PeHg/AtdW6aaIO2a+98Xj7rWY4KC1E6yOy7AFknJQ7VXUGNrMlyxDFxJo7HqLtjQms/ZhhQX52mLVW/EX3JGOw== + "@types/uglify-js@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" @@ -3414,6 +3458,13 @@ atob@^2.1.1: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +auto-bind@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-2.1.0.tgz#254e12d53063d7cab90446ce021accfb3faa1464" + integrity sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg== + dependencies: + "@types/react" "^16.8.12" + autoprefixer@9.3.1: version "9.3.1" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.3.1.tgz#71b622174de2b783d5fd99f9ad617b7a3c78443e" @@ -4954,6 +5005,14 @@ cli-table3@0.5.1: optionalDependencies: colors "^1.1.2" +cli-truncate@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" + integrity sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA== + dependencies: + slice-ansi "^1.0.0" + string-width "^2.0.0" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -5160,7 +5219,7 @@ commander@^2.18.0, commander@~2.19.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== -commander@^2.19.0, commander@^2.9.0, commander@~2.20.0: +commander@^2.19.0, commander@^2.8.1, commander@^2.9.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -9432,6 +9491,30 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= +ink@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ink/-/ink-2.3.0.tgz#222136be17bb72fc742e19090483e7e0e7dc3690" + integrity sha512-931rgXHAS3hM++8ygWPOBeHOFwTzHh3pDAVZtiBVOUH6tVvJijym43ODUy22ySo2NwYUFeR/Zj3xuWzBEKMiHw== + dependencies: + "@types/react" "^16.8.6" + arrify "^1.0.1" + auto-bind "^2.0.0" + chalk "^2.4.1" + cli-cursor "^2.1.0" + cli-truncate "^1.1.0" + is-ci "^2.0.0" + lodash.throttle "^4.1.1" + log-update "^3.0.0" + prop-types "^15.6.2" + react-reconciler "^0.20.0" + scheduler "^0.13.2" + signal-exit "^3.0.2" + slice-ansi "^1.0.0" + string-length "^2.0.0" + widest-line "^2.0.0" + wrap-ansi "^5.0.0" + yoga-layout-prebuilt "^1.9.3" + inquirer@6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" @@ -11270,6 +11353,11 @@ lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, l resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== +lodash@^4.17.13: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + log-symbols@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -11277,6 +11365,15 @@ log-symbols@^2.0.0: dependencies: chalk "^2.0.1" +log-update@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-3.3.0.tgz#3b0501815123f66cb33f300e3dac2a2b6ad3fdf5" + integrity sha512-YSKm5n+YjZoGZT5lfmOqasVH1fIH9xQA9A81Y48nZ99PxAP62vdCCtua+Gcu6oTn0nqtZd/LwRV+Vflo53ZDWA== + dependencies: + ansi-escapes "^3.2.0" + cli-cursor "^2.1.0" + wrap-ansi "^5.0.0" + logalot@^2.0.0, logalot@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" @@ -12083,6 +12180,14 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" +node-environment-flags@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + node-fetch@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" @@ -13251,7 +13356,7 @@ pino@4.10.2: quick-format-unescaped "^1.1.1" split2 "^2.2.0" -pirates@^4.0.1: +pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== @@ -14540,7 +14645,7 @@ react-popper@^1.3.3: typed-styles "^0.0.7" warning "^4.0.2" -react-reconciler@^0.20.2: +react-reconciler@^0.20.0, react-reconciler@^0.20.2: version "0.20.4" resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.20.4.tgz#3da6a95841592f849cb4edd3d38676c86fd920b2" integrity sha512-kxERc4H32zV2lXMg/iMiwQHOtyqf15qojvkcZ5Ja2CPkjVohHw9k70pdDBwrnQhLVetUJBSYyqU3yqrlVTOajA== @@ -15518,7 +15623,7 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.13.6: +scheduler@^0.13.2, scheduler@^0.13.6: version "0.13.6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== @@ -15938,7 +16043,7 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== -slice-ansi@1.0.0: +slice-ansi@1.0.0, slice-ansi@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== @@ -17099,6 +17204,11 @@ tiny-emitter@^2.0.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + title-case@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" @@ -17718,6 +17828,13 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +v8flags@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8" + integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w== + dependencies: + homedir-polyfill "^1.0.1" + vali-date@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" @@ -18249,6 +18366,15 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrap-fn@^0.1.0: version "0.1.5" resolved "https://registry.yarnpkg.com/wrap-fn/-/wrap-fn-0.1.5.tgz#f21b6e41016ff4a7e31720dbc63a09016bdf9845" @@ -18535,6 +18661,11 @@ yauzl@^2.4.2: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" +yoga-layout-prebuilt@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.9.3.tgz#11e3be29096afe3c284e5d963cc2d628148c1372" + integrity sha512-9SNQpwuEh2NucU83i2KMZnONVudZ86YNcFk9tq74YaqrQfgJWO3yB9uzH1tAg8iqh5c9F5j0wuyJ2z72wcum2w== + zip-stream@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-2.0.1.tgz#48a062488afe91dda42f823700fae589753ccd34" From 44da583d6dec1fe153abc0c64bc0ce2de33b1df9 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 15:34:46 -0700 Subject: [PATCH 02/37] Load .ts files too --- package.json | 2 +- scripts/observer/index.tsx | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 375e603ff66..8ba0acf1b2a 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "version": "yarn run readme-update-version", "storybook": "start-storybook -p 6006 --quiet", "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static", - "observer": "babel-node --extensions '.tsx' ./scripts/observer/index.tsx" + "observer": "babel-node --extensions '.tsx, .ts' ./scripts/observer/index.tsx" }, "stylelint": { "extends": [ diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx index be0c11f2457..1357cacff30 100644 --- a/scripts/observer/index.tsx +++ b/scripts/observer/index.tsx @@ -1,7 +1,5 @@ import React from 'react'; -import tinycolor from 'tinycolor2'; -import tokens from '@shopify/polaris-tokens'; -import {Box, Text, render, Color} from 'ink'; +import {Box, Text, Color, render} from 'ink'; const data = [ { @@ -50,7 +48,7 @@ const Component = ({path, filename, componentsAffected}) => ( {filename} - Affected files: + Affected files: {componentsAffected.length} {componentsAffected.map(({path, filename}) => ( From 991217883d844a77b5a401451834d42727b65246 Mon Sep 17 00:00:00 2001 From: amrocha Date: Tue, 10 Sep 2019 18:26:52 -0700 Subject: [PATCH 03/37] Add graph script --- package.json | 7 +-- treebuilder.ts | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ yarn.lock | 12 ++++- 3 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 treebuilder.ts diff --git a/package.json b/package.json index 8ba0acf1b2a..3452c26ef86 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "version": "yarn run readme-update-version", "storybook": "start-storybook -p 6006 --quiet", "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static", - "observer": "babel-node --extensions '.tsx, .ts' ./scripts/observer/index.tsx" + "observer": "babel-node --extensions '.tsx' ./scripts/observer/index.tsx" }, "stylelint": { "extends": [ @@ -106,7 +106,7 @@ "@types/enzyme": "^3.10.3", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/lodash": "^4.14.108", - "@types/node": "^11.13.8", + "@types/node": "^12.7.4", "@types/tinycolor2": "^1.4.2", "archiver": "^3.0.0", "babel-core": "7.0.0-bridge.0", @@ -121,7 +121,7 @@ "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", "fs-extra": "^7.0.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "gray-matter": "^4.0.2", "in-publish": "^2.0.0", "ink": "^2.3.0", @@ -194,6 +194,7 @@ "@types/react-transition-group": "^2.0.7", "hoist-non-react-statics": "^3.3.0", "lodash": "^4.17.4", + "node-cmd": "^3.0.0", "tslib": "^1.9.3" } } diff --git a/treebuilder.ts b/treebuilder.ts new file mode 100644 index 00000000000..945f7703869 --- /dev/null +++ b/treebuilder.ts @@ -0,0 +1,143 @@ +import path from 'path'; +import * as ts from 'typescript'; +import glob from 'glob'; +import cmd from 'node-cmd'; + +type Node = { + fileName: string; + dependsOn: Node[]; + dependedOnBy: Node[]; +}; + +type GraphType = { + [name: string]: Node; +}; + +const graph: GraphType = {}; + +function compile(fileNames: string[], options: ts.CompilerOptions): void { + const program = ts.createProgram(fileNames, options); + + fileNames.map((fileName) => { + if (!graph[path.resolve(fileName)]) { + const ast: any = program.getSourceFile(fileName); + recurse({ + fileName: skipIndexFile(path.resolve(ast.originalFileName)), + dependsOn: [], + dependedOnBy: [], + }); + } + }); + + function recurse(node: Node) { + const ast: any = program.getSourceFile(node.fileName); + + if (ast && ast.resolvedModules) { + const dependencies = Array.from(ast.resolvedModules.entries()) + .map(([key, module]: any) => { + if (!module) { + return recurse({ + fileName: path.resolve( + ast.originalFileName.replace(/(.*\/)(.*)/, `$1${key}`), + ), + dependsOn: [], + dependedOnBy: [node], + }); + } + + if (module.isExternalLibraryImport) { + return undefined; + } + + const moduleFileName = module.resolvedFileName; + + let newNode; + if (graph[path.resolve(moduleFileName)]) { + newNode = graph[path.resolve(moduleFileName)]; + newNode.dependedOnBy.push(node); + } else { + newNode = recurse({ + fileName: skipIndexFile(moduleFileName), + dependsOn: [], + dependedOnBy: [node], + }); + } + return newNode; + }) + .filter((node) => node); + + node.dependsOn = dependencies; + } + + graph[path.resolve(node.fileName)] = node; + return node; + } + + function skipIndexFile(fileName) { + if (/(components\/)(\w*\/)?(index.ts)/.test(fileName)) { + const ast: any = program.getSourceFile(fileName); + return (Array.from(ast.resolvedModules.values())[0] as any) + .resolvedFileName; + } + return fileName; + } +} + +function findDependencies(fileName) { + const dependencies = {}; + recurse(graph[path.resolve(fileName)], 0); + + function recurse(node, depth) { + if (node.dependedOnBy) { + node.dependedOnBy.forEach((dependency) => { + dependencies[dependency.fileName] = 1; + recurse(dependency, depth + 1); + }); + } + } + + return Object.keys(dependencies).filter( + (dependency) => + dependency !== + '/Users/andrerocha/src/github.com/Shopify/polaris-react/src/components/index.ts', + ); +} + +export function getGitStagedFiles() { + return new Promise((resolve, reject) => { + cmd.get('git status --no-renames -s', (err, data, stderr) => { + if (err) { + reject(err); + return; + } + + resolve( + data + .split('\n') + .filter( + (datum) => + ['M', 'A'].includes(datum[0]) || ['M', 'A'].includes(datum[1]), + ) + .map((datum) => datum.slice(3)), + ); + }); + }); +} + +export function getDependencies(codebaseGlob, ignoreGlob, fileGlobs) { + const codebase = glob.sync(codebaseGlob, { + ignore: ignoreGlob, + }); + + compile(codebase, { + noEmitOnError: true, + noImplicitAny: true, + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + }); + + return fileGlobs + .map((fileGlob) => glob.sync(fileGlob)) + .reduce((accumulator, current) => [...accumulator, ...current], []) + .map(findDependencies); +} diff --git a/yarn.lock b/yarn.lock index 8d34be58a0d..20f630869d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2374,11 +2374,16 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*", "@types/node@^11.13.5", "@types/node@^11.13.8": +"@types/node@*", "@types/node@^11.13.5": version "11.13.8" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.8.tgz#e5d71173c95533be9842b2c798978f095f912aab" integrity sha512-szA3x/3miL90ZJxUCzx9haNbK5/zmPieGraZEe4WI+3srN0eGLiT22NXeMHmyhNEopn+IrxqMc7wdVwvPl8meg== +"@types/node@^12.7.4": + version "12.7.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" + integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== + "@types/prop-types@*": version "15.5.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.5.tgz#17038dd322c2325f5da650a94d5f9974943625e3" @@ -12173,6 +12178,11 @@ node-ask@^1.0.1: resolved "https://registry.yarnpkg.com/node-ask/-/node-ask-1.0.1.tgz#caaa1076cc58e0364267a0903e3eadfac158396b" integrity sha1-yqoQdsxY4DZCZ6CQPj6t+sFYOWs= +node-cmd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/node-cmd/-/node-cmd-3.0.0.tgz#38fff70a4aaa4f659d203eb57862737018e24f6f" + integrity sha1-OP/3CkqqT2WdID61eGJzcBjiT28= + node-dir@^0.1.10: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" From 9d511bab52aa5c19d641ca8a6ea5037a79ce1467 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 20:29:37 -0700 Subject: [PATCH 04/37] Enable compilation of .ts files --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3452c26ef86..8601e537786 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "version": "yarn run readme-update-version", "storybook": "start-storybook -p 6006 --quiet", "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static", - "observer": "babel-node --extensions '.tsx' ./scripts/observer/index.tsx" + "observer": "babel-node --extensions '.tsx','.ts' ./scripts/observer/index.tsx" }, "stylelint": { "extends": [ From 3adc842acb69413c6d8259d794cfd2883bc8f6aa Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 20:29:58 -0700 Subject: [PATCH 05/37] Remove tinycolor2 dependency --- package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/package.json b/package.json index 8601e537786..1fcdd1bd153 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,6 @@ "shx": "^0.3.2", "storybook-chroma": "^2.1.1", "svgo": "^1.2.2", - "tinycolor2": "^1.4.1", "typescript": "~3.5.1", "yargs": "^13.2.2" }, diff --git a/yarn.lock b/yarn.lock index 20f630869d2..8089f473b8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17214,11 +17214,6 @@ tiny-emitter@^2.0.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== -tinycolor2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" - integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= - title-case@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" From a9da56e449d02bdd925a83c556ed0f62500fb8b1 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 20:32:51 -0700 Subject: [PATCH 06/37] Make filter more portable across environments --- treebuilder.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index 945f7703869..5dfd547b854 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -96,10 +96,8 @@ function findDependencies(fileName) { } } - return Object.keys(dependencies).filter( - (dependency) => - dependency !== - '/Users/andrerocha/src/github.com/Shopify/polaris-react/src/components/index.ts', + return Object.keys(dependencies).filter((dependency) => + dependency.endsWith('src/components/index.ts'), ); } From be171511d907843fdd3b427b8aa5154b33fa97e4 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 20:33:32 -0700 Subject: [PATCH 07/37] Add scoping to getGitStagedFiles --- treebuilder.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index 5dfd547b854..2a5eda9199f 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -101,7 +101,7 @@ function findDependencies(fileName) { ); } -export function getGitStagedFiles() { +export function getGitStagedFiles(scope = '') { return new Promise((resolve, reject) => { cmd.get('git status --no-renames -s', (err, data, stderr) => { if (err) { @@ -116,7 +116,8 @@ export function getGitStagedFiles() { (datum) => ['M', 'A'].includes(datum[0]) || ['M', 'A'].includes(datum[1]), ) - .map((datum) => datum.slice(3)), + .map((datum) => datum.slice(3)) + .filter((filepath) => filepath.startsWith(scope)), ); }); }); From b0c05033451398ad50e5820acad3ae8ee19f272c Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 20:35:38 -0700 Subject: [PATCH 08/37] Try to use functions from treebuilder.ts --- scripts/observer/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx index 1357cacff30..bbc1364f6d1 100644 --- a/scripts/observer/index.tsx +++ b/scripts/observer/index.tsx @@ -1,5 +1,13 @@ import React from 'react'; import {Box, Text, Color, render} from 'ink'; +import {getGitStagedFiles, getDependencies} from '../../treebuilder'; + +(async function() { + const stagedFiles = await getGitStagedFiles('src/'); + console.log(stagedFiles); + const data = await getDependencies(/* how do I use this function? */); + console.log(data); +})(); const data = [ { From 90801fffc8600c525f3c9099ed832698f87c1270 Mon Sep 17 00:00:00 2001 From: amrocha Date: Tue, 10 Sep 2019 21:03:57 -0700 Subject: [PATCH 09/37] Add types --- treebuilder.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index 2a5eda9199f..511bc8a4f0f 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -123,7 +123,11 @@ export function getGitStagedFiles(scope = '') { }); } -export function getDependencies(codebaseGlob, ignoreGlob, fileGlobs) { +export function getDependencies( + codebaseGlob: string, + ignoreGlob: string, + fileGlobs: string[], +) { const codebase = glob.sync(codebaseGlob, { ignore: ignoreGlob, }); @@ -138,5 +142,16 @@ export function getDependencies(codebaseGlob, ignoreGlob, fileGlobs) { return fileGlobs .map((fileGlob) => glob.sync(fileGlob)) .reduce((accumulator, current) => [...accumulator, ...current], []) - .map(findDependencies); + .map(findDependencies) + .reduce( + (accumulator, currentArray) => [...accumulator, ...currentArray], + [], + ); } + +// console.log( +// getDependencies('src/**/*.tsx', 'src/**/*.test.tsx', [ +// 'src/components/Button/Button.tsx', +// 'src/components/Avatar/Avatar.tsx', +// ]), +// ); From 5fde385c98db4e20cab61365adff98dc0b513d81 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 21:25:12 -0700 Subject: [PATCH 10/37] Fix filter --- scripts/observer/index.tsx | 8 ++++++-- treebuilder.ts | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx index bbc1364f6d1..cecd40e5624 100644 --- a/scripts/observer/index.tsx +++ b/scripts/observer/index.tsx @@ -3,9 +3,13 @@ import {Box, Text, Color, render} from 'ink'; import {getGitStagedFiles, getDependencies} from '../../treebuilder'; (async function() { - const stagedFiles = await getGitStagedFiles('src/'); + const stagedFiles = (await getGitStagedFiles('src/')) as string[]; console.log(stagedFiles); - const data = await getDependencies(/* how do I use this function? */); + const data = await getDependencies( + 'src/**/*.tsx', + 'src/**/*.test.tsx,src/**/index.ts', + stagedFiles, + ); console.log(data); })(); diff --git a/treebuilder.ts b/treebuilder.ts index 511bc8a4f0f..0746dcd9ad0 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -96,8 +96,8 @@ function findDependencies(fileName) { } } - return Object.keys(dependencies).filter((dependency) => - dependency.endsWith('src/components/index.ts'), + return Object.keys(dependencies).filter( + (dependency) => !dependency.endsWith('src/components/index.ts'), ); } From acd9c2e89507a87bcb9a7dd125053668f496a0a8 Mon Sep 17 00:00:00 2001 From: amrocha Date: Tue, 10 Sep 2019 21:30:04 -0700 Subject: [PATCH 11/37] Formatting --- treebuilder.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index 0746dcd9ad0..ccc7a22cfbb 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -88,7 +88,7 @@ function findDependencies(fileName) { recurse(graph[path.resolve(fileName)], 0); function recurse(node, depth) { - if (node.dependedOnBy) { + if (node && node.dependedOnBy) { node.dependedOnBy.forEach((dependency) => { dependencies[dependency.fileName] = 1; recurse(dependency, depth + 1); @@ -139,19 +139,22 @@ export function getDependencies( module: ts.ModuleKind.CommonJS, }); - return fileGlobs + const dependencies = fileGlobs .map((fileGlob) => glob.sync(fileGlob)) .reduce((accumulator, current) => [...accumulator, ...current], []) - .map(findDependencies) - .reduce( - (accumulator, currentArray) => [...accumulator, ...currentArray], - [], - ); + .map(findDependencies); + + return fileGlobs.map((fileGlob, index) => ({ + fileName: fileGlob, + dependencies: dependencies[index], + })); } // console.log( -// getDependencies('src/**/*.tsx', 'src/**/*.test.tsx', [ +// getDependencies('src/***/*.tsx', 'src/***/*.test.tsx', [ // 'src/components/Button/Button.tsx', // 'src/components/Avatar/Avatar.tsx', // ]), // ); + +// debugger; From 370d844222d02bbb7996bde952bee6b341700100 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 22:59:50 -0700 Subject: [PATCH 12/37] Remove absolute part of the path --- treebuilder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index ccc7a22cfbb..7cec9f824ca 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -96,9 +96,9 @@ function findDependencies(fileName) { } } - return Object.keys(dependencies).filter( - (dependency) => !dependency.endsWith('src/components/index.ts'), - ); + return Object.keys(dependencies) + .filter((dependency) => !dependency.endsWith('/src/components/index.ts')) + .map((dependency) => dependency.split('polaris-react/')[1]); } export function getGitStagedFiles(scope = '') { From 8cb411355b96252243d1367969ff3d03bc353724 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Tue, 10 Sep 2019 23:00:22 -0700 Subject: [PATCH 13/37] Plug data from git status and improve listing --- scripts/observer/.eslintrc | 3 +- scripts/observer/index.tsx | 185 +++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 90 deletions(-) diff --git a/scripts/observer/.eslintrc b/scripts/observer/.eslintrc index d2c6d2560a7..935cfee4dc6 100644 --- a/scripts/observer/.eslintrc +++ b/scripts/observer/.eslintrc @@ -1,5 +1,6 @@ { "rules": { - "jsx-a11y/accessible-emoji": "off" + "jsx-a11y/accessible-emoji": "off", + "shopify/jsx-no-hardcoded-content": "off" } } diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx index cecd40e5624..def77b93a72 100644 --- a/scripts/observer/index.tsx +++ b/scripts/observer/index.tsx @@ -1,68 +1,56 @@ -import React from 'react'; +import path from 'path'; +import React, {useState, useEffect} from 'react'; import {Box, Text, Color, render} from 'ink'; +import sortBy from 'lodash/sortBy'; import {getGitStagedFiles, getDependencies} from '../../treebuilder'; -(async function() { - const stagedFiles = (await getGitStagedFiles('src/')) as string[]; - console.log(stagedFiles); - const data = await getDependencies( - 'src/**/*.tsx', - 'src/**/*.test.tsx,src/**/index.ts', - stagedFiles, - ); - console.log(data); -})(); +const excludedFileNames = (fileName) => + !fileName.includes('test') && + !fileName.includes('types') && + !fileName.endsWith('index.ts') && + !fileName.endsWith('utils.tsx'); -const data = [ - { - path: 'src/components/Button/', - filename: 'Button.tsx', - componentsAffected: [ - {path: 'src/components/ButtonGroup/', filename: 'ButtonGroup.tsx'}, - {path: 'src/components/CalloutCard/', filename: 'CalloutCard.tsx'}, - {path: 'src/components/Caption/', filename: 'Caption.tsx'}, - {path: 'src/components/TopBar/', filename: 'TopBar.tsx'}, - ], - }, - { - path: 'src/components/Button/', - filename: 'Button.scss', - componentsAffected: [ - {path: 'src/components/ButtonGroup/', filename: 'ButtonGroup.tsx'}, - {path: 'src/components/Caption/', filename: 'Caption.tsx'}, - {path: 'src/components/Button/', filename: 'Button.tsx'}, - ], - }, - { - path: 'src/components/Checkbox/', - filename: 'Checkbox.tsx', - componentsAffected: [ - { - path: 'src/components/ContextualSaveBar/', - filename: 'ContextualSaveBar.tsx', - }, - { - path: 'src/components/EmptySearchResult/', - filename: 'EmptySearchResult.tsx', - }, - {path: 'src/components/Labelled/', filename: 'Labelled.tsx'}, - {path: 'src/components/Button/', filename: 'Button.tsx'}, - ], - }, -]; +const formatDependencies = (dependencies) => + dependencies + .filter(({fileName}) => excludedFileNames(fileName)) + .map((dependency) => ({ + path: `${path.dirname(dependency.fileName)}/`, + filename: path.basename(dependency.fileName), + dependencies: sortBy( + dependency.dependencies.filter(excludedFileNames).map((dependency) => ({ + path: `${path.dirname(dependency)}/`, + filename: path.basename(dependency), + componentName: path + .dirname(dependency) + .replace('src/components/', '') + .split('/')[0], + })), + ['path', 'filename'], + ), + })); -const Component = ({path, filename, componentsAffected}) => ( +const Component = ({path, filename, dependencies}) => ( {filename.endsWith('tsx') ? '🧩 ' : '💅 '} - - {path} - {filename} + + + {path} + {filename} + - Affected files: {componentsAffected.length} - {componentsAffected.map(({path, filename}) => ( + + Component name + File potentially affected (total: {dependencies.length}) + + {dependencies.map(({path, filename, componentName}) => ( + + {'<'} + {componentName} + {' />'} + {path} {filename} @@ -74,12 +62,12 @@ const Component = ({path, filename, componentsAffected}) => ( const Components = ({components}) => ( - {components.map(({path, filename, componentsAffected}) => ( + {components.map(({path, filename, dependencies}) => ( ))} @@ -87,50 +75,69 @@ const Components = ({components}) => ( const Summary = ({ componentsModified, - componentsAffected, + dependencies, }: { componentsModified: number; - componentsAffected: number; + dependencies: number; }) => ( - - Components modified: + + Files modified: {componentsModified} - - Components affected: + + Files potentially affected: - {componentsAffected} + {dependencies} ); -render( - - - 💡 tip: command + click file paths to open them in your text editor - - - [path, path + filename]), - ...data.reduce( - (val, curr) => - val.concat( - curr.componentsAffected.map(({path}) => [ - path, - curr.path + curr.filename, - ]), - ), - [], - ), - ]).size - } - /> - , -); +const App = () => { + const [data, setData] = useState([]); + + useEffect(() => { + const fetchData = async () => { + const stagedFiles = (await getGitStagedFiles('src/')) as string[]; + const dependencies = await getDependencies( + 'src/**/*.tsx', + '*.test.tsx', + stagedFiles, + ); + setData(formatDependencies(dependencies)); + }; + fetchData(); + }, []); + + return ( + + + 💡 tip: command + click file paths to open them in your text editor + + + [path, path + filename]), + ...data.reduce( + (val, curr) => + val.concat( + curr.dependencies.map(({path}) => [ + path, + curr.path + curr.filename, + ]), + ), + [], + ), + ]).size + } + /> + + ); +}; + +render(); From f7bfb820ec3cff589e71df16f66e87c0b384ed1c Mon Sep 17 00:00:00 2001 From: Kaelig Date: Wed, 11 Sep 2019 23:22:09 -0700 Subject: [PATCH 14/37] Rename script to yarn splash, add watcher mode --- package.json | 2 +- scripts/observer/README.md | 3 - scripts/observer/index.tsx | 143 ----------------- scripts/{observer => splash}/.eslintrc | 0 scripts/splash/README.md | 3 + scripts/splash/index.tsx | 207 +++++++++++++++++++++++++ treebuilder.ts | 2 +- 7 files changed, 212 insertions(+), 148 deletions(-) delete mode 100644 scripts/observer/README.md delete mode 100644 scripts/observer/index.tsx rename scripts/{observer => splash}/.eslintrc (100%) create mode 100644 scripts/splash/README.md create mode 100644 scripts/splash/index.tsx diff --git a/package.json b/package.json index 1fcdd1bd153..18baa0d459c 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "version": "yarn run readme-update-version", "storybook": "start-storybook -p 6006 --quiet", "storybook:build": "yarn run copy-polaris-tokens && build-storybook -o build/storybook/static", - "observer": "babel-node --extensions '.tsx','.ts' ./scripts/observer/index.tsx" + "splash": "babel-node --extensions '.tsx','.ts' ./scripts/splash/index.tsx" }, "stylelint": { "extends": [ diff --git a/scripts/observer/README.md b/scripts/observer/README.md deleted file mode 100644 index af6b2d36594..00000000000 --- a/scripts/observer/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `yarn observer` - -A command-line interface to observe the impact of a change across the component library. diff --git a/scripts/observer/index.tsx b/scripts/observer/index.tsx deleted file mode 100644 index def77b93a72..00000000000 --- a/scripts/observer/index.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import path from 'path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text, Color, render} from 'ink'; -import sortBy from 'lodash/sortBy'; -import {getGitStagedFiles, getDependencies} from '../../treebuilder'; - -const excludedFileNames = (fileName) => - !fileName.includes('test') && - !fileName.includes('types') && - !fileName.endsWith('index.ts') && - !fileName.endsWith('utils.tsx'); - -const formatDependencies = (dependencies) => - dependencies - .filter(({fileName}) => excludedFileNames(fileName)) - .map((dependency) => ({ - path: `${path.dirname(dependency.fileName)}/`, - filename: path.basename(dependency.fileName), - dependencies: sortBy( - dependency.dependencies.filter(excludedFileNames).map((dependency) => ({ - path: `${path.dirname(dependency)}/`, - filename: path.basename(dependency), - componentName: path - .dirname(dependency) - .replace('src/components/', '') - .split('/')[0], - })), - ['path', 'filename'], - ), - })); - -const Component = ({path, filename, dependencies}) => ( - - - {filename.endsWith('tsx') ? '🧩 ' : '💅 '} - - - {path} - {filename} - - - - - Component name - File potentially affected (total: {dependencies.length}) - - {dependencies.map(({path, filename, componentName}) => ( - - - {'<'} - {componentName} - {' />'} - - - {path} - {filename} - - - ))} - -); - -const Components = ({components}) => ( - - {components.map(({path, filename, dependencies}) => ( - - ))} - -); - -const Summary = ({ - componentsModified, - dependencies, -}: { - componentsModified: number; - dependencies: number; -}) => ( - - - - Files modified: - - {componentsModified} - - - - Files potentially affected: - - {dependencies} - - -); - -const App = () => { - const [data, setData] = useState([]); - - useEffect(() => { - const fetchData = async () => { - const stagedFiles = (await getGitStagedFiles('src/')) as string[]; - const dependencies = await getDependencies( - 'src/**/*.tsx', - '*.test.tsx', - stagedFiles, - ); - setData(formatDependencies(dependencies)); - }; - fetchData(); - }, []); - - return ( - - - 💡 tip: command + click file paths to open them in your text editor - - - [path, path + filename]), - ...data.reduce( - (val, curr) => - val.concat( - curr.dependencies.map(({path}) => [ - path, - curr.path + curr.filename, - ]), - ), - [], - ), - ]).size - } - /> - - ); -}; - -render(); diff --git a/scripts/observer/.eslintrc b/scripts/splash/.eslintrc similarity index 100% rename from scripts/observer/.eslintrc rename to scripts/splash/.eslintrc diff --git a/scripts/splash/README.md b/scripts/splash/README.md new file mode 100644 index 00000000000..4adf37becec --- /dev/null +++ b/scripts/splash/README.md @@ -0,0 +1,3 @@ +# `yarn splash` + +A command-line interface to observe the splash zone of a change across the component library. diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx new file mode 100644 index 00000000000..abe27c6e7be --- /dev/null +++ b/scripts/splash/index.tsx @@ -0,0 +1,207 @@ +import path from 'path'; +import React, {useState, useEffect} from 'react'; +import {Box, Text, Color, render} from 'ink'; +import sortBy from 'lodash/sortBy'; +import {argv} from 'yargs'; +import {getGitStagedFiles, getDependencies} from '../../treebuilder'; + +const excludedFileNames = (fileName) => + !fileName.includes('test') && + !fileName.includes('types') && + !fileName.endsWith('index.ts') && + !fileName.endsWith('utils.tsx'); + +const getEmojiForExtension = (extension) => { + switch (extension) { + case '.tsx': + return '🧩'; + case '.scss': + return '🎨'; + default: + return '❔'; + } +}; +const formatDependencies = (dependencies) => + dependencies + .filter(({fileName}) => excludedFileNames(fileName)) + .map((dependency) => ({ + pathname: `${path.dirname(dependency.fileName)}/`, + filename: path.basename(dependency.fileName), + dependencies: sortBy( + dependency.dependencies.filter(excludedFileNames).map((dependency) => ({ + pathname: `${path.dirname(dependency)}/`, + filename: path.basename(dependency), + componentName: path + .dirname(dependency) + .replace('src/components/', '') + .split('/')[0], + })), + ['pathname', 'filename'], + ), + })); + +const Component = ({pathname, filename, dependencies}) => ( + + + {getEmojiForExtension(path.extname(filename))} + + + {pathname} + {filename} + + + + + Component name + Files potentially affected (total: {dependencies.length}) + + {dependencies.map(({pathname, filename, componentName}) => ( + + + {'<'} + {componentName} + {' />'} + + + {pathname} + {filename} + + + ))} + +); + +const Components = ({components, status}) => ( + + {status === 'loading' && ( + + ⏳{' '}Please wait during compilation… Beep boop beep 🤖 + + )} + + {status === 'loaded' && + components.map(({pathname, filename, dependencies}) => ( + + ))} + +); + +const Summary = ({ + componentsModified, + dependencies, +}: { + componentsModified: number; + dependencies: number; +}) => ( + + + + Files modified: + + + {componentsModified} + + + + + Files potentially affected: + + + {dependencies > -1 ? dependencies : '⏳'} + + + +); + +const App = () => { + const [stagedFiles, setStagedFiles] = useState([]); + const [data, setData] = useState([]); + const [dataStatus, setDataStatus] = useState('loading'); + + const getStagedFiles = async () => { + const staged = (await getGitStagedFiles('src/')) as string[]; + setStagedFiles(staged); + if (staged.length === 0) { + setDataStatus('loaded'); + } + }; + + useEffect(() => { + if (!argv.watch) { + getStagedFiles(); + } + }, []); + // ^ empty dependency array = exits after one run + + useEffect(() => { + if (argv.watch) { + getStagedFiles(); + } + }); + // ^ no dependencies = keeps watching + + useEffect(() => { + if (stagedFiles.length > 0) { + const dependencies = getDependencies( + 'src/**/*.tsx', + '*.test.tsx', + stagedFiles, + ); + setData(formatDependencies(dependencies)); + setDataStatus('loaded'); + } + }, [setData, stagedFiles]); + + return ( + + + + 💦 + + yarn splash: Observe the splash zone of a change + across the entire library + + + + + [ + pathname, + pathname + filename, + ]), + ...data.reduce( + (val, curr) => + val.concat( + curr.dependencies.map(({pathname}) => [ + pathname, + curr.pathname + curr.filename, + ]), + ), + [], + ), + ]).size + } + /> + + + 💡 + + tip: command + click a file path to open it in your text editor + + + + + ); +}; + +render(); diff --git a/treebuilder.ts b/treebuilder.ts index 7cec9f824ca..ce5753c2e80 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -103,7 +103,7 @@ function findDependencies(fileName) { export function getGitStagedFiles(scope = '') { return new Promise((resolve, reject) => { - cmd.get('git status --no-renames -s', (err, data, stderr) => { + cmd.get('git status --porcelain', (err, data, stderr) => { if (err) { reject(err); return; From 61b233e08880a31ae38d891be62854f81750a188 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Wed, 11 Sep 2019 23:25:34 -0700 Subject: [PATCH 15/37] Align summary text to the right --- scripts/splash/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index abe27c6e7be..0e420d5f9ad 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -103,7 +103,7 @@ const Summary = ({ Files modified: - + {componentsModified} @@ -111,7 +111,7 @@ const Summary = ({ Files potentially affected: - + {dependencies > -1 ? dependencies : '⏳'} From e50011ab5dcc29bf05577e1f995d836fd5590696 Mon Sep 17 00:00:00 2001 From: amrocha Date: Thu, 12 Sep 2019 09:56:31 -0700 Subject: [PATCH 16/37] Change filtering --- treebuilder.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/treebuilder.ts b/treebuilder.ts index ce5753c2e80..a4bbaaa023a 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -22,7 +22,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions): void { if (!graph[path.resolve(fileName)]) { const ast: any = program.getSourceFile(fileName); recurse({ - fileName: skipIndexFile(path.resolve(ast.originalFileName)), + fileName: path.resolve(ast.originalFileName), dependsOn: [], dependedOnBy: [], }); @@ -57,7 +57,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions): void { newNode.dependedOnBy.push(node); } else { newNode = recurse({ - fileName: skipIndexFile(moduleFileName), + fileName: moduleFileName, dependsOn: [], dependedOnBy: [node], }); @@ -97,7 +97,9 @@ function findDependencies(fileName) { } return Object.keys(dependencies) - .filter((dependency) => !dependency.endsWith('/src/components/index.ts')) + .filter( + (dependency) => !/(components\/)(\w*\/)?(index.ts)/.test(dependency), + ) .map((dependency) => dependency.split('polaris-react/')[1]); } @@ -151,10 +153,9 @@ export function getDependencies( } // console.log( -// getDependencies('src/***/*.tsx', 'src/***/*.test.tsx', [ +// getDependencies('src/**/*.tsx', 'src/**/*.test.tsx', [ // 'src/components/Button/Button.tsx', // 'src/components/Avatar/Avatar.tsx', // ]), // ); - // debugger; From 204bb6049d5bbb4849e50fb52bad3219ce3bfb97 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 09:58:51 -0700 Subject: [PATCH 17/37] Add temporary workaround to the skipIndexFile function --- treebuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/treebuilder.ts b/treebuilder.ts index ce5753c2e80..4d6503037d0 100644 --- a/treebuilder.ts +++ b/treebuilder.ts @@ -74,7 +74,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions): void { } function skipIndexFile(fileName) { - if (/(components\/)(\w*\/)?(index.ts)/.test(fileName)) { + if (/(components\/)(\w*\/)?(index.tsFIXME)/.test(fileName)) { const ast: any = program.getSourceFile(fileName); return (Array.from(ast.resolvedModules.values())[0] as any) .resolvedFileName; From 7ce1a5eb4faf9a7d4f7fd60b8ec9aa3889aac2b6 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 10:00:24 -0700 Subject: [PATCH 18/37] Move treebuilder.ts to scripts/splash --- scripts/splash/index.tsx | 2 +- treebuilder.ts => scripts/splash/treebuilder.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename treebuilder.ts => scripts/splash/treebuilder.ts (100%) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 0e420d5f9ad..157db2f03b5 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -3,7 +3,7 @@ import React, {useState, useEffect} from 'react'; import {Box, Text, Color, render} from 'ink'; import sortBy from 'lodash/sortBy'; import {argv} from 'yargs'; -import {getGitStagedFiles, getDependencies} from '../../treebuilder'; +import {getGitStagedFiles, getDependencies} from './treebuilder'; const excludedFileNames = (fileName) => !fileName.includes('test') && diff --git a/treebuilder.ts b/scripts/splash/treebuilder.ts similarity index 100% rename from treebuilder.ts rename to scripts/splash/treebuilder.ts From 7493e70697c529309c797f3c8d0fe19b4ca1c5aa Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 10:01:58 -0700 Subject: [PATCH 19/37] Remove skipIndexFile --- scripts/splash/treebuilder.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/splash/treebuilder.ts b/scripts/splash/treebuilder.ts index c453349de6d..b2c87a3147e 100644 --- a/scripts/splash/treebuilder.ts +++ b/scripts/splash/treebuilder.ts @@ -72,15 +72,6 @@ function compile(fileNames: string[], options: ts.CompilerOptions): void { graph[path.resolve(node.fileName)] = node; return node; } - - function skipIndexFile(fileName) { - if (/(components\/)(\w*\/)?(index.tsFIXME)/.test(fileName)) { - const ast: any = program.getSourceFile(fileName); - return (Array.from(ast.resolvedModules.values())[0] as any) - .resolvedFileName; - } - return fileName; - } } function findDependencies(fileName) { From fb5019ba300d0dce0b29e5e1e795d9e9945b0e6e Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 10:54:49 -0700 Subject: [PATCH 20/37] Add docs --- scripts/splash/README.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/scripts/splash/README.md b/scripts/splash/README.md index 4adf37becec..c49d841efd3 100644 --- a/scripts/splash/README.md +++ b/scripts/splash/README.md @@ -1,3 +1,23 @@ -# `yarn splash` +# `yarn splash` (beta) -A command-line interface to observe the splash zone of a change across the component library. +`yarn splash` is a command-line interface to observe the splash zone of a change across the component library. + +It answers the question: + +> When I modify a component, what parts of the system did that also touch (also known as the change’s “splash zone”)? + +## How to use `yarn splash` + +1. Edit files in `src/`, such as components 🧩 and style sheets 🎨 +2. Run `yarn splash` to see the splash zone of your changes in the working directory + +## Tips + +- command + click a file path to open it in your text editor +- `yarn splash --watch` continuously looks for changes in the working directory and updates the list of impacted files in real-time + +## Feedback and bug reports + +Found an issue or want to share feedback? + +Reach out on Slack in [#polaris-tooling](https://shopify.slack.com/messages/CCNUS0FML). From 0db5a4b88f797948772f494d557a75367cc4114b Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 10:57:29 -0700 Subject: [PATCH 21/37] Add changelog item --- UNRELEASED.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UNRELEASED.md b/UNRELEASED.md index 88bad639c56..cd982fd7965 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -18,6 +18,8 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f ### Development workflow +- Added [`yarn splash` (beta)](/scripts/splash/), a command-line interface to observe the splash zone of a change across the component library ([#2113](https://github.com/Shopify/polaris-react/pull/2113)) + ### Dependency upgrades ### Code quality From 230d07c0c9c43b80a303f34bb414c12ae87762fa Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 11:01:54 -0700 Subject: [PATCH 22/37] Add mention that the watcher is still alpha --- scripts/splash/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/splash/README.md b/scripts/splash/README.md index c49d841efd3..cc25f41f734 100644 --- a/scripts/splash/README.md +++ b/scripts/splash/README.md @@ -14,7 +14,7 @@ It answers the question: ## Tips - command + click a file path to open it in your text editor -- `yarn splash --watch` continuously looks for changes in the working directory and updates the list of impacted files in real-time +- `yarn splash --watch` continuously looks for changes in the working directory and updates the list of impacted files in real-time (alpha: you may need to hit ctrl + c multiple times to exit) ## Feedback and bug reports From 961e3aec9ee359f014ec20c2e9d253c33210e62a Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 11:05:10 -0700 Subject: [PATCH 23/37] Remove unused type dependency --- package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/package.json b/package.json index 2c7bcfcca6d..2b2f2d97115 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,6 @@ "@types/enzyme-adapter-react-16": "^1.0.5", "@types/lodash": "^4.14.108", "@types/node": "^12.7.4", - "@types/tinycolor2": "^1.4.2", "archiver": "^3.0.0", "babel-core": "7.0.0-bridge.0", "babel-loader": "^8.0.5", diff --git a/yarn.lock b/yarn.lock index 5fa8d5fe900..b55ed65170d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2443,11 +2443,6 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== -"@types/tinycolor2@^1.4.2": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf" - integrity sha512-PeHg/AtdW6aaIO2a+98Xj7rWY4KC1E6yOy7AFknJQ7VXUGNrMlyxDFxJo7HqLtjQms/ZhhQX52mLVW/EX3JGOw== - "@types/uglify-js@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" From 4028392cb301f1cf93160c3b8c23317bc0907c04 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 11:05:46 -0700 Subject: [PATCH 24/37] Add missing space --- scripts/splash/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 157db2f03b5..cd5bf26603c 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -21,6 +21,7 @@ const getEmojiForExtension = (extension) => { return '❔'; } }; + const formatDependencies = (dependencies) => dependencies .filter(({fileName}) => excludedFileNames(fileName)) From af429e9b912e0c3aa25810ce27ea3de80589264b Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 11:06:24 -0700 Subject: [PATCH 25/37] Add missing space --- scripts/splash/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index cd5bf26603c..a845d0c9c95 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -127,6 +127,7 @@ const App = () => { const getStagedFiles = async () => { const staged = (await getGitStagedFiles('src/')) as string[]; setStagedFiles(staged); + if (staged.length === 0) { setDataStatus('loaded'); } From f397782921884eb7b5b76e05b76059a66da1325e Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 12:55:39 -0700 Subject: [PATCH 26/37] Verifies the index file is in a component folder --- scripts/splash/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index a845d0c9c95..54a43ed4da0 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -8,7 +8,7 @@ import {getGitStagedFiles, getDependencies} from './treebuilder'; const excludedFileNames = (fileName) => !fileName.includes('test') && !fileName.includes('types') && - !fileName.endsWith('index.ts') && + !/(components\/)(\w*\/)?(index.ts)/.test(fileName) && !fileName.endsWith('utils.tsx'); const getEmojiForExtension = (extension) => { From 9d1873cad97f05fd1000813eb817349edc19a79e Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 12:57:21 -0700 Subject: [PATCH 27/37] Account for .ts files --- scripts/splash/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 54a43ed4da0..d46c47576d6 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -14,6 +14,7 @@ const excludedFileNames = (fileName) => const getEmojiForExtension = (extension) => { switch (extension) { case '.tsx': + case '.ts': return '🧩'; case '.scss': return '🎨'; From 9b081de3137a8346c83efcd47a4d793344f650b2 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 13:00:58 -0700 Subject: [PATCH 28/37] Show utils.tsx files again --- scripts/splash/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index d46c47576d6..cc8a023f08d 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -8,8 +8,7 @@ import {getGitStagedFiles, getDependencies} from './treebuilder'; const excludedFileNames = (fileName) => !fileName.includes('test') && !fileName.includes('types') && - !/(components\/)(\w*\/)?(index.ts)/.test(fileName) && - !fileName.endsWith('utils.tsx'); + !/(components\/)(\w*\/)?(index.ts)/.test(fileName); const getEmojiForExtension = (extension) => { switch (extension) { From 3502aef410e390ac3dec33f2ce97a8ca4d128e38 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 13:08:14 -0700 Subject: [PATCH 29/37] Handle loading status properly --- scripts/splash/index.tsx | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index cc8a023f08d..a7305a57a65 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -95,9 +95,11 @@ const Components = ({components, status}) => ( const Summary = ({ componentsModified, dependencies, + status, }: { componentsModified: number; dependencies: number; + status: string; }) => ( @@ -113,7 +115,7 @@ const Summary = ({ Files potentially affected: - {dependencies > -1 ? dependencies : '⏳'} + {status === 'loading' ? '⏳' : dependencies} @@ -173,25 +175,24 @@ const App = () => { [ - pathname, - pathname + filename, - ]), - ...data.reduce( - (val, curr) => - val.concat( - curr.dependencies.map(({pathname}) => [ - pathname, - curr.pathname + curr.filename, - ]), - ), - [], + new Map([ + ...data.map(({pathname, filename}) => [ + pathname, + pathname + filename, + ]), + ...data.reduce( + (val, curr) => + val.concat( + curr.dependencies.map(({pathname}) => [ + pathname, + curr.pathname + curr.filename, + ]), ), - ]).size + [], + ), + ]).size } /> From 4a53045565cba5f7a2531ec6dee7da5ae7c076a2 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 13:24:55 -0700 Subject: [PATCH 30/37] Stop filtering index.ts files out --- scripts/splash/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index a7305a57a65..84549825c46 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -6,9 +6,7 @@ import {argv} from 'yargs'; import {getGitStagedFiles, getDependencies} from './treebuilder'; const excludedFileNames = (fileName) => - !fileName.includes('test') && - !fileName.includes('types') && - !/(components\/)(\w*\/)?(index.ts)/.test(fileName); + !fileName.includes('test') && !fileName.includes('types'); const getEmojiForExtension = (extension) => { switch (extension) { From aed6ff3d90ca14a66389f0b10c11b4d5e01e9d18 Mon Sep 17 00:00:00 2001 From: amrocha Date: Thu, 12 Sep 2019 15:10:06 -0700 Subject: [PATCH 31/37] Integrate with storybook --- .storybook/webpack.config.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js index 6937638ac91..71a6d7c6805 100644 --- a/.storybook/webpack.config.js +++ b/.storybook/webpack.config.js @@ -3,6 +3,7 @@ // For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config const path = require('path'); +const spawn = require('child_process').spawn; const postcssShopify = require('postcss-shopify'); @@ -111,6 +112,17 @@ module.exports = ({config, mode}) => { }, ]; + config.plugins.push({ + apply: (compiler) => { + compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => { + const spawnedProcess = spawn('yarn splash', { + shell: true, + stdio: 'inherit', + }); + }); + }, + }); + config.module.rules = [config.module.rules[0], ...extraRules]; if (isProduction) { From ec0fb8c9724803544619c44c053a9c7056bddc7e Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 16:19:54 -0700 Subject: [PATCH 32/37] Make component grid layout responsive --- scripts/splash/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 84549825c46..bb503fbe7ab 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -55,16 +55,20 @@ const Component = ({pathname, filename, dependencies}) => ( Files potentially affected (total: {dependencies.length}) {dependencies.map(({pathname, filename, componentName}) => ( - + 80 ? 'row' : 'column'} + > {'<'} {componentName} {' />'} - + {pathname} {filename} - + ))} From 4a575ddda3eec35903be706b6cc64cab1caea408 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 16:33:19 -0700 Subject: [PATCH 33/37] Delete watch mode --- package.json | 3 +- scripts/splash/README.md | 5 +-- scripts/splash/index.tsx | 32 ++++++------------- .../TopBar/components/UserMenu/UserMenu.tsx | 2 +- yarn.lock | 32 +------------------ 5 files changed, 14 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 2b2f2d97115..a2723e0fc91 100644 --- a/package.json +++ b/package.json @@ -156,8 +156,7 @@ "shx": "^0.3.2", "storybook-chroma": "^2.1.1", "svgo": "^1.2.2", - "typescript": "~3.5.1", - "yargs": "^13.2.2" + "typescript": "~3.5.1" }, "peerDependencies": { "react": "^16.8.6", diff --git a/scripts/splash/README.md b/scripts/splash/README.md index cc25f41f734..e283d7d6e8b 100644 --- a/scripts/splash/README.md +++ b/scripts/splash/README.md @@ -11,10 +11,7 @@ It answers the question: 1. Edit files in `src/`, such as components 🧩 and style sheets 🎨 2. Run `yarn splash` to see the splash zone of your changes in the working directory -## Tips - -- command + click a file path to open it in your text editor -- `yarn splash --watch` continuously looks for changes in the working directory and updates the list of impacted files in real-time (alpha: you may need to hit ctrl + c multiple times to exit) +💡 Tip: command + click a file path to open it in your text editor ## Feedback and bug reports diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index bb503fbe7ab..a60f38b5a8d 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -2,7 +2,6 @@ import path from 'path'; import React, {useState, useEffect} from 'react'; import {Box, Text, Color, render} from 'ink'; import sortBy from 'lodash/sortBy'; -import {argv} from 'yargs'; import {getGitStagedFiles, getDependencies} from './treebuilder'; const excludedFileNames = (fileName) => @@ -128,28 +127,17 @@ const App = () => { const [data, setData] = useState([]); const [dataStatus, setDataStatus] = useState('loading'); - const getStagedFiles = async () => { - const staged = (await getGitStagedFiles('src/')) as string[]; - setStagedFiles(staged); - - if (staged.length === 0) { - setDataStatus('loaded'); - } - }; - useEffect(() => { - if (!argv.watch) { - getStagedFiles(); - } - }, []); - // ^ empty dependency array = exits after one run + const getStagedFiles = async () => { + const staged = (await getGitStagedFiles('src/')) as string[]; + setStagedFiles(staged); - useEffect(() => { - if (argv.watch) { - getStagedFiles(); - } - }); - // ^ no dependencies = keeps watching + if (staged.length === 0) { + setDataStatus('loaded'); + } + }; + getStagedFiles(); + }, []); useEffect(() => { if (stagedFiles.length > 0) { @@ -201,7 +189,7 @@ const App = () => { 💡 - tip: command + click a file path to open it in your text editor + Tip: command + click a file path to open it in your text editor diff --git a/src/components/TopBar/components/UserMenu/UserMenu.tsx b/src/components/TopBar/components/UserMenu/UserMenu.tsx index 3dc9b602221..6f26d85abda 100644 --- a/src/components/TopBar/components/UserMenu/UserMenu.tsx +++ b/src/components/TopBar/components/UserMenu/UserMenu.tsx @@ -13,7 +13,7 @@ export interface UserMenuProps { message?: MenuProps['message']; /** A string detailing the merchant’s full name to be displayed in the user menu */ name: string; - /** A string allowing further details on the merchant’s name displayed in the user menu */ + /** A string allowing further detail on the merchant’s name displayed in the user menu */ detail?: string; /** The merchant’s initials, rendered in place of an avatar image when not provided */ initials: AvatarProps['initials']; diff --git a/yarn.lock b/yarn.lock index b55ed65170d..c40ca77ba7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8202,11 +8202,6 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - get-port@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.0.0.tgz#373c85960138ee20027c070e3cb08019fea29816" @@ -12850,7 +12845,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-locale@^3.0.0, os-locale@^3.1.0: +os-locale@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== @@ -18500,14 +18495,6 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" - integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" @@ -18602,23 +18589,6 @@ yargs@^12.0.2: y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" -yargs@^13.2.2: - version "13.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" - integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== - dependencies: - cliui "^4.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.0.0" - yargs@^7.0.0, yargs@^7.0.2: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" From 7dd8e0a9dc03dcf188083b7fc78e92b3ed1f3c78 Mon Sep 17 00:00:00 2001 From: amrocha Date: Thu, 12 Sep 2019 16:45:45 -0700 Subject: [PATCH 34/37] Update useEffects flow --- scripts/splash/index.tsx | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index a60f38b5a8d..613d31ac85d 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -77,7 +77,8 @@ const Components = ({components, status}) => ( {status === 'loading' && ( - ⏳{' '}Please wait during compilation… Beep boop beep 🤖 + ⏳{' '} + Please wait during compilation… Beep boop beep 🤖 )} @@ -131,25 +132,25 @@ const App = () => { const getStagedFiles = async () => { const staged = (await getGitStagedFiles('src/')) as string[]; setStagedFiles(staged); - - if (staged.length === 0) { - setDataStatus('loaded'); - } }; getStagedFiles(); }, []); - useEffect(() => { - if (stagedFiles.length > 0) { - const dependencies = getDependencies( - 'src/**/*.tsx', - '*.test.tsx', - stagedFiles, - ); - setData(formatDependencies(dependencies)); + useEffect( + () => { + if (stagedFiles.length !== 0) { + const dependencies = getDependencies( + 'src/**/*.tsx', + '*.test.tsx', + stagedFiles, + ); + setData(formatDependencies(dependencies)); + } + setDataStatus('loaded'); - } - }, [setData, stagedFiles]); + }, + [setData, stagedFiles], + ); return ( From 7eeba2aecc8c9feaa21033fc7c30432cccdcd89a Mon Sep 17 00:00:00 2001 From: amrocha Date: Thu, 12 Sep 2019 17:14:23 -0700 Subject: [PATCH 35/37] enum --- scripts/splash/index.tsx | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 613d31ac85d..53efd78455b 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -4,6 +4,11 @@ import {Box, Text, Color, render} from 'ink'; import sortBy from 'lodash/sortBy'; import {getGitStagedFiles, getDependencies} from './treebuilder'; +enum Status { + Loading = 'LOADING', + Loaded = 'LOADED', +} + const excludedFileNames = (fileName) => !fileName.includes('test') && !fileName.includes('types'); @@ -75,14 +80,14 @@ const Component = ({pathname, filename, dependencies}) => ( const Components = ({components, status}) => ( - {status === 'loading' && ( + {status === Status.Loading && ( ⏳{' '} Please wait during compilation… Beep boop beep 🤖 )} - {status === 'loaded' && + {status === Status.Loaded && components.map(({pathname, filename, dependencies}) => ( Files potentially affected: - {status === 'loading' ? '⏳' : dependencies} + {status === Status.Loading ? '⏳' : dependencies} @@ -126,15 +131,20 @@ const Summary = ({ const App = () => { const [stagedFiles, setStagedFiles] = useState([]); const [data, setData] = useState([]); - const [dataStatus, setDataStatus] = useState('loading'); + const [dataStatus, setDataStatus] = useState(Status.Loading); - useEffect(() => { - const getStagedFiles = async () => { - const staged = (await getGitStagedFiles('src/')) as string[]; - setStagedFiles(staged); - }; - getStagedFiles(); - }, []); + useEffect( + () => { + if (dataStatus === Status.Loading) { + const getStagedFiles = async () => { + const staged = (await getGitStagedFiles('src/')) as string[]; + setStagedFiles(staged); + }; + getStagedFiles(); + } + }, + [dataStatus], + ); useEffect( () => { @@ -147,7 +157,7 @@ const App = () => { setData(formatDependencies(dependencies)); } - setDataStatus('loaded'); + setDataStatus(Status.Loaded); }, [setData, stagedFiles], ); From 768957fe4aef586116a203516537b02d431fd70f Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 17:31:36 -0700 Subject: [PATCH 36/37] Revert "enum" This reverts commit 7eeba2aecc8c9feaa21033fc7c30432cccdcd89a. --- scripts/splash/index.tsx | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 53efd78455b..613d31ac85d 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -4,11 +4,6 @@ import {Box, Text, Color, render} from 'ink'; import sortBy from 'lodash/sortBy'; import {getGitStagedFiles, getDependencies} from './treebuilder'; -enum Status { - Loading = 'LOADING', - Loaded = 'LOADED', -} - const excludedFileNames = (fileName) => !fileName.includes('test') && !fileName.includes('types'); @@ -80,14 +75,14 @@ const Component = ({pathname, filename, dependencies}) => ( const Components = ({components, status}) => ( - {status === Status.Loading && ( + {status === 'loading' && ( ⏳{' '} Please wait during compilation… Beep boop beep 🤖 )} - {status === Status.Loaded && + {status === 'loaded' && components.map(({pathname, filename, dependencies}) => ( Files potentially affected: - {status === Status.Loading ? '⏳' : dependencies} + {status === 'loading' ? '⏳' : dependencies} @@ -131,20 +126,15 @@ const Summary = ({ const App = () => { const [stagedFiles, setStagedFiles] = useState([]); const [data, setData] = useState([]); - const [dataStatus, setDataStatus] = useState(Status.Loading); + const [dataStatus, setDataStatus] = useState('loading'); - useEffect( - () => { - if (dataStatus === Status.Loading) { - const getStagedFiles = async () => { - const staged = (await getGitStagedFiles('src/')) as string[]; - setStagedFiles(staged); - }; - getStagedFiles(); - } - }, - [dataStatus], - ); + useEffect(() => { + const getStagedFiles = async () => { + const staged = (await getGitStagedFiles('src/')) as string[]; + setStagedFiles(staged); + }; + getStagedFiles(); + }, []); useEffect( () => { @@ -157,7 +147,7 @@ const App = () => { setData(formatDependencies(dependencies)); } - setDataStatus(Status.Loaded); + setDataStatus('loaded'); }, [setData, stagedFiles], ); From 1863788b1f4cc25abe3ce86ab58c0e83456194b3 Mon Sep 17 00:00:00 2001 From: Kaelig Date: Thu, 12 Sep 2019 17:31:42 -0700 Subject: [PATCH 37/37] Revert "Update useEffects flow" This reverts commit 7dd8e0a9dc03dcf188083b7fc78e92b3ed1f3c78. --- scripts/splash/index.tsx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/scripts/splash/index.tsx b/scripts/splash/index.tsx index 613d31ac85d..a60f38b5a8d 100644 --- a/scripts/splash/index.tsx +++ b/scripts/splash/index.tsx @@ -77,8 +77,7 @@ const Components = ({components, status}) => ( {status === 'loading' && ( - ⏳{' '} - Please wait during compilation… Beep boop beep 🤖 + ⏳{' '}Please wait during compilation… Beep boop beep 🤖 )} @@ -132,25 +131,25 @@ const App = () => { const getStagedFiles = async () => { const staged = (await getGitStagedFiles('src/')) as string[]; setStagedFiles(staged); + + if (staged.length === 0) { + setDataStatus('loaded'); + } }; getStagedFiles(); }, []); - useEffect( - () => { - if (stagedFiles.length !== 0) { - const dependencies = getDependencies( - 'src/**/*.tsx', - '*.test.tsx', - stagedFiles, - ); - setData(formatDependencies(dependencies)); - } - + useEffect(() => { + if (stagedFiles.length > 0) { + const dependencies = getDependencies( + 'src/**/*.tsx', + '*.test.tsx', + stagedFiles, + ); + setData(formatDependencies(dependencies)); setDataStatus('loaded'); - }, - [setData, stagedFiles], - ); + } + }, [setData, stagedFiles]); return (