Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove style guides #108

Merged
merged 7 commits into from Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -28,5 +28,5 @@ npm init @eslint/config@latest -- --config eslint-config-standard
To use an eslintrc-style (legacy) shared config:

```bash
npm init @eslint/config -- --eslintrc --config eslint-config-standard
npm init @eslint/config@latest -- --eslintrc --config eslint-config-standard
```
2 changes: 1 addition & 1 deletion bin/create-config.js
Expand Up @@ -31,7 +31,7 @@ if (sharedConfigIndex === -1) {
// passed "--config"
const packageName = argv[sharedConfigIndex + 1];
const type = argv.includes("--eslintrc") ? "eslintrc" : "flat";
const answers = { purpose: "style", moduleType: "module", styleguide: { packageName, type } };
const answers = { config: { packageName, type } };
const generator = new ConfigGenerator({ cwd, packageJsonPath, answers });

generator.calc();
Expand Down
100 changes: 34 additions & 66 deletions lib/config-generator.js
Expand Up @@ -11,17 +11,6 @@ import { isPackageTypeModule, installSyncSaveDev, fetchPeerDependencies, findPac
import { getShorthandName } from "./utils/naming.js";
import * as log from "./utils/logging.js";

// TODO: need to specify the package version - they may export flat configs in the future.
const jsStyleGuides = [
{ message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb", value: { packageName: "eslint-config-airbnb-base", type: "eslintrc" } },
{ message: "Standard: https://github.com/standard/standard", name: "standard", value: { packageName: "eslint-config-standard", type: "eslintrc" } },
{ message: "XO: https://github.com/xojs/eslint-config-xo", name: "xo", value: { packageName: "eslint-config-xo", type: "eslintrc" } }
];
const tsStyleGuides = [
{ message: "Standard: https://github.com/standard/eslint-config-standard-with-typescript", name: "standard", value: { packageName: "eslint-config-standard-with-typescript", type: "eslintrc" } },
{ message: "XO: https://github.com/xojs/eslint-config-xo-typescript", name: "xo", value: { packageName: "eslint-config-xo-typescript", type: "eslintrc" } }
];

/**
* Class representing a ConfigGenerator.
*/
Expand All @@ -39,7 +28,7 @@ export class ConfigGenerator {
this.packageJsonPath = options.packageJsonPath || findPackageJson(this.cwd);
this.answers = options.answers || {};
this.result = {
devDependencies: ["eslint"],
devDependencies: [],
configFilename: "eslint.config.js",
configContent: ""
};
Expand All @@ -58,8 +47,7 @@ export class ConfigGenerator {
initial: 1,
choices: [
{ message: "To check syntax only", name: "syntax" },
{ message: "To check syntax and find problems", name: "problems" },
{ message: "To check syntax, find problems, and enforce code style", name: "style" }
{ message: "To check syntax and find problems", name: "problems" }
]
},
{
Expand Down Expand Up @@ -110,20 +98,6 @@ export class ConfigGenerator {
const answers = await enquirer.prompt(questions);

Object.assign(this.answers, answers);

if (answers.purpose === "style") {

const choices = this.answers.language === "javascript" ? jsStyleGuides : tsStyleGuides;
const styleguideAnswer = await enquirer.prompt({
type: "select",
name: "styleguide",
message: "Which style guide do you want to follow?",
choices,
result: choice => choices.find(it => it.name === choice).value
});

Object.assign(this.answers, styleguideAnswer);
}
}

/**
Expand All @@ -134,22 +108,9 @@ export class ConfigGenerator {
const isESMModule = isPackageTypeModule(this.packageJsonPath);

this.result.configFilename = isESMModule ? "eslint.config.js" : "eslint.config.mjs";
this.answers.styleguide = typeof this.answers.styleguide === "string"
? { packageName: this.answers.styleguide, type: "flat" }
: this.answers.styleguide;

// replaced `eslint-config-airbnb-base` with `eslint-config-airbnb`(for react supports)
if (this.answers.styleguide?.packageName === "eslint-config-airbnb-base" && this.answers.framework === "react") {
this.answers.styleguide.packageName = "eslint-config-airbnb";
this.answers.framework = "none";
}

// tseslint should have been a dependency in the shared configs
// avoid install tseslint - it may install multi tseslint versions
// see https://github.com/eslint/create-config/issues/97
if (this.answers.styleguide && this.answers.language === "typescript") {
this.answers.language = "javascript";
}
this.answers.config = typeof this.answers.config === "string"
? { packageName: this.answers.config, type: "flat" }
: this.answers.config;

let importContent = "";
const helperContent = `import path from "path";
Expand Down Expand Up @@ -188,28 +149,6 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
this.result.devDependencies.push("@eslint/js");
importContent += "import pluginJs from \"@eslint/js\";\n";
exportContent += " pluginJs.configs.recommended,\n";
} else if (this.answers.purpose === "style") {
const styleguide = this.answers.styleguide;

this.result.devDependencies.push(styleguide.packageName);

// install peer dependencies - it's needed for most eslintrc-style shared configs.
const peers = fetchPeerDependencies(styleguide.packageName);

if (peers !== null) {
this.result.devDependencies.push(...peers);
}

if (styleguide.type === "flat" || styleguide.type === void 0) {
importContent += `import styleGuide from "${styleguide.packageName}";\n`;
exportContent += " ...[].concat(styleGuide),\n";
} else if (styleguide.type === "eslintrc") {
needCompatHelper = true;

const shorthandName = getShorthandName(styleguide.packageName, "eslint-config");

exportContent += ` ...compat.extends("${shorthandName}"),\n`;
}
}

if (this.answers.language === "typescript") {
Expand All @@ -231,10 +170,39 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
importContent += "import pluginReactConfig from \"eslint-plugin-react/configs/recommended.js\";\n";
exportContent += " pluginReactConfig,\n";
}
if (this.answers.config) {
const config = this.answers.config;

this.result.devDependencies.push(config.packageName);

// install peer dependencies - it's needed for most eslintrc-style shared configs.
const peers = fetchPeerDependencies(config.packageName);

if (peers !== null) {
this.result.devDependencies.push(...peers);
}

if (config.type === "flat" || config.type === void 0) {
importContent += `import config from "${config.packageName}";\n`;
exportContent += " ...[].concat(config),\n";
} else if (config.type === "eslintrc") {
needCompatHelper = true;

const shorthandName = getShorthandName(config.packageName, "eslint-config");

exportContent += ` ...compat.extends("${shorthandName}"),\n`;
}
}

if (needCompatHelper) {
this.result.devDependencies.push("@eslint/eslintrc", "@eslint/js");
}

const hasEslint = this.result.devDependencies.some(dep => (/^eslint(@|$)/u.test(dep)));

if (!hasEslint) {
this.result.devDependencies.push("eslint");
}
this.result.configContent = `${importContent}
${needCompatHelper ? helperContent : ""}
export default [\n${exportContent}];`;
Expand Down
@@ -1,6 +1,5 @@
{
"configContent": "import globals from "globals";

"configContent": "
import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
Expand All @@ -12,13 +11,10 @@ const __dirname = path.dirname(__filename);
const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs.configs.recommended});

export default [
{languageOptions: { globals: globals.browser }},
...compat.extends("airbnb"),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint",
"globals",
"eslint-config-airbnb",
"eslint@^7.32.0 || ^8.2.0",
"eslint-plugin-import@^2.25.3",
Expand Down
@@ -1,6 +1,5 @@
{
"configContent": "import globals from "globals";

"configContent": "
import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
Expand All @@ -12,13 +11,10 @@ const __dirname = path.dirname(__filename);
const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs.configs.recommended});

export default [
{languageOptions: { globals: globals.browser }},
...compat.extends("airbnb-base"),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint",
"globals",
"eslint-config-airbnb-base",
"eslint@^7.32.0 || ^8.2.0",
"eslint-plugin-import@^2.25.2",
Expand Down
@@ -1,6 +1,5 @@
{
"configContent": "import globals from "globals";

"configContent": "
import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
Expand All @@ -12,18 +11,15 @@ const __dirname = path.dirname(__filename);
const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs.configs.recommended});

export default [
{languageOptions: { globals: globals.browser }},
...compat.extends("xo-typescript"),
...compat.extends("standard"),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint",
"globals",
"eslint-config-xo-typescript",
"@typescript-eslint/eslint-plugin@>=7.0.2",
"@typescript-eslint/parser@>=7.0.2",
"eslint@>=8.56.0",
"typescript@>=5.0.0",
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
"@eslint/eslintrc",
"@eslint/js",
],
Expand Down
16 changes: 16 additions & 0 deletions tests/__snapshots__/config@eslint-config-standard-flat
@@ -0,0 +1,16 @@
{
"configContent": "import config from "eslint-config-standard";


export default [
...[].concat(config),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
],
}
16 changes: 16 additions & 0 deletions tests/__snapshots__/config@eslint-config-standard-flat2
@@ -0,0 +1,16 @@
{
"configContent": "import config from "eslint-config-standard";


export default [
...[].concat(config),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
],
}
@@ -1,6 +1,5 @@
{
"configContent": "import globals from "globals";

"configContent": "
import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
Expand All @@ -12,13 +11,10 @@ const __dirname = path.dirname(__filename);
const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs.configs.recommended});

export default [
{languageOptions: { globals: globals.node }},
...compat.extends("xo"),
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint",
"globals",
"eslint-config-xo",
"eslint@>=8.56.0",
"@eslint/eslintrc",
Expand Down
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-none-javascript
Expand Up @@ -10,8 +10,8 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-none-typescript
Expand Up @@ -12,9 +12,9 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-react-javascript
Expand Up @@ -12,9 +12,9 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"eslint-plugin-react",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-react-typescript
Expand Up @@ -14,10 +14,10 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint-plugin-react",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-vue-javascript
Expand Up @@ -12,9 +12,9 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"eslint-plugin-vue",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-commonjs-vue-typescript
Expand Up @@ -14,10 +14,10 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint-plugin-vue",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-esm-none-javascript
Expand Up @@ -9,8 +9,8 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"eslint",
],
}
2 changes: 1 addition & 1 deletion tests/__snapshots__/problems-esm-none-typescript
Expand Up @@ -11,9 +11,9 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
}