diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 1984c5b7402a..e9a6bb1b2a54 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -55,6 +55,7 @@ "commander": "^6.2.1", "cross-spawn": "^7.0.3", "degit": "^2.8.4", + "detect-indent": "^6.1.0", "envinfo": "^7.7.3", "execa": "^5.0.0", "express": "^4.17.1", diff --git a/code/lib/cli/src/automigrate/fixes/eslint-plugin.ts b/code/lib/cli/src/automigrate/fixes/eslint-plugin.ts index 1a83c18c91b7..13f4515260a2 100644 --- a/code/lib/cli/src/automigrate/fixes/eslint-plugin.ts +++ b/code/lib/cli/src/automigrate/fixes/eslint-plugin.ts @@ -2,6 +2,8 @@ import chalk from 'chalk'; import { dedent } from 'ts-dedent'; import { ConfigFile, readConfig, writeConfig } from '@storybook/csf-tools'; import { getStorybookInfo } from '@storybook/core-common'; +import { readFile, readJson, writeJson } from 'fs-extra'; +import detectIndent from 'detect-indent'; import { findEslintFile, SUPPORTED_ESLINT_EXTENSIONS } from '../helpers/getEslintInfo'; @@ -79,26 +81,39 @@ export const eslintPlugin: Fix = { if (!dryRun) packageManager.addDependencies({ installAsDevDependencies: true }, deps); if (!dryRun && unsupportedExtension) { - throw new Error(dedent` - ⚠️ The plugin was successfuly installed but failed to configure. + logger.info(dedent` + ⚠️ The plugin was successfully installed but failed to configure. - Found an .eslintrc config file with an unsupported automigration format: ${unsupportedExtension}. - Supported formats for automigration are: ${SUPPORTED_ESLINT_EXTENSIONS.join(', ')}. + Found an eslint config file with an unsupported automigration format: .eslintrc.${unsupportedExtension}. + The supported formats for this automigration are: ${SUPPORTED_ESLINT_EXTENSIONS.join( + ', ' + )}. Please refer to https://github.com/storybookjs/eslint-plugin-storybook#usage to finish setting up the plugin manually. `); + return; } - const eslint = await readConfig(eslintFile); - logger.info(`✅ Configuring eslint rules in ${eslint.fileName}`); - + logger.info(`✅ Adding Storybook plugin to ${eslintFile}`); if (!dryRun) { - logger.info(`✅ Adding Storybook to extends list`); - const extendsConfig = eslint.getFieldValue(['extends']) || []; - const existingConfigValue = Array.isArray(extendsConfig) ? extendsConfig : [extendsConfig]; - eslint.setFieldValue(['extends'], [...existingConfigValue, 'plugin:storybook/recommended']); - - await writeConfig(eslint); + if (eslintFile.endsWith('json')) { + const eslintConfig = (await readJson(eslintFile)) as { extends?: string[] }; + const existingConfigValue = Array.isArray(eslintConfig.extends) + ? eslintConfig.extends + : [eslintConfig.extends]; + eslintConfig.extends = [...(existingConfigValue || []), 'plugin:storybook/recommended']; + + const eslintFileContents = await readFile(eslintFile, 'utf8'); + const spaces = detectIndent(eslintFileContents).amount || 2; + await writeJson(eslintFile, eslintConfig, { spaces }); + } else { + const eslint = await readConfig(eslintFile); + const extendsConfig = eslint.getFieldValue(['extends']) || []; + const existingConfigValue = Array.isArray(extendsConfig) ? extendsConfig : [extendsConfig]; + eslint.setFieldValue(['extends'], [...existingConfigValue, 'plugin:storybook/recommended']); + + await writeConfig(eslint); + } } }, }; diff --git a/code/lib/cli/src/automigrate/helpers/getEslintInfo.ts b/code/lib/cli/src/automigrate/helpers/getEslintInfo.ts index fb153b8fe5b9..698e2c4bde7e 100644 --- a/code/lib/cli/src/automigrate/helpers/getEslintInfo.ts +++ b/code/lib/cli/src/automigrate/helpers/getEslintInfo.ts @@ -1,7 +1,7 @@ import fse from 'fs-extra'; -export const SUPPORTED_ESLINT_EXTENSIONS = ['js', 'cjs']; -const UNSUPPORTED_ESLINT_EXTENSIONS = ['yaml', 'yml', 'json']; +export const SUPPORTED_ESLINT_EXTENSIONS = ['js', 'cjs', 'json']; +const UNSUPPORTED_ESLINT_EXTENSIONS = ['yaml', 'yml']; export const findEslintFile = () => { const filePrefix = '.eslintrc'; diff --git a/code/yarn.lock b/code/yarn.lock index 7ecd35bb8078..4e9929ae560c 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -7295,6 +7295,7 @@ __metadata: commander: ^6.2.1 cross-spawn: ^7.0.3 degit: ^2.8.4 + detect-indent: ^6.1.0 envinfo: ^7.7.3 execa: ^5.0.0 express: ^4.17.1 @@ -16699,7 +16700,7 @@ __metadata: languageName: node linkType: hard -"detect-indent@npm:^6.0.0": +"detect-indent@npm:^6.0.0, detect-indent@npm:^6.1.0": version: 6.1.0 resolution: "detect-indent@npm:6.1.0" checksum: dd83cdeda9af219cf77f5e9a0dc31d828c045337386cfb55ce04fad94ba872ee7957336834154f7647b89b899c3c7acc977c57a79b7c776b506240993f97acc7