From 369ac5580e807286be470853932f8f472ee43d7d Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 8 Jun 2017 09:24:12 +0200 Subject: [PATCH 01/15] ADD a CLI for bootstrapping --- package.json | 7 ++-- scripts/bootstrap.js | 83 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100755 scripts/bootstrap.js diff --git a/package.json b/package.json index 483abd531e04..c093b1a8aab3 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "url": "https://github.com/storybooks/storybook.git" }, "scripts": { - "bootstrap": "lerna bootstrap", + "bootstrap": "./scripts/bootstrap.js", + "bootstrap:libs": "lerna bootstrap", "bootstrap:docs": "cd docs && npm i", "bootstrap:test-cra": "lerna exec --scope test-cra -- npm i", "bootstrap:react-native-vanilla": "lerna exec --scope react-native-vanilla -- npm i", @@ -36,6 +37,7 @@ "babel-preset-stage-0": "^6.24.1", "chalk": "^1.1.3", "codecov": "^2.2.0", + "commander": "^2.9.0", "enzyme": "^2.8.2", "eslint": "^3.19.0", "eslint-config-airbnb": "^15.0.1", @@ -49,6 +51,7 @@ "gh-pages": "^1.0.0", "github-release-from-changelog": "^1.2.1", "husky": "^0.13.4", + "inquirer": "^3.1.0", "jest": "^20.0.4", "jest-enzyme": "^3.2.0", "lerna": "2.0.0-rc.5", @@ -56,7 +59,7 @@ "markdown-it-anchor": "^4.0.0", "markdownlint-cli": "^0.3.1", "nodemon": "^1.11.0", - "prettier": "^1.3.1", + "prettier": "^1.4.4", "react": "^15.5.4", "react-dom": "^15.5.4", "react-test-renderer": "^15.5.4", diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js new file mode 100755 index 000000000000..032424500202 --- /dev/null +++ b/scripts/bootstrap.js @@ -0,0 +1,83 @@ +#!/usr/bin/env babel-node + +import inquirer from 'inquirer'; +import program from 'commander'; +import childProcess from 'child_process'; + +const spawn = childProcess.spawnSync; + +program + .version('1.0.0') + .option('--all', 'Run all without asking') + .option('--docs', 'Bootstrap docs') + .option('--libs', 'Bootstrap libs') + .option('--test-cra', 'Bootstrap test-cra') + .option('--react-native-vanilla', 'Bootstrap react-native-vanilla') + .parse(process.argv); + +const todo = { + docs: false, + libs: false, + 'test-cra': false, + 'react-native-vanilla': false, +}; + +if (program.all) { + Object.assign(todo, { + docs: true, + libs: true, + 'test-cra': true, + 'react-native-vanilla': true, + }); +} + +if (program.docs) { + Object.assign(todo, { + docs: true, + }); +} +if (program.libs) { + Object.assign(todo, { + libs: true, + }); +} +if (program['test-cra']) { + Object.assign(todo, { + 'test-cra': true, + }); +} +if (program['react-native-vanilla']) { + Object.assign(todo, { + 'react-native-vanilla': true, + }); +} + +let selection; +if (!Object.keys(todo).map(key => todo[key]).filter(Boolean).length) { + selection = inquirer + .prompt([ + { + type: 'checkbox', + message: 'Select which packages to bootstrap', + name: 'todo', + choices: Object.keys(todo).map(key => ({ name: key })), + }, + ]) + .then(answers => answers.todo); +} else { + selection = Promise.resolve(Object.keys(todo).filter(key => todo[key] === true)); +} + +selection.then(list => { + if (list.length === 0) { + console.log('Nothing to bootstrap'); + } else { + console.log(`Bootstrapping: ${list.join(', ')}`); + list.forEach(key => { + spawn('npm', [`run bootstrap:${key}`], { + shell: true, + stdio: 'inherit', + }); + }); + } +}); From 4f4b9e4a8b9469758cd3f8befb122618220aeb04 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 23 Jul 2017 21:41:25 +0200 Subject: [PATCH 02/15] set as default bootstrap command && add core as default --- package.json | 4 +- scripts/bootstrap.js | 89 ++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index c14646e6c27b..16d439f715e6 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "url": "https://github.com/storybooks/storybook.git" }, "scripts": { - "bootstrap:experimental": "./scripts/bootstrap.js", - "bootstrap": "lerna bootstrap --concurrency 1 --npm-client=\"yarn\" --hoist && node ./scripts/hoist-internals.js", + "bootstrap": "./scripts/bootstrap.js", + "bootstrap:core": "lerna bootstrap --concurrency 1 --npm-client=\"yarn\" --hoist && node ./scripts/hoist-internals.js", "bootstrap:docs": "cd docs && yarn install", "bootstrap:react-native-vanilla": "lerna exec --scope react-native-vanilla -- yarn install", "bootstrap:test-cra": "npm run build-packs && lerna exec --scope test-cra -- yarn install", diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index 032424500202..c39e5ceef51f 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -1,80 +1,79 @@ #!/usr/bin/env babel-node - import inquirer from 'inquirer'; import program from 'commander'; import childProcess from 'child_process'; +import chalk from 'chalk'; +import log from 'npmlog'; + +log.heading = 'storybook'; +const prefix = 'bootstrap'; const spawn = childProcess.spawnSync; program - .version('1.0.0') + .version('3.0.0') .option('--all', 'Run all without asking') + .option('--core', 'Bootstrap core') .option('--docs', 'Bootstrap docs') - .option('--libs', 'Bootstrap libs') - .option('--test-cra', 'Bootstrap test-cra') - .option('--react-native-vanilla', 'Bootstrap react-native-vanilla') + .option('--test-cra', 'Bootstrap examples/test-cra') + .option('--react-native-vanilla', 'Bootstrap examples/react-native-vanilla') .parse(process.argv); const todo = { - docs: false, - libs: false, - 'test-cra': false, - 'react-native-vanilla': false, + core: { + value: false, + name: `Core & Examples ${chalk.gray('(core)')}`, + default: true, + }, + docs: { + value: false, + name: `Documentation ${chalk.gray('(docs)')}`, + default: false, + }, + 'test-cra': { + value: false, + name: `Realistic installed example ${chalk.gray('(test-cra)')}`, + default: false, + }, + 'react-native-vanilla': { + value: false, + name: `React-Native example ${chalk.gray('(react-native-vanilla)')}`, + default: false, + }, }; -if (program.all) { - Object.assign(todo, { - docs: true, - libs: true, - 'test-cra': true, - 'react-native-vanilla': true, - }); -} - -if (program.docs) { - Object.assign(todo, { - docs: true, - }); -} -if (program.libs) { - Object.assign(todo, { - libs: true, - }); -} -if (program['test-cra']) { - Object.assign(todo, { - 'test-cra': true, - }); -} -if (program['react-native-vanilla']) { - Object.assign(todo, { - 'react-native-vanilla': true, - }); -} +Object.keys(todo).forEach(key => { + todo[key].value = program[key] || program.all; +}); let selection; -if (!Object.keys(todo).map(key => todo[key]).filter(Boolean).length) { +if (!Object.keys(todo).map(key => todo[key].value).filter(Boolean).length) { selection = inquirer .prompt([ { type: 'checkbox', message: 'Select which packages to bootstrap', name: 'todo', - choices: Object.keys(todo).map(key => ({ name: key })), + choices: Object.keys(todo).map(key => ({ + name: todo[key].name, + checked: todo[key].default, + })), }, ]) - .then(answers => answers.todo); + .then(answers => answers.todo.map(name => Object.keys(todo).find(i => todo[i].name === name))); } else { - selection = Promise.resolve(Object.keys(todo).filter(key => todo[key] === true)); + selection = Promise.resolve(Object.keys(todo).filter(key => todo[key].value === true)); } selection.then(list => { if (list.length === 0) { - console.log('Nothing to bootstrap'); + log.warn(prefix, 'Nothing to bootstrap'); } else { - console.log(`Bootstrapping: ${list.join(', ')}`); list.forEach(key => { - spawn('npm', [`run bootstrap:${key}`], { + if (list.length > 1) { + log.info(prefix, `Bootstrapping: ${todo[key].name}`); + } + spawn('yarn', [`bootstrap:${key}`, '-s'], { shell: true, stdio: 'inherit', }); From 9fafeab4cb1fe898550e72eb120845212113ed42 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 23 Jul 2017 21:49:14 +0200 Subject: [PATCH 03/15] CHANGE hoist-internals script to be less verbose --- scripts/hoist-internals.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/hoist-internals.js b/scripts/hoist-internals.js index d178df18df9b..8b082a929d20 100644 --- a/scripts/hoist-internals.js +++ b/scripts/hoist-internals.js @@ -103,8 +103,8 @@ const task = getLernaPackages() task .then(packages => { - log.info(prefix, packages.map(dir => dir.replace(cwd, '')).join(',\n')); - log.success(prefix, 'complete'); + log.verbose(prefix, packages.map(dir => dir.replace(cwd, '')).join(',\n')); + log.success(prefix, `Hoisted ${packages.length} packages`); }) .catch(error => { log.error(prefix, 'failed', error); From 6aad7a1cfc7b50d7edfc6ed609f52c2857868623 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 24 Jul 2017 07:52:56 +0200 Subject: [PATCH 04/15] use `-- --flag` in docs & circleci --- .circleci/config.yml | 15 +++++-------- CONTRIBUTING.md | 50 ++++++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65d7fc239439..6fd689bba69b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap + npm run bootstrap -- --core - save_cache: key: package-dependencies-{{ checksum "package.json" }} paths: @@ -70,8 +70,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap - npm run bootstrap:test-cra + npm run bootstrap -- --core --test-cra - run: name: "Running test-cra" command: | @@ -91,8 +90,7 @@ jobs: - run: name: "Bootstrapping packages" command: | - npm run bootstrap - npm run bootstrap:react-native-vanilla + npm run bootstrap -- --core --react-native-vanilla - run: name: "Running react-native" command: | @@ -113,7 +111,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap:docs + npm run bootstrap -- --docs - run: name: "Running docs" command: | @@ -149,10 +147,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap - npm run bootstrap:docs - npm run bootstrap:test-cra - npm run bootstrap:react-native-vanilla + npm run bootstrap -- --all - run: name: "Unit testing" command: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 06cdc399d360..7801eef7af27 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,22 +20,26 @@ No software is bug free. So, if you got an issue, follow these steps: To test your project against the current latest version of storybook, you can clone the repository and link it with `npm`. Try following these steps: -1. Download the latest version of this project, and build it +1. Download the latest version of this project, and build it: - git clone https://github.com/storybooks/storybook.git - cd storybook - npm install - npm run bootstrap +```sh +git clone https://github.com/storybooks/storybook.git +cd storybook +npm install +npm run bootstrap +``` -2. Link `storybook` and any other required dependencies +2. Link `storybook` and any other required dependencies: - cd app/react - npm link +```sh +cd app/react +npm link - cd - npm link @storybook/react +cd +npm link @storybook/react - # repeat with whichever other parts of the monorepo you are using. +# repeat with whichever other parts of the monorepo you are using. +``` ### Reproductions @@ -43,7 +47,7 @@ The best way to help figure out an issue you are having is to produce a minimal A good way to do that is using the example `test-cra` app embedded in this repository: -```bash +```sh # Download and build this repository: git clone https://github.com/storybooks/storybook.git cd storybook @@ -115,15 +119,13 @@ If an issue is a `bug`, and it doesn't have a clear reproduction that you have p ### Closing issues - Duplicate issues should be closed with a link to the original. - -- Unreproducible issues should be closed if it's not possible to reproduce them (if the reporter drops offline, it is reasonable to wait 2 weeks before closing). - +- Unreproducible issues should be closed if it's not possible to reproduce them (if the reporter drops offline, + it is reasonable to wait 2 weeks before closing). - `bug`s should be labelled `merged` when merged, and be closed when the issue is fixed and released. - -- `feature`s, `maintenance`s, `greenkeeper`s should be labelled `merged` when merged, and closed when released or if the feature is deemed not appropriate. - -- `question / support`s should be closed when the question has been answered. If the questioner drops offline, a reasonable period to wait is two weeks. - +- `feature`s, `maintenance`s, `greenkeeper`s should be labelled `merged` when merged, + and closed when released or if the feature is deemed not appropriate. +- `question / support`s should be closed when the question has been answered. + If the questioner drops offline, a reasonable period to wait is two weeks. - `discussion`s should be closed at a maintainer's discretion. ## Development Guide @@ -133,9 +135,11 @@ If an issue is a `bug`, and it doesn't have a clear reproduction that you have p This project written in ES2016+ syntax so, we need to transpile it before use. So run the following command: - npm run dev +```sh +npm run dev +``` -This will watch files and transpile. +This will watch files and transpile in watch mode. ### Linking @@ -194,7 +198,7 @@ git status git clean -fdx && yarn # build all the packages -npm run bootstrap +npm run bootstrap -- --all ``` From here there are different procedures for prerelease (e.g. alpha/beta/rc) and proper release. From 02e095096827a53eae32e4e7f3024bf2f92b9172 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sat, 19 Aug 2017 22:31:09 +0200 Subject: [PATCH 05/15] ADD build-packs --- scripts/bootstrap.js | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index c39e5ceef51f..c1e2ddb656c3 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -19,7 +19,7 @@ program .option('--react-native-vanilla', 'Bootstrap examples/react-native-vanilla') .parse(process.argv); -const todo = { +const bootstrapOptions = { core: { value: false, name: `Core & Examples ${chalk.gray('(core)')}`, @@ -30,6 +30,11 @@ const todo = { name: `Documentation ${chalk.gray('(docs)')}`, default: false, }, + 'build-packs': { + value: false, + name: `Build tarballs of packages ${chalk.gray('(build-packs)')}`, + default: false, + }, 'test-cra': { value: false, name: `Realistic installed example ${chalk.gray('(test-cra)')}`, @@ -42,27 +47,33 @@ const todo = { }, }; -Object.keys(todo).forEach(key => { - todo[key].value = program[key] || program.all; +Object.keys(bootstrapOptions).forEach(key => { + bootstrapOptions[key].value = program[key] || program.all; }); let selection; -if (!Object.keys(todo).map(key => todo[key].value).filter(Boolean).length) { +if (!Object.keys(bootstrapOptions).map(key => bootstrapOptions[key].value).filter(Boolean).length) { selection = inquirer .prompt([ { type: 'checkbox', message: 'Select which packages to bootstrap', name: 'todo', - choices: Object.keys(todo).map(key => ({ - name: todo[key].name, - checked: todo[key].default, + choices: Object.keys(bootstrapOptions).map(key => ({ + name: bootstrapOptions[key].name, + checked: bootstrapOptions[key].default, })), }, ]) - .then(answers => answers.todo.map(name => Object.keys(todo).find(i => todo[i].name === name))); + .then(answers => + answers.todo.map(name => + Object.keys(bootstrapOptions).find(i => bootstrapOptions[i].name === name) + ) + ); } else { - selection = Promise.resolve(Object.keys(todo).filter(key => todo[key].value === true)); + selection = Promise.resolve( + Object.keys(bootstrapOptions).filter(key => bootstrapOptions[key].value === true) + ); } selection.then(list => { @@ -71,7 +82,7 @@ selection.then(list => { } else { list.forEach(key => { if (list.length > 1) { - log.info(prefix, `Bootstrapping: ${todo[key].name}`); + log.info(prefix, `Bootstrapping: ${bootstrapOptions[key].name}`); } spawn('yarn', [`bootstrap:${key}`, '-s'], { shell: true, From 540ec9aadbee7c3bc8270cb1fee3137902b25c2e Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sat, 19 Aug 2017 22:31:59 +0200 Subject: [PATCH 06/15] DISABLE concurrency on lint-staged (I got problems with git lock files) --- package.json | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 167a21743b18..4903472ce4c5 100644 --- a/package.json +++ b/package.json @@ -88,18 +88,22 @@ "url": "https://opencollective.com/storybook" }, "lint-staged": { - "*.js": [ - "npm run lint:js -- --fix", - "git add" - ], - "*.json": [ - "npm run lint:js -- --fix", - "git add" - ], - "*.md": [ - "npm run lint:md -- -o", - "git add" - ] + "linters": { + "*.js": [ + "npm run lint:js -- --fix", + "git add" + ], + "*.json": [ + "npm run lint:js -- --fix", + "git add" + ], + "*.md": [ + "npm run lint:md -- -o", + "git add" + ] + }, + "verbose": true, + "concurrent": false }, "pr-log": { "skipLabels": [ From c85776a6055580fb9b90e6dfffef7cc66600dd45 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 20 Aug 2017 23:48:27 +0200 Subject: [PATCH 07/15] WIP --- package.json | 1 - scripts/bootstrap.js | 144 +++++++++++++++++++++++++++++-------------- 2 files changed, 98 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 4903472ce4c5..66a1b59d36dc 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "docs:deploy:manual": "cd docs && npm run deploy:manual", "docs:dev": "cd docs && npm run dev", "github-release": "github-release-from-changelog", - "import-repo": "lerna import", "lint": "npm run lint:js . && npm run lint:md .", "lint:js": "eslint --cache --cache-location=.cache/eslint --ext .js,.jsx,.json", "lint:md": "remark", diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index c1e2ddb656c3..ba7c27839d05 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -5,74 +5,126 @@ import childProcess from 'child_process'; import chalk from 'chalk'; import log from 'npmlog'; +const { lstatSync, readdirSync } = require('fs'); +const { join } = require('path'); + +const isTgz = source => lstatSync(source).isFile() && source.match(/.tgz$/); +const getDirectories = source => readdirSync(source).map(name => join(source, name)).filter(isTgz); + log.heading = 'storybook'; const prefix = 'bootstrap'; -const spawn = childProcess.spawnSync; +const spawn = command => + childProcess.spawnSync(`${command}`, { + shell: true, + stdio: 'inherit', + }); -program +const main = program .version('3.0.0') - .option('--all', 'Run all without asking') - .option('--core', 'Bootstrap core') - .option('--docs', 'Bootstrap docs') - .option('--test-cra', 'Bootstrap examples/test-cra') - .option('--react-native-vanilla', 'Bootstrap examples/react-native-vanilla') - .parse(process.argv); + .option('--all', `Bootstrap everything ${chalk.gray('(all)')}`); -const bootstrapOptions = { - core: { - value: false, - name: `Core & Examples ${chalk.gray('(core)')}`, - default: true, +const createTask = ({ defaultValue, option, name, check = () => true, command, pre = [] }) => ({ + value: false, + defaultValue: defaultValue || false, + option: option || undefined, + name: name || 'unnamed task', + check: check || (() => true), + command: () => { + // run all pre tasks + // eslint-disable-next-line no-use-before-define + pre.map(key => tasks[key]).forEach(task => task.check() || task.command()); + + log.info(prefix, name); + command(); }, - docs: { - value: false, +}); + +const tasks = { + reset: createTask({ + name: `Clean and re-install root dependencies ${chalk.gray('(reset)')}`, + defaultValue: true, + option: '--reset', + command: () => { + log.info(prefix, 'git clean'); + spawn('git clean -fdx'); + log.info(prefix, 'yarn install'); + spawn('yarn install --no-lockfile'); + }, + }), + core: createTask({ + name: `Core & Examples ${chalk.gray('(core)')}`, + defaultValue: true, + option: '--core', + command: () => { + spawn('yarn bootstrap:core'); + }, + }), + docs: createTask({ name: `Documentation ${chalk.gray('(docs)')}`, - default: false, - }, - 'build-packs': { - value: false, + defaultValue: false, + option: '--docs', + command: () => { + spawn('yarn bootstrap:docs'); + }, + }), + packs: createTask({ name: `Build tarballs of packages ${chalk.gray('(build-packs)')}`, - default: false, - }, - 'test-cra': { - value: false, + defaultValue: true, + option: '--packs', + command: () => { + spawn('yarn build-packs'); + }, + check: () => getDirectories(join(__dirname, '..', 'packs')).length > 0, + }), + 'test-cra': createTask({ name: `Realistic installed example ${chalk.gray('(test-cra)')}`, - default: false, - }, - 'react-native-vanilla': { - value: false, + defaultValue: false, + option: '--test', + pre: ['packs'], + command: () => { + spawn('yarn bootstrap:test-cra'); + }, + }), + 'react-native-vanilla': createTask({ name: `React-Native example ${chalk.gray('(react-native-vanilla)')}`, - default: false, - }, + defaultValue: false, + option: '--reactnative', + pre: ['packs'], + command: () => { + spawn('yarn bootstrap:react-native-vanilla'); + }, + }), }; -Object.keys(bootstrapOptions).forEach(key => { - bootstrapOptions[key].value = program[key] || program.all; +Object.keys(tasks) + .reduce((acc, key) => acc.option(tasks[key].option, tasks[key].name), main) + .parse(process.argv); + +Object.keys(tasks).forEach(key => { + tasks[key].value = program[tasks[key].option.replace('--', '')] || program.all; }); let selection; -if (!Object.keys(bootstrapOptions).map(key => bootstrapOptions[key].value).filter(Boolean).length) { +if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { selection = inquirer .prompt([ { type: 'checkbox', message: 'Select which packages to bootstrap', name: 'todo', - choices: Object.keys(bootstrapOptions).map(key => ({ - name: bootstrapOptions[key].name, - checked: bootstrapOptions[key].default, + choices: Object.keys(tasks).map(key => ({ + name: tasks[key].name, + checked: tasks[key].defaultValue, })), }, ]) .then(answers => - answers.todo.map(name => - Object.keys(bootstrapOptions).find(i => bootstrapOptions[i].name === name) - ) + answers.todo.map(name => tasks[Object.keys(tasks).find(i => tasks[i].name === name)]) ); } else { selection = Promise.resolve( - Object.keys(bootstrapOptions).filter(key => bootstrapOptions[key].value === true) + Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true) ); } @@ -81,13 +133,13 @@ selection.then(list => { log.warn(prefix, 'Nothing to bootstrap'); } else { list.forEach(key => { - if (list.length > 1) { - log.info(prefix, `Bootstrapping: ${bootstrapOptions[key].name}`); - } - spawn('yarn', [`bootstrap:${key}`, '-s'], { - shell: true, - stdio: 'inherit', - }); + key.command(); }); + process.stdout.write('\x07'); + try { + spawn('say "Bootstrapping sequence complete"'); + } catch (e) { + // discard error + } } }); From de7777e16cc220bf40c263ed71756971f5204953 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 21 Aug 2017 01:03:34 +0200 Subject: [PATCH 08/15] SWITCH to normal node for bootstrap script && CHANGE circleCI to use new bootstrap script --- .circleci/config.yml | 18 ++++++------------ scripts/bootstrap.js | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87677e8c4c33..391003192214 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap + npm run bootstrap -- --all - save_cache: key: package-dependencies-{{ checksum "package.json" }} paths: @@ -63,7 +63,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap + npm run bootstrap -- --core - run: name: "Build react kitchen-sink" command: | @@ -87,9 +87,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap - npm run build-packs - npm run bootstrap:test-cra + npm run bootstrap -- --core --test - run: name: "Build test-cra" command: | @@ -109,9 +107,7 @@ jobs: - run: name: "Bootstrapping packages" command: | - npm run bootstrap - npm run build-packs - npm run bootstrap:react-native-vanilla + npm run bootstrap -- --core --reactnative - run: name: "Running react-native" command: | @@ -131,7 +127,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap:docs + npm run bootstrap -- --docs - run: name: "Running docs" command: | @@ -167,9 +163,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap - npm run build-packs - npm run bootstrap:react-native-vanilla + npm run bootstrap --core --reactnative - run: name: "Unit testing" command: | diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index ba7c27839d05..7494d70cbc13 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -1,9 +1,9 @@ -#!/usr/bin/env babel-node -import inquirer from 'inquirer'; -import program from 'commander'; -import childProcess from 'child_process'; -import chalk from 'chalk'; -import log from 'npmlog'; +#!/usr/bin/env node +const inquirer = require('inquirer'); +const program = require('commander'); +const childProcess = require('child_process'); +const chalk = require('chalk'); +const log = require('npmlog'); const { lstatSync, readdirSync } = require('fs'); const { join } = require('path'); @@ -33,7 +33,11 @@ const createTask = ({ defaultValue, option, name, check = () => true, command, p command: () => { // run all pre tasks // eslint-disable-next-line no-use-before-define - pre.map(key => tasks[key]).forEach(task => task.check() || task.command()); + pre.map(key => tasks[key]).forEach(task => { + if (!task.check()) { + task.command(); + } + }); log.info(prefix, name); command(); @@ -42,8 +46,8 @@ const createTask = ({ defaultValue, option, name, check = () => true, command, p const tasks = { reset: createTask({ - name: `Clean and re-install root dependencies ${chalk.gray('(reset)')}`, - defaultValue: true, + name: `Clean and re-install root dependencies ${chalk.red('(reset)')}`, + defaultValue: false, option: '--reset', command: () => { log.info(prefix, 'git clean'); @@ -70,7 +74,7 @@ const tasks = { }), packs: createTask({ name: `Build tarballs of packages ${chalk.gray('(build-packs)')}`, - defaultValue: true, + defaultValue: false, option: '--packs', command: () => { spawn('yarn build-packs'); From b215110e01cc656a52405123bd557d9d5f193e3b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 21 Aug 2017 07:57:12 +0200 Subject: [PATCH 09/15] FIX circleCI.yml --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 391003192214..4f0a786d56b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -163,7 +163,7 @@ jobs: - run: name: "Bootstrapping" command: | - npm run bootstrap --core --reactnative + npm run bootstrap -- --core --reactnative - run: name: "Unit testing" command: | From 7940e62577b1d00255216638dd8cd192db14ae44 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 21 Aug 2017 08:07:08 +0200 Subject: [PATCH 10/15] REVERT incorrect changes on docs/pages --- docs/pages/addons/addon-gallery/index.md | 7 +++---- docs/pages/addons/using-addons/index.md | 7 +++---- docs/pages/basics/faq/index.md | 4 ++-- docs/pages/basics/guide-react/index.md | 7 +++---- docs/pages/basics/guide-vue/index.md | 7 +++---- docs/pages/basics/quick-start-guide/index.md | 7 +++---- docs/pages/basics/slow-start-guide/index.md | 7 +++---- docs/pages/basics/writing-stories/index.md | 7 +++---- docs/pages/configurations/custom-webpack-config/index.md | 7 +++---- docs/pages/configurations/default-config/index.md | 7 +++---- 10 files changed, 29 insertions(+), 38 deletions(-) diff --git a/docs/pages/addons/addon-gallery/index.md b/docs/pages/addons/addon-gallery/index.md index d79184601851..bf5867ce7612 100644 --- a/docs/pages/addons/addon-gallery/index.md +++ b/docs/pages/addons/addon-gallery/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'addon-gallery' - -## title: 'Addon Gallery' +title: 'Addon Gallery' +--- This is a list of available addons for Storybook. diff --git a/docs/pages/addons/using-addons/index.md b/docs/pages/addons/using-addons/index.md index e98a5b130486..095a005ba2a7 100644 --- a/docs/pages/addons/using-addons/index.md +++ b/docs/pages/addons/using-addons/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'using-addons' - -## title: 'Using Addons' +title: 'Using Addons' +--- Storybook comes with a variety of "core" addons developed and maintained alongside Storybook. Most examples in this site use [actions](https://github.com/storybooks/storybook/tree/master/addons/actions) and [links](https://github.com/storybooks/storybook/tree/master/addons/links). But it's easy to use any third party addons distributed via NPM. diff --git a/docs/pages/basics/faq/index.md b/docs/pages/basics/faq/index.md index a929eb634cab..d45fefaa16be 100644 --- a/docs/pages/basics/faq/index.md +++ b/docs/pages/basics/faq/index.md @@ -28,8 +28,8 @@ You can generally reuse webpack rules fairly easily by placing them in a file th ### Why is there no addons channel? A common error is that an addon tries to access the "channel", but the channel is not set. This can happen in a few different cases: -1. In storybook/addon development, it can be an NPM version problem. If there are two versions of the addons NPM package, it will cause problems. In this case, make sure there is only a single version of `@storybook/addons` being used by your project. -2. In React Native, it's a special case that's documented in [#1192](https://github.com/storybooks/storybook/issues/1192) +1\. In storybook/addon development, it can be an NPM version problem. If there are two versions of the addons NPM package, it will cause problems. In this case, make sure there is only a single version of `@storybook/addons` being used by your project. +2\. In React Native, it's a special case that's documented in [#1192](https://github.com/storybooks/storybook/issues/1192) ### Can I modify React component state in stories? diff --git a/docs/pages/basics/guide-react/index.md b/docs/pages/basics/guide-react/index.md index 48738a4992fe..da950fc4f000 100644 --- a/docs/pages/basics/guide-react/index.md +++ b/docs/pages/basics/guide-react/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'guide-react' - -## title: 'Storybook for React' +title: 'Storybook for React' +--- You may have tried to use our quick start guide to setup your project for Storybook. If you want to set up Storybook manually, this is the guide for you. diff --git a/docs/pages/basics/guide-vue/index.md b/docs/pages/basics/guide-vue/index.md index 843b96778809..43187efe4db0 100644 --- a/docs/pages/basics/guide-vue/index.md +++ b/docs/pages/basics/guide-vue/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'guide-vue' - -## title: 'Storybook for Vue' +title: 'Storybook for Vue' +--- You may have tried to use our quick start guide to setup your project for Storybook. If you want to set up Storybook manually, this is the guide for you. diff --git a/docs/pages/basics/quick-start-guide/index.md b/docs/pages/basics/quick-start-guide/index.md index a18e9c1b8272..1d067775639e 100644 --- a/docs/pages/basics/quick-start-guide/index.md +++ b/docs/pages/basics/quick-start-guide/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'quick-start-guide' - -## title: 'Quick Start Guide' +title: 'Quick Start Guide' +--- Storybook is very easy to use. You can use it with any kind of React or Vue project. Follow these steps to get started with Storybook. diff --git a/docs/pages/basics/slow-start-guide/index.md b/docs/pages/basics/slow-start-guide/index.md index fc2c79482346..cdb65750c74d 100644 --- a/docs/pages/basics/slow-start-guide/index.md +++ b/docs/pages/basics/slow-start-guide/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'slow-start-guide' - -## title: 'Slow start guide' +title: 'Slow start guide' +--- Storybook supports multiple UI libraries, the manual setup for each is different: diff --git a/docs/pages/basics/writing-stories/index.md b/docs/pages/basics/writing-stories/index.md index 60cad6a751fb..cc06435695a8 100644 --- a/docs/pages/basics/writing-stories/index.md +++ b/docs/pages/basics/writing-stories/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'writing-stories' - -## title: 'Writing Stories' +title: 'Writing Stories' +--- Storybook is all about writing stories. Usually a story contains a single state of one of your components. That's like a visual test case. diff --git a/docs/pages/configurations/custom-webpack-config/index.md b/docs/pages/configurations/custom-webpack-config/index.md index d8aa9ea735e3..9c461498db8a 100644 --- a/docs/pages/configurations/custom-webpack-config/index.md +++ b/docs/pages/configurations/custom-webpack-config/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'custom-webpack-config' - -## title: 'Custom Webpack Config' +title: 'Custom Webpack Config' +--- ## Default mode diff --git a/docs/pages/configurations/default-config/index.md b/docs/pages/configurations/default-config/index.md index 279bad0fdf3b..a5f402c9e3d6 100644 --- a/docs/pages/configurations/default-config/index.md +++ b/docs/pages/configurations/default-config/index.md @@ -1,8 +1,7 @@ -* * * - +--- id: 'default-config' - -## title: 'Default Config' +title: 'Default Config' +--- Storybook has a default Webpack setup which suits a large range of projects. It is similar to [Create React App](https://github.com/facebookincubator/create-react-app)'s config when using react, and has been tweaked to closely resemble the webpack config generated by [Vue CLI](https://github.com/vuejs/vue-cli). From 184319654922d7957409add9141615c703634551 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 23 Aug 2017 08:30:15 +0200 Subject: [PATCH 11/15] ADD crna-kitchen-sink bootstrap command --- scripts/bootstrap.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index 5bc24cb755fd..163280627532 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -90,6 +90,15 @@ const tasks = { spawn('yarn bootstrap:react-native-vanilla'); }, }), + 'crna-kitchen-sink': createTask({ + name: `React-Native-App example ${chalk.gray('(crna-kitchen-sink)')}`, + defaultValue: false, + option: '--reactnativeapp', + pre: ['packs'], + command: () => { + spawn('yarn bootstrap:crna-kitchen-sink'); + }, + }), }; Object.keys(tasks) From f84623d86b746a0656e5c508cc0cab777a555cac Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 23 Aug 2017 20:08:16 +0200 Subject: [PATCH 12/15] ADD .vscode and .idea to gitignore, but whitelist them from being removed with git clean --- .gitignore | 1 + scripts/bootstrap.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 382b043ede80..b95d551d1cae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules *.log .idea +.vscode npm-shrinkwrap.json dist .tern-port diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index 163280627532..e386a25fcb7a 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -51,7 +51,7 @@ const tasks = { option: '--reset', command: () => { log.info(prefix, 'git clean'); - spawn('git clean -fdx'); + spawn('git clean -fdx --exclude=".vscode" --exclude=".idea"'); log.info(prefix, 'yarn install'); spawn('yarn install --no-lockfile'); }, From 0723401b51bdda3766267766b00fef53278ce334 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 23 Aug 2017 20:35:57 +0200 Subject: [PATCH 13/15] ADD -- --core to CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1366346ad785..54fdcbc4c205 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ To test your project against the current latest version of storybook, you can cl git clone https://github.com/storybooks/storybook.git cd storybook npm install -npm run bootstrap +npm run bootstrap -- --core ``` 2. Link `storybook` and any other required dependencies: @@ -52,7 +52,7 @@ A good way to do that is using the example `cra-kitchen-sink` app embedded in th git clone https://github.com/storybooks/storybook.git cd storybook npm install -npm run bootstrap +npm run bootstrap -- --core cd examples/cra-kitchen-sink From 30e7c3779be9f97bd64159e86339931c3e36a683 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 23 Aug 2017 21:15:49 +0200 Subject: [PATCH 14/15] ADD a confirmation step when doing the reset task, it will NOT ask when `--reset` is set --- scripts/bootstrap.js | 62 ++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index e386a25fcb7a..4bf53a6e4461 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -13,6 +13,7 @@ const getDirectories = source => readdirSync(source).map(name => join(source, na log.heading = 'storybook'; const prefix = 'bootstrap'; +log.addLevel('aborted', 3001, { fg: 'red', bold: true }); const spawn = command => childProcess.spawnSync(`${command}`, { @@ -123,27 +124,54 @@ if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { })), }, ]) - .then(answers => - answers.todo.map(name => tasks[Object.keys(tasks).find(i => tasks[i].name === name)]) - ); + .then(({ todo }) => + todo.map(name => tasks[Object.keys(tasks).find(i => tasks[i].name === name)]) + ) + .then(list => { + if (list.find(i => i === tasks.reset)) { + return inquirer + .prompt([ + { + type: 'confirm', + message: `${chalk.red('DESTRUCTIVE')}, ${chalk.cyan( + 'Are you sure?' + )} ${chalk.underline('files will get deleted')}`, + name: 'sure', + }, + ]) + .then(({ sure }) => { + if (sure) { + return list; + } + throw new Error('problem is between keyboard and chair'); + }); + } + return list; + }); } else { selection = Promise.resolve( Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true) ); } -selection.then(list => { - if (list.length === 0) { - log.warn(prefix, 'Nothing to bootstrap'); - } else { - list.forEach(key => { - key.command(); - }); - process.stdout.write('\x07'); - try { - spawn('say "Bootstrapping sequence complete"'); - } catch (e) { - // discard error +selection + .then(list => { + if (list.length === 0) { + log.warn(prefix, 'Nothing to bootstrap'); + } else { + list.forEach(key => { + key.command(); + }); + process.stdout.write('\x07'); + try { + spawn('say "Bootstrapping sequence complete"'); + } catch (e) { + // discard error + } } - } -}); + }) + .catch(e => { + log.aborted(prefix, chalk.red(e.message)); + log.silly(prefix, e); + return true; + }); From 55a2b9a0df1214e00f0b54400cda9eb0848557f2 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 23 Aug 2017 23:16:40 +0200 Subject: [PATCH 15/15] IMPROVE confirm message --- scripts/bootstrap.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index 4bf53a6e4461..f026e4ab498e 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -133,9 +133,9 @@ if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { .prompt([ { type: 'confirm', - message: `${chalk.red('DESTRUCTIVE')}, ${chalk.cyan( - 'Are you sure?' - )} ${chalk.underline('files will get deleted')}`, + message: `${chalk.red('DESTRUCTIVE')} files not present in git ${chalk.underline( + 'will get deleted' + )}, except for .idea and .vscode, ${chalk.cyan('Continue?')}`, name: 'sure', }, ])