diff --git a/lib/cli/bin/generate.js b/lib/cli/bin/generate.js index 4f2ef441ac2f..d837167c0444 100755 --- a/lib/cli/bin/generate.js +++ b/lib/cli/bin/generate.js @@ -74,6 +74,14 @@ switch (projectType) { // Add a new line for the clear visibility. logger.log(); break; + + case types.UPDATE_PACKAGE_ORGANIZATIONS: + require('../generators/UPDATE_PACKAGE_ORGANIZATIONS') + .then(r => null) // commmandLog doesn't like to see output + .then(commandLog('Upgrading your project to the new storybook packages.')) + .then(end); + break; + case types.REACT_SCRIPTS: require('../generators/REACT_SCRIPTS') .then(commandLog('Adding storybook support to your "Create React App" based project')) diff --git a/lib/cli/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.js b/lib/cli/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.js new file mode 100644 index 000000000000..210317157e1a --- /dev/null +++ b/lib/cli/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.js @@ -0,0 +1,50 @@ +const helpers = require('../../lib/helpers'); +const latestVersion = require('latest-version'); +const spawn = require('child-process-promise').spawn; +const path = require('path'); + +const packageNames = require('@storybook/codemod').packageNames; + +function updatePackage(devDependencies, oldName, newName) { + if (devDependencies[oldName]) { + return latestVersion(newName).then(version => { + delete devDependencies[oldName]; + devDependencies[newName] = version; + }); + } else { + return Promise.resolve(null); + } +} + +function updatePackageJson() { + const packageJson = helpers.getPackageJson(); + const { devDependencies } = packageJson; + + return Promise.all( + Object.entries(packageNames).map(([oldName, newName]) => + updatePackage(devDependencies, oldName, newName) + ) + ).then(() => { + if (!devDependencies['@storybook/react'] && !devDependencies['@storybook/react-native']) { + throw new Error('Expected to find `@kadira/[react-native]-storybook` in devDependencies'); + } + helpers.writePackageJson(packageJson); + }); +} + +function updateSourceCode() { + const jscodeshiftPath = path.dirname(require.resolve('jscodeshift')); + const jscodeshiftCommand = path.join(jscodeshiftPath, 'bin', 'jscodeshift.sh'); + + const codemodPath = path.join( + path.dirname(require.resolve('@storybook/codemod')), + 'transforms', + 'update-organisation-name.js' + ); + + const args = ['-t', codemodPath, '--silent', '--ignore-pattern', '"node_modules|dist"', '.']; + + return spawn(jscodeshiftCommand, args, { stdio: 'inherit' }); +} + +module.exports = updatePackageJson().then(updateSourceCode); diff --git a/lib/cli/lib/detect.js b/lib/cli/lib/detect.js index 0394655e4fd4..3dd1247e95d9 100644 --- a/lib/cli/lib/detect.js +++ b/lib/cli/lib/detect.js @@ -9,6 +9,22 @@ module.exports = function detect(options) { return types.UNDETECTED; } + if (!options.force && packageJson.devDependencies) { + if ( + packageJson.devDependencies['@storybook/react'] || + packageJson.devDependencies['@storybook/react-native'] + ) { + return types.ALREADY_HAS_STORYBOOK; + } + + if ( + packageJson.devDependencies['@kadira/storybook'] || + packageJson.devDependencies['@kadira/react-native-storybook'] + ) { + return types.UPDATE_PACKAGE_ORGANIZATIONS; + } + } + if ( !options.force && packageJson.devDependencies && diff --git a/lib/cli/lib/project_types.js b/lib/cli/lib/project_types.js index e38b0c969481..be535af9a368 100644 --- a/lib/cli/lib/project_types.js +++ b/lib/cli/lib/project_types.js @@ -8,4 +8,5 @@ module.exports = { REACT_PROJECT: 'REACT_PROJECT', WEBPACK_REACT: 'WEBPACK_REACT', ALREADY_HAS_STORYBOOK: 'ALREADY_HAS_STORYBOOK', + UPDATE_PACKAGE_ORGANIZATIONS: 'UPDATE_PACKAGE_ORGANIZATIONS', }; diff --git a/lib/cli/package.json b/lib/cli/package.json index 11673ca909f3..a5642aec45cc 100644 --- a/lib/cli/package.json +++ b/lib/cli/package.json @@ -21,9 +21,12 @@ }, "homepage": "https://github.com/storybooks/storybook/tree/master/lib/cli", "dependencies": { + "@storybook/codemod": "^3.0.0-rc.2", "chalk": "^1.1.3", + "child-process-promise": "^2.2.1", "commander": "^2.9.0", "cross-spawn": "^5.0.1", + "jscodeshift": "^0.3.30", "json5": "^0.5.1", "merge-dirs": "^0.2.1", "opencollective": "^1.0.3", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 5fea2dfa71f7..b675c5c92681 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -7,7 +7,7 @@ "type": "git", "url": "git+https://github.com/storybooks/storybook.git" }, - "main": "src/index.js", + "main": "dist/index.js", "dependencies": { "jscodeshift": "^0.3.30" }, diff --git a/lib/codemod/src/index.js b/lib/codemod/src/index.js index c781731a84b1..3e7e5a91aa63 100644 --- a/lib/codemod/src/index.js +++ b/lib/codemod/src/index.js @@ -1,3 +1,6 @@ /* eslint import/prefer-default-export: "off" */ -export { default as updateOrganisationName } from './transforms/update-organisation-name'; +export { + default as updateOrganisationName, + packageNames, +} from './transforms/update-organisation-name'; diff --git a/lib/codemod/src/transforms/update-organisation-name.js b/lib/codemod/src/transforms/update-organisation-name.js index 0735bd9b7146..a07875858b2d 100644 --- a/lib/codemod/src/transforms/update-organisation-name.js +++ b/lib/codemod/src/transforms/update-organisation-name.js @@ -1,28 +1,29 @@ +export const packageNames = { + '@kadira/react-storybook-decorator-centered': '@storybook/addon-centered', + '@kadira/storybook-addons': '@storybook/addons', + '@kadira/storybook-addon-actions': '@storybook/addon-actions', + '@kadira/storybook-addon-comments': '@storybook/addon-comments', + '@kadira/storybook-addon-graphql': '@storybook/addon-graphql', + '@kadira/storybook-addon-info': '@storybook/addon-info', + '@kadira/storybook-addon-knobs': '@storybook/addon-knobs', + '@kadira/storybook-addon-links': '@storybook/addon-links', + '@kadira/storybook-addon-notes': '@storybook/addon-notes', + '@kadira/storybook-addon-options': '@storybook/addon-options', + '@kadira/storybook-channels': '@storybook/channels', + '@kadira/storybook-channel-postmsg': '@storybook/channel-postmessage', + '@kadira/storybook-channel-websocket': '@storybook/channel-websocket', + '@kadira/storybook-ui': '@storybook/ui', + '@kadira/react-native-storybook': '@storybook/react-native', + '@kadira/react-storybook': '@storybook/react', + '@kadira/getstorybook': '@storybook/cli', + '@kadira/storybook': '@storybook/react', + storyshots: '@storybook/addon-storyshots', + getstorybook: '@storybook/cli', +}; + export default function transformer(file, api) { const j = api.jscodeshift; - const packageNames = { - '@kadira/react-storybook-decorator-centered': '@storybook/addon-centered', - '@kadira/storybook-addons': '@storybook/addons', - '@kadira/storybook-addon-actions': '@storybook/addon-actions', - '@kadira/storybook-addon-comments': '@storybook/addon-comments', - '@kadira/storybook-addon-graphql': '@storybook/addon-graphql', - '@kadira/storybook-addon-info': '@storybook/addon-info', - '@kadira/storybook-addon-knobs': '@storybook/addon-knobs', - '@kadira/storybook-addon-links': '@storybook/addon-links', - '@kadira/storybook-addon-notes': '@storybook/addon-notes', - '@kadira/storybook-addon-options': '@storybook/addon-options', - '@kadira/storybook-channels': '@storybook/channels', - '@kadira/storybook-channel-postmsg': '@storybook/channel-postmessage', - '@kadira/storybook-channel-websocket': '@storybook/channel-websocket', - '@kadira/storybook-ui': '@storybook/ui', - '@kadira/react-native-storybook': '@storybook/react-native', - '@kadira/react-storybook': '@storybook/react', - '@kadira/getstorybook': '@storybook/cli', - '@kadira/storybook': '@storybook/react', - storyshots: '@storybook/addon-storyshots', - getstorybook: '@storybook/cli', - }; const packageNamesKeys = Object.keys(packageNames); /**