-
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f893814
commit 4c96a45
Showing
32 changed files
with
532 additions
and
1,483 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 4 | ||
trim_trailing_whitespace = true | ||
end_of_line = lf | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* @fileoverview Main CLI that is run via the eslint command. | ||
* @author Nicholas C. Zakas | ||
* @fileoverview Main CLI that is run via the `npm init @eslint/config` command. | ||
* @author 唯然<[email protected]> | ||
*/ | ||
|
||
/* eslint no-console:off -- CLI */ | ||
import { initializeConfig } from "../lib/init/config-initializer.js"; | ||
initializeConfig(); | ||
import { ConfigGenerator } from "../lib/config-generator.js"; | ||
|
||
const generator = new ConfigGenerator(); | ||
|
||
generator.prompt(); | ||
generator.calc(); | ||
generator.output(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/** | ||
* @fileoverview to generate config files. | ||
* @author 唯然<[email protected]> | ||
*/ | ||
import process from "process"; | ||
import path from "path"; | ||
import { spawnSync } from "child_process"; | ||
import { writeFile } from "fs/promises"; | ||
import enquirer from "enquirer"; | ||
import { isPackageTypeModule, installSyncSaveDev } from "./utils/npm-utils.js"; | ||
import * as log from "./utils/logging.js"; | ||
|
||
/** | ||
* Class representing a ConfigGenerator. | ||
*/ | ||
export class ConfigGenerator { | ||
|
||
/** | ||
* Create a ConfigGenerator. | ||
* @param {Object} options The options for the ConfigGenerator. | ||
* @param {string} options.cwd The current working directory. | ||
* @param {Object} options.answers The answers provided by the user. | ||
* @returns {ConfigGenerator} The ConfigGenerator instance. | ||
*/ | ||
constructor(options = {}) { | ||
this.cwd = options.cwd || process.cwd(); | ||
this.answers = options.answers || {}; | ||
this.result = { | ||
devDependencies: ["eslint"], | ||
configFilename: "eslint.config.js", | ||
configContent: "" | ||
}; | ||
} | ||
|
||
/** | ||
* Prompt the user for input. | ||
* @returns {void} | ||
*/ | ||
prompt() { | ||
|
||
// TODO: ask users to input | ||
this.answers = { | ||
purpose: "syntax", | ||
module: "esm", | ||
framework: "vue", | ||
lang: "js", | ||
env: ["browser", "node"] | ||
}; | ||
} | ||
|
||
// eslint-disable-next-line jsdoc/require-throws -- ts is not supported yet | ||
/** | ||
* Calculate the configuration based on the user's answers. | ||
* @returns {void} | ||
*/ | ||
calc() { | ||
const isModule = isPackageTypeModule(this.cwd); | ||
|
||
this.result.configFilename = isModule ? "eslint.config.js" : "eslint.config.mjs"; | ||
|
||
let importContent = ""; | ||
let exportContent = ""; | ||
let languageOptionsContent = ""; | ||
|
||
if (this.answers.purpose === "syntax") { | ||
|
||
// no need to install any plugin | ||
} else if (this.answers.purpose === "problem") { | ||
this.result.devDependencies.push("@eslint/js"); | ||
importContent += "import pluginJs from \"@eslint/js\";\n"; | ||
exportContent += " pluginJs.configs.recommended,\n"; | ||
} else if (this.answers.purpose === "style") { | ||
|
||
// TODO: style | ||
} | ||
|
||
if (this.answers.module === "commonjs") { | ||
languageOptionsContent += "sourceType: \"commonjs\", "; | ||
} | ||
if (this.answers.env?.length > 0) { | ||
this.result.devDependencies.push("globals"); | ||
importContent += "import globals from \"globals\";\n"; | ||
const envContent = { | ||
browser: "globals: globals.browser", | ||
node: "globals: globals.node", | ||
"browser,node": "globals: {...globals.browser, ...globals.node}" | ||
}; | ||
|
||
languageOptionsContent += `${envContent[this.answers.env.join(",")]}, `; | ||
} | ||
|
||
|
||
if (this.answers.lang === "ts") { | ||
throw new Error("typescript is not supported yet."); | ||
|
||
// this.result.devDependencies.push("@typescript-eslint/eslint-plugin"); | ||
// importContent += "import pluginTs from \"@typescript-eslint/eslint-plugin\";\n"; | ||
// exportContent += " pluginTs.configs.recommended,\n"; | ||
} | ||
|
||
if (this.answers.framework === "vue") { | ||
this.result.devDependencies.push("eslint-plugin-vue"); | ||
importContent += "import pluginVue from \"eslint-plugin-vue\";\n"; | ||
exportContent += " pluginVue.configs.recommended,\n"; | ||
} | ||
|
||
if (this.answers.framework === "react") { | ||
this.result.devDependencies.push("eslint-plugin-react"); | ||
importContent += "import pluginReactConfig from \"eslint-plugin-react/configs/recommended.js\";\n"; | ||
exportContent += " pluginReactConfig,\n"; | ||
} | ||
|
||
this.result.configContent = `${importContent}export default [\n { ${languageOptionsContent}},\n${exportContent}];`; | ||
} | ||
|
||
/** | ||
* Output the configuration. | ||
* @returns {void} | ||
*/ | ||
async output() { | ||
|
||
// TODO: is peerDependencies still needed? | ||
const packageManager = (await enquirer.prompt({ | ||
type: "select", | ||
name: "packageManager", | ||
message: "Which package manager do you want to use?", | ||
initial: 0, | ||
choices: ["npm", "yarn", "pnpm", "bun"] | ||
})).packageManager; | ||
|
||
installSyncSaveDev(this.result.devDependencies, packageManager); | ||
|
||
const configPath = path.join(this.cwd, this.result.configFilename); | ||
|
||
await writeFile(configPath, this.result.configContent); | ||
|
||
// import("eslint") won't work in some cases. | ||
// refs: https://github.com/eslint/create-config/issues/8, https://github.com/eslint/create-config/issues/12 | ||
const eslintBin = path.join(this.cwd, "./node_modules/.bin/eslint"); | ||
const result = spawnSync(eslintBin, ["--fix", "--quiet", configPath], { encoding: "utf8" }); | ||
|
||
if (result.error || result.status !== 0) { | ||
log.error("A config file was generated, but the config file itself may not follow your linting rules."); | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.