Repository: eslint/eslint
Pull request #15491 (2022-01-05 13:09:52)

feat: Support arbitrary module namespace names in no-restricted-imports
<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

#### Prerequisites checklist

- [x] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

[ ] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-proposal.md))
[x] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

Refs #15465, fixes `no-restricted-imports`.

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

#### What changes did you make? (Give an overview)

Updated the `no-restricted-imports` rule to correctly read quoted module export names.

Before this change:

```js
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "mod",
    importNames: ["foo"]    
}]}]*/

import { "foo" as bar } from "mod"; // ok, false negative

export { "foo" } from "mod"; // ok, false negative

export { "foo" as bar } from "mod"; // ok, false negative
```

After this change:

```js
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "mod",
    importNames: ["foo"]    
}]}]*/

import { "foo" as bar } from "mod"; // error

export { "foo" } from "mod"; // error

export { "foo" as bar } from "mod"; // error
```

#### Is there anything you'd like reviewers to focus on?

<!-- markdownlint-disable-file MD004 -->



Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5d9aa9536..939496ded 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,9 +1,9 @@
 name: CI
 on:
   push:
-    branches: [master, main]
+    branches: [main]
   pull_request:
-    branches: [master, main]
+    branches: [main]
 
 jobs:
   verify_files:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index ef362a4b6..60f7922fd 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -13,10 +13,10 @@ name: "CodeQL"
 
 on:
   push:
-    branches: [master, main]
+    branches: [main]
   pull_request:
     # The branches below must be a subset of the branches above
-    branches: [master, main]
+    branches: [main]
   schedule:
     - cron: '28 17 * * 5'
 
diff --git a/README.md b/README.md
index 088e19694..6c6a855ec 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ $ npm install eslint --save-dev
 You should then set up a configuration file:
 
 ```sh
-$ ./node_modules/.bin/eslint --init
+$ npm init @eslint/config
 ```
 
 After that, you can run ESLint on any file or directory like this:
@@ -65,7 +65,7 @@ $ ./node_modules/.bin/eslint yourfile.js
 
 ## <a name="configuration"></a>Configuration
 
-After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
+After running `npm init @eslint/config`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
 
 ```json
 {
@@ -294,7 +294,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
 <p><a href="https://contra.com"><img src="https://images.opencollective.com/contra1/c70f93f/logo.png" alt="Contra" height="96"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://coinbase.com"><img src="https://avatars.githubusercontent.com/u/1885080?v=4" alt="Coinbase" height="96"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
+<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/bin/eslint.js b/bin/eslint.js
index 6b05356b9..d00a870c0 100755
--- a/bin/eslint.js
+++ b/bin/eslint.js
@@ -124,7 +124,13 @@ ${message}`);
 
     // Call the config initializer if `--init` is present.
     if (process.argv.includes("--init")) {
-        await require("../lib/init/config-initializer").initializeConfig();
+
+        // `eslint --init` has been moved to `@eslint/create-config`
+        console.warn("You can also run this command directly using 'npm init @eslint/config'.");
+
+        const spawn = require("cross-spawn");
+
+        spawn.sync("npm", ["init", "@eslint/config"], { encoding: "utf8", stdio: "inherit" });
         return;
     }
 
diff --git a/docs/developer-guide/architecture.md b/docs/developer-guide/architecture.md
index 6531c2839..37261abcc 100644
--- a/docs/developer-guide/architecture.md
+++ b/docs/developer-guide/architecture.md
@@ -7,7 +7,6 @@ At a high level, there are a few key parts to ESLint:
 * `bin/eslint.js` - this is the file that actually gets executed with the command line utility. It's a dumb wrapper that does nothing more than bootstrap ESLint, passing the command line arguments to `cli`. This is intentionally small so as not to require heavy testing.
 * `lib/api.js` - this is the entry point of `require("eslint")`. This file exposes an object that contains public classes `Linter`, `ESLint`, `RuleTester`, and `SourceCode`.
 * `lib/cli.js` - this is the heart of the ESLint CLI. It takes an array of arguments and then uses `eslint` to execute the commands. By keeping this as a separate utility, it allows others to effectively call ESLint from within another Node.js program as if it were done on the command line. The main call is `cli.execute()`. This is also the part that does all the file reading, directory traversing, input, and output.
-* `lib/init/` - this module contains `--init` functionality that set up a configuration file for end users.
 * `lib/cli-engine/` - this module is `CLIEngine` class that finds source code files and configuration files then does code verifying with the `Linter` class. This includes the loading logic of configuration files, parsers, plugins, and formatters.
 * `lib/linter/` - this module is the core `Linter` class that does code verifying based on configuration options. This file does no file I/O and does not interact with the `console` at all. For other Node.js programs that have JavaScript text to verify, they would be able to use this interface directly.
 * `lib/rule-tester/` - this module is `RuleTester` class that is a wrapper around Mocha so that rules can be unit tested. This class lets us write consistently formatted tests for each rule that is implemented and be confident that each of the rules work. The RuleTester interface was modeled after Mocha and works with Mocha's global testing methods. RuleTester can also be modified to work with other testing frameworks.
diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md
index d8e06101b..414485fdf 100644
--- a/docs/rules/no-restricted-imports.md
+++ b/docs/rules/no-restricted-imports.md
@@ -150,7 +150,11 @@ import DisallowedObject from "foo";
     message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
 }]}]*/
 
+import { DisallowedObject } from "foo";
+
 import { DisallowedObject as AllowedObject } from "foo";
+
+import { "DisallowedObject" as AllowedObject } from "foo";
 ```
 
 ```js
diff --git a/docs/rules/no-useless-rename.md b/docs/rules/no-useless-rename.md
index fba312332..1a827288c 100644
--- a/docs/rules/no-useless-rename.md
+++ b/docs/rules/no-useless-rename.md
@@ -52,8 +52,11 @@ Examples of **incorrect** code for this rule by default:
 /*eslint no-useless-rename: "error"*/
 
 import { foo as foo } from "bar";
+import { "foo" as foo } from "bar";
 export { foo as foo };
+export { foo as "foo" };
 export { foo as foo } from "bar";
+export { "foo" as "foo" } from "bar";
 let { foo: foo } = bar;
 let { 'foo': foo } = bar;
 function foo({ bar: bar }) {}
@@ -68,10 +71,13 @@ Examples of **correct** code for this rule by default:
 import * as foo from "foo";
 import { foo } from "bar";
 import { foo as bar } from "baz";
+import { "foo" as bar } from "baz";
 
 export { foo };
 export { foo as bar };
+export { foo as "bar" };
 export { foo as bar } from "foo";
+export { "foo" as "bar" } from "foo";
 
 let { foo } = bar;
 let { foo: bar } = baz;
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index 6f350d485..d30931bf0 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -457,7 +457,7 @@ Example:
 
 #### `--init`
 
-This option will start config initialization wizard. It's designed to help new users quickly create .eslintrc file by answering a few questions, choosing a popular style guide, or inspecting your source files and attempting to automatically generate a suitable configuration.
+This option will run `npm init @eslint/config` to start config initialization wizard. It's designed to help new users quickly create .eslintrc file by answering a few questions, choosing a popular style guide.
 
 The resulting configuration file will be created in the current directory.
 
diff --git a/docs/user-guide/configuring/configuration-files.md b/docs/user-guide/configuring/configuration-files.md
index 3156a99e3..cc1d5bf3c 100644
--- a/docs/user-guide/configuring/configuration-files.md
+++ b/docs/user-guide/configuring/configuration-files.md
@@ -232,7 +232,7 @@ A [sharable configuration](https://eslint.org/docs/developer-guide/shareable-con
 
 The `extends` property value can omit the `eslint-config-` prefix of the package name.
 
-The `eslint --init` command can create a configuration so you can extend a popular style guide (for example, `eslint-config-standard`).
+The `npm init @eslint/config` command can create a configuration so you can extend a popular style guide (for example, `eslint-config-standard`).
 
 Example of a configuration file in YAML format:
 
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index cf808ddc0..1cd016b66 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -20,17 +20,17 @@ npm install eslint --save-dev
 yarn add eslint --dev
 ```
 
-You should then set up a configuration file, and the easiest way to do that is to use the `--init` flag:
+You should then set up a configuration file, and the easiest way to do that is:
 
 ```sh
-$ npx eslint --init
+$ npm init @eslint/config
 
 # or
 
-$ yarn run eslint --init
+$ yarn create @eslint/config
 ```
 
-**Note:** `--init` assumes you have a `package.json` file already. If you don't, make sure to run `npm init` or `yarn init` beforehand.
+**Note:** `npm init @eslint/config` assumes you have a `package.json` file already. If you don't, make sure to run `npm init` or `yarn init` beforehand.
 
 After that, you can run ESLint on any file or directory like this:
 
@@ -48,7 +48,7 @@ It is also possible to install ESLint globally rather than locally (using `npm i
 
 **Note:** If you are coming from a version before 1.0.0 please see the [migration guide](migrating-to-1.0.0.md).
 
-After running `eslint --init`, you'll have a `.eslintrc.{js,yml,json}` file in your directory. In it, you'll see some rules configured like this:
+After running `npm init @eslint/config`, you'll have a `.eslintrc.{js,yml,json}` file in your directory. In it, you'll see some rules configured like this:
 
 ```json
 {
diff --git a/docs/user-guide/migrating-from-jscs.md b/docs/user-guide/migrating-from-jscs.md
index e05ee70d6..b48e9f9fe 100644
--- a/docs/user-guide/migrating-from-jscs.md
+++ b/docs/user-guide/migrating-from-jscs.md
@@ -42,7 +42,7 @@ $ polyjuice --jscs .jscsrc.json ./foo/.jscsrc.json > .eslintrc.json
 If you don't want to convert your JSCS configuration directly into an ESLint configuration, then you can use ESLint's built-in wizard to get you started. Just run:
 
 ```sh
-$ eslint --init
+$ npm init @eslint/config
 ```
 
 You'll be guided through a series of questions that will help you setup a basic configuration file to get you started.
diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js
index e3647018d..c8e137f4d 100644
--- a/lib/cli-engine/cli-engine.js
+++ b/lib/cli-engine/cli-engine.js
@@ -408,7 +408,7 @@ function isErrorMessage(message) {
  * a directory or looks like a directory (ends in `path.sep`), in which case the file
  * name will be the `cacheFile/.cache_hashOfCWD`
  *
- * if cacheFile points to a file or looks like a file then in will just use that file
+ * if cacheFile points to a file or looks like a file then it will just use that file
  * @param {string} cacheFile The name of file to be used to store the cache
  * @param {string} cwd Current working directory
  * @returns {string} the resolved path to the cache file
diff --git a/lib/init/autoconfig.js b/lib/init/autoconfig.js
deleted file mode 100644
index ea2523421..000000000
--- a/lib/init/autoconfig.js
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- * @fileoverview Used for creating a suggested configuration based on project code.
- * @author Ian VanSchooten
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const equal = require("fast-deep-equal"),
-    recConfig = require("../../conf/eslint-recommended"),
-    {
-        Legacy: {
-            ConfigOps
-        }
-    } = require("@eslint/eslintrc"),
-    { Linter } = require("../linter"),
-    configRule = require("./config-rule");
-
-const debug = require("debug")("eslint:autoconfig");
-const linter = new Linter();
-
-//------------------------------------------------------------------------------
-// Data
-//------------------------------------------------------------------------------
-
-const MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only
-    RECOMMENDED_CONFIG_NAME = "eslint:recommended";
-
-//------------------------------------------------------------------------------
-// Private
-//------------------------------------------------------------------------------
-
-/**
- * Information about a rule configuration, in the context of a Registry.
- * @typedef {Object}     registryItem
- * @property {ruleConfig} config A valid configuration for the rule
- * @property {number} specificity The number of elements in the ruleConfig array
- * @property {number} errorCount The number of errors encountered when linting with the config
- */
-
-/**
- * This callback is used to measure execution status in a progress bar
- * @callback progressCallback
- * @param {number} The total number of times the callback will be called.
- */
-
-/**
- * Create registryItems for rules
- * @param {rulesConfig} rulesConfig Hash of rule names and arrays of ruleConfig items
- * @returns {Object} registryItems for each rule in provided rulesConfig
- */
-function makeRegistryItems(rulesConfig) {
-    return Object.keys(rulesConfig).reduce((accumulator, ruleId) => {
-        accumulator[ruleId] = rulesConfig[ruleId].map(config => ({
-            config,
-            specificity: config.length || 1,
-            errorCount: void 0
-        }));
-        return accumulator;
-    }, {});
-}
-
-/**
- * Creates an object in which to store rule configs and error counts
- *
- * Unless a rulesConfig is provided at construction, the registry will not contain
- * any rules, only methods.  This will be useful for building up registries manually.
- *
- * Registry class
- */
-class Registry {
-
-    /**
-     * @param {rulesConfig} [rulesConfig] Hash of rule names and arrays of possible configurations
-     */
-    constructor(rulesConfig) {
-        this.rules = (rulesConfig) ? makeRegistryItems(rulesConfig) : {};
-    }
-
-    /**
-     * Populate the registry with core rule configs.
-     *
-     * It will set the registry's `rule` property to an object having rule names
-     * as keys and an array of registryItems as values.
-     * @returns {void}
-     */
-    populateFromCoreRules() {
-        const rulesConfig = configRule.createCoreRuleConfigs(/* noDeprecated = */ true);
-
-        this.rules = makeRegistryItems(rulesConfig);
-    }
-
-    /**
-     * Creates sets of rule configurations which can be used for linting
-     * and initializes registry errors to zero for those configurations (side effect).
-     *
-     * This combines as many rules together as possible, such that the first sets
-     * in the array will have the highest number of rules configured, and later sets
-     * will have fewer and fewer, as not all rules have the same number of possible
-     * configurations.
-     *
-     * The length of the returned array will be <= MAX_CONFIG_COMBINATIONS.
-     * @returns {Object[]} "rules" configurations to use for linting
-     */
-    buildRuleSets() {
-        let idx = 0;
-        const ruleIds = Object.keys(this.rules),
-            ruleSets = [];
-
-        /**
-         * Add a rule configuration from the registry to the ruleSets
-         *
-         * This is broken out into its own function so that it doesn't need to be
-         * created inside of the while loop.
-         * @param {string} rule The ruleId to add.
-         * @returns {void}
-         */
-        const addRuleToRuleSet = function(rule) {
-
-            /*
-             * This check ensures that there is a rule configuration and that
-             * it has fewer than the max combinations allowed.
-             * If it has too many configs, we will only use the most basic of
-             * the possible configurations.
-             */
-            const hasFewCombos = (this.rules[rule].length <= MAX_CONFIG_COMBINATIONS);
-
-            if (this.rules[rule][idx] && (hasFewCombos || this.rules[rule][idx].specificity <= 2)) {
-
-                /*
-                 * If the rule has too many possible combinations, only take
-                 * simple ones, avoiding objects.
-                 */
-                if (!hasFewCombos && typeof this.rules[rule][idx].config[1] === "object") {
-                    return;
-                }
-
-                ruleSets[idx] = ruleSets[idx] || {};
-                ruleSets[idx][rule] = this.rules[rule][idx].config;
-
-                /*
-                 * Initialize errorCount to zero, since this is a config which
-                 * will be linted.
-                 */
-                this.rules[rule][idx].errorCount = 0;
-            }
-        }.bind(this);
-
-        while (ruleSets.length === idx) {
-            ruleIds.forEach(addRuleToRuleSet);
-            idx += 1;
-        }
-
-        return ruleSets;
-    }
-
-    /**
-     * Remove all items from the registry with a non-zero number of errors
-     *
-     * Note: this also removes rule configurations which were not linted
-     * (meaning, they have an undefined errorCount).
-     * @returns {void}
-     */
-    stripFailingConfigs() {
-        const ruleIds = Object.keys(this.rules),
-            newRegistry = new Registry();
-
-        newRegistry.rules = Object.assign({}, this.rules);
-        ruleIds.forEach(ruleId => {
-            const errorFreeItems = newRegistry.rules[ruleId].filter(registryItem => (registryItem.errorCount === 0));
-
-            if (errorFreeItems.length > 0) {
-                newRegistry.rules[ruleId] = errorFreeItems;
-            } else {
-                delete newRegistry.rules[ruleId];
-            }
-        });
-
-        return newRegistry;
-    }
-
-    /**
-     * Removes rule configurations which were not included in a ruleSet
-     * @returns {void}
-     */
-    stripExtraConfigs() {
-        const ruleIds = Object.keys(this.rules),
-            newRegistry = new Registry();
-
-        newRegistry.rules = Object.assign({}, this.rules);
-        ruleIds.forEach(ruleId => {
-            newRegistry.rules[ruleId] = newRegistry.rules[ruleId].filter(registryItem => (typeof registryItem.errorCount !== "undefined"));
-        });
-
-        return newRegistry;
-    }
-
-    /**
-     * Creates a registry of rules which had no error-free configs.
-     * The new registry is intended to be analyzed to determine whether its rules
-     * should be disabled or set to warning.
-     * @returns {Registry} A registry of failing rules.
-     */
-    getFailingRulesRegistry() {
-        const ruleIds = Object.keys(this.rules),
-            failingRegistry = new Registry();
-
-        ruleIds.forEach(ruleId => {
-            const failingConfigs = this.rules[ruleId].filter(registryItem => (registryItem.errorCount > 0));
-
-            if (failingConfigs && failingConfigs.length === this.rules[ruleId].length) {
-                failingRegistry.rules[ruleId] = failingConfigs;
-            }
-        });
-
-        return failingRegistry;
-    }
-
-    /**
-     * Create an eslint config for any rules which only have one configuration
-     * in the registry.
-     * @returns {Object} An eslint config with rules section populated
-     */
-    createConfig() {
-        const ruleIds = Object.keys(this.rules),
-            config = { rules: {} };
-
-        ruleIds.forEach(ruleId => {
-            if (this.rules[ruleId].length === 1) {
-                config.rules[ruleId] = this.rules[ruleId][0].config;
-            }
-        });
-
-        return config;
-    }
-
-    /**
-     * Return a cloned registry containing only configs with a desired specificity
-     * @param {number} specificity Only keep configs with this specificity
-     * @returns {Registry} A registry of rules
-     */
-    filterBySpecificity(specificity) {
-        const ruleIds = Object.keys(this.rules),
-            newRegistry = new Registry();
-
-        newRegistry.rules = Object.assign({}, this.rules);
-        ruleIds.forEach(ruleId => {
-            newRegistry.rules[ruleId] = this.rules[ruleId].filter(registryItem => (registryItem.specificity === specificity));
-        });
-
-        return newRegistry;
-    }
-
-    /**
-     * Lint SourceCodes against all configurations in the registry, and record results
-     * @param {Object[]} sourceCodes SourceCode objects for each filename
-     * @param {Object} config ESLint config object
-     * @param {progressCallback} [cb] Optional callback for reporting execution status
-     * @returns {Registry} New registry with errorCount populated
-     */
-    lintSourceCode(sourceCodes, config, cb) {
-        let lintedRegistry = new Registry();
-
-        lintedRegistry.rules = Object.assign({}, this.rules);
-
-        const ruleSets = lintedRegistry.buildRuleSets();
-
-        lintedRegistry = lintedRegistry.stripExtraConfigs();
-
-        debug("Linting with all possible rule combinations");
-
-        const filenames = Object.keys(sourceCodes);
-        const totalFilesLinting = filenames.length * ruleSets.length;
-
-        filenames.forEach(filename => {
-            debug(`Linting file: ${filename}`);
-
-            let ruleSetIdx = 0;
-
-            ruleSets.forEach(ruleSet => {
-                const lintConfig = Object.assign({}, config, { rules: ruleSet });
-                const lintResults = linter.verify(sourceCodes[filename], lintConfig);
-
-                lintResults.forEach(result => {
-
-                    /*
-                     * It is possible that the error is from a configuration comment
-                     * in a linted file, in which case there may not be a config
-                     * set in this ruleSetIdx.
-                     * (https://github.com/eslint/eslint/issues/5992)
-                     * (https://github.com/eslint/eslint/issues/7860)
-                     */
-                    if (
-                        lintedRegistry.rules[result.ruleId] &&
-                        lintedRegistry.rules[result.ruleId][ruleSetIdx]
-                    ) {
-                        lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1;
-                    }
-                });
-
-                ruleSetIdx += 1;
-
-                if (cb) {
-                    cb(totalFilesLinting); // eslint-disable-line node/callback-return -- End of function
-                }
-            });
-
-            // Deallocate for GC
-            sourceCodes[filename] = null;
-        });
-
-        return lintedRegistry;
-    }
-}
-
-/**
- * Extract rule configuration into eslint:recommended where possible.
- *
- * This will return a new config with `["extends": [ ..., "eslint:recommended"]` and
- * only the rules which have configurations different from the recommended config.
- * @param {Object} config config object
- * @returns {Object} config object using `"extends": ["eslint:recommended"]`
- */
-function extendFromRecommended(config) {
-    const newConfig = Object.assign({}, config);
-
-    ConfigOps.normalizeToStrings(newConfig);
-
-    const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId]));
-
-    recRules.forEach(ruleId => {
-        if (equal(recConfig.rules[ruleId], newConfig.rules[ruleId])) {
-            delete newConfig.rules[ruleId];
-        }
-    });
-    newConfig.extends.unshift(RECOMMENDED_CONFIG_NAME);
-    return newConfig;
-}
-
-
-//------------------------------------------------------------------------------
-// Public Interface
-//------------------------------------------------------------------------------
-
-module.exports = {
-    Registry,
-    extendFromRecommended
-};
diff --git a/lib/init/config-file.js b/lib/init/config-file.js
deleted file mode 100644
index 9eb10fab3..000000000
--- a/lib/init/config-file.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * @fileoverview Helper to locate and load configuration files.
- * @author Nicholas C. Zakas
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const fs = require("fs"),
-    path = require("path"),
-    stringify = require("json-stable-stringify-without-jsonify");
-
-const debug = require("debug")("eslint:config-file");
-
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-/**
- * Determines sort order for object keys for json-stable-stringify
- *
- * see: https://github.com/samn/json-stable-stringify#cmp
- * @param {Object} a The first comparison object ({key: akey, value: avalue})
- * @param {Object} b The second comparison object ({key: bkey, value: bvalue})
- * @returns {number} 1 or -1, used in stringify cmp method
- */
-function sortByKey(a, b) {
-    return a.key > b.key ? 1 : -1;
-}
-
-//------------------------------------------------------------------------------
-// Private
-//------------------------------------------------------------------------------
-
-/**
- * Writes a configuration file in JSON format.
- * @param {Object} config The configuration object to write.
- * @param {string} filePath The filename to write to.
- * @returns {void}
- * @private
- */
-function writeJSONConfigFile(config, filePath) {
-    debug(`Writing JSON config file: ${filePath}`);
-
-    const content = `${stringify(config, { cmp: sortByKey, space: 4 })}\n`;
-
-    fs.writeFileSync(filePath, content, "utf8");
-}
-
-/**
- * Writes a configuration file in YAML format.
- * @param {Object} config The configuration object to write.
- * @param {string} filePath The filename to write to.
- * @returns {void}
- * @private
- */
-function writeYAMLConfigFile(config, filePath) {
-    debug(`Writing YAML config file: ${filePath}`);
-
-    // lazy load YAML to improve performance when not used
-    const yaml = require("js-yaml");
-
-    const content = yaml.dump(config, { sortKeys: true });
-
-    fs.writeFileSync(filePath, content, "utf8");
-}
-
-/**
- * Writes a configuration file in JavaScript format.
- * @param {Object} config The configuration object to write.
- * @param {string} filePath The filename to write to.
- * @throws {Error} If an error occurs linting the config file contents.
- * @returns {void}
- * @private
- */
-function writeJSConfigFile(config, filePath) {
-    debug(`Writing JS config file: ${filePath}`);
-
-    let contentToWrite;
-    const stringifiedContent = `module.exports = ${stringify(config, { cmp: sortByKey, space: 4 })};\n`;
-
-    try {
-        const { CLIEngine } = require("../cli-engine");
-        const linter = new CLIEngine({
-            baseConfig: config,
-            fix: true,
-            useEslintrc: false
-        });
-        const report = linter.executeOnText(stringifiedContent);
-
-        contentToWrite = report.results[0].output || stringifiedContent;
-    } catch (e) {
-        debug("Error linting JavaScript config file, writing unlinted version");
-        const errorMessage = e.message;
-
-        contentToWrite = stringifiedContent;
-        e.message = "An error occurred while generating your JavaScript config file. ";
-        e.message += "A config file was still generated, but the config file itself may not follow your linting rules.";
-        e.message += `\nError: ${errorMessage}`;
-        throw e;
-    } finally {
-        fs.writeFileSync(filePath, contentToWrite, "utf8");
-    }
-}
-
-/**
- * Writes a configuration file.
- * @param {Object} config The configuration object to write.
- * @param {string} filePath The filename to write to.
- * @returns {void}
- * @throws {Error} When an unknown file type is specified.
- * @private
- */
-function write(config, filePath) {
-    switch (path.extname(filePath)) {
-        case ".js":
-        case ".cjs":
-            writeJSConfigFile(config, filePath);
-            break;
-
-        case ".json":
-            writeJSONConfigFile(config, filePath);
-            break;
-
-        case ".yaml":
-        case ".yml":
-            writeYAMLConfigFile(config, filePath);
-            break;
-
-        default:
-            throw new Error("Can't write to unknown file type.");
-    }
-}
-
-//------------------------------------------------------------------------------
-// Public Interface
-//------------------------------------------------------------------------------
-
-module.exports = {
-    write
-};
diff --git a/lib/init/config-initializer.js b/lib/init/config-initializer.js
deleted file mode 100644
index 3c244b7bc..000000000
--- a/lib/init/config-initializer.js
+++ /dev/null
@@ -1,709 +0,0 @@
-/**
- * @fileoverview Config initialization wizard.
- * @author Ilya Volodin
- */
-
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const util = require("util"),
-    path = require("path"),
-    fs = require("fs"),
-    enquirer = require("enquirer"),
-    ProgressBar = require("progress"),
-    semver = require("semver"),
-    espree = require("espree"),
-    recConfig = require("../../conf/eslint-recommended"),
-    {
-        Legacy: {
-            ConfigOps,
-            naming
-        }
-    } = require("@eslint/eslintrc"),
-    log = require("../shared/logging"),
-    ModuleResolver = require("../shared/relative-module-resolver"),
-    autoconfig = require("./autoconfig.js"),
-    ConfigFile = require("./config-file"),
-    npmUtils = require("./npm-utils"),
-    { getSourceCodeOfFiles } = require("./source-code-utils");
-
-const debug = require("debug")("eslint:config-initializer");
-
-//------------------------------------------------------------------------------
-// Private
-//------------------------------------------------------------------------------
-
-/* istanbul ignore next: hard to test fs function */
-/**
- * Create .eslintrc file in the current working directory
- * @param {Object} config object that contains user's answers
- * @param {string} format The file format to write to.
- * @returns {void}
- */
-function writeFile(config, format) {
-
-    // default is .js
-    let extname = ".js";
-
-    if (format === "YAML") {
-        extname = ".yml";
-    } else if (format === "JSON") {
-        extname = ".json";
-    } else if (format === "JavaScript") {
-        const pkgJSONPath = npmUtils.findPackageJson();
-
-        if (pkgJSONPath) {
-            const pkgJSONContents = JSON.parse(fs.readFileSync(pkgJSONPath, "utf8"));
-
-            if (pkgJSONContents.type === "module") {
-                extname = ".cjs";
-            }
-        }
-    }
-
-    const installedESLint = config.installedESLint;
-
-    delete config.installedESLint;
-
-    ConfigFile.write(config, `./.eslintrc${extname}`);
-    log.info(`Successfully created .eslintrc${extname} file in ${process.cwd()}`);
-
-    if (installedESLint) {
-        log.info("ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy.");
-    }
-}
-
-/**
- * Get the peer dependencies of the given module.
- * This adds the gotten value to cache at the first time, then reuses it.
- * In a process, this function is called twice, but `npmUtils.fetchPeerDependencies` needs to access network which is relatively slow.
- * @param {string} moduleName The module name to get.
- * @returns {Object} The peer dependencies of the given module.
- * This object is the object of `peerDependencies` field of `package.json`.
- * Returns null if npm was not found.
- */
-function getPeerDependencies(moduleName) {
-    let result = getPeerDependencies.cache.get(moduleName);
-
-    if (!result) {
-        log.info(`Checking peerDependencies of ${moduleName}`);
-
-        result = npmUtils.fetchPeerDependencies(moduleName);
-        getPeerDependencies.cache.set(moduleName, result);
-    }
-
-    return result;
-}
-getPeerDependencies.cache = new Map();
-
-/**
- * Return necessary plugins, configs, parsers, etc. based on the config
- * @param {Object} config config object
- * @param {boolean} [installESLint=true] If `false` is given, it does not install eslint.
- * @returns {string[]} An array of modules to be installed.
- */
-function getModulesList(config, installESLint) {
-    const modules = {};
-
-    // Create a list of modules which should be installed based on config
-    if (config.plugins) {
-        for (const plugin of config.plugins) {
-            const moduleName = naming.normalizePackageName(plugin, "eslint-plugin");
-
-            modules[moduleName] = "latest";
-        }
-    }
-    if (config.extends) {
-        const extendList = Array.isArray(config.extends) ? config.extends : [config.extends];
-
-        for (const extend of extendList) {
-            if (extend.startsWith("eslint:") || extend.startsWith("plugin:")) {
-                continue;
-            }
-            const moduleName = naming.normalizePackageName(extend, "eslint-config");
-
-            modules[moduleName] = "latest";
-            Object.assign(
-                modules,
-                getPeerDependencies(`${moduleName}@latest`)
-            );
-        }
-    }
-
-    const parser = config.parser || (config.parserOptions && config.parserOptions.parser);
-
-    if (parser) {
-        modules[parser] = "latest";
-    }
-
-    if (installESLint === false) {
-        delete modules.eslint;
-    } else {
-        const installStatus = npmUtils.checkDevDeps(["eslint"]);
-
-        // Mark to show messages if it's new installation of eslint.
-        if (installStatus.eslint === false) {
-            log.info("Local ESLint installation not found.");
-            modules.eslint = modules.eslint || "latest";
-            config.installedESLint = true;
-        }
-    }
-
-    return Object.keys(modules).map(name => `${name}@${modules[name]}`);
-}
-
-/**
- * Set the `rules` of a config by examining a user's source code
- *
- * Note: This clones the config object and returns a new config to avoid mutating
- * the original config parameter.
- * @param {Object} answers answers received from enquirer
- * @param {Object} config config object
- * @throws {Error} If source code retrieval fails or source code file count is 0.
- * @returns {Object} config object with configured rules
- */
-function configureRules(answers, config) {
-    const BAR_TOTAL = 20,
-        BAR_SOURCE_CODE_TOTAL = 4,
-        newConfig = Object.assign({}, config),
-        disabledConfigs = {};
-    let sourceCodes,
-        registry;
-
-    // Set up a progress bar, as this process can take a long time
-    const bar = new ProgressBar("Determining Config: :percent [:bar] :elapseds elapsed, eta :etas ", {
-        width: 30,
-        total: BAR_TOTAL
-    });
-
-    bar.tick(0); // Shows the progress bar
-
-    // Get the SourceCode of all chosen files
-    const patterns = answers.patterns.split(/[\s]+/u);
-
-    try {
-        sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => {
-            bar.tick((BAR_SOURCE_CODE_TOTAL / total));
-        });
-    } catch (e) {
-        log.info("\n");
-        throw e;
-    }
-    const fileQty = Object.keys(sourceCodes).length;
-
-    if (fileQty === 0) {
-        log.info("\n");
-        throw new Error("Automatic Configuration failed.  No files were able to be parsed.");
-    }
-
-    // Create a registry of rule configs
-    registry = new autoconfig.Registry();
-    registry.populateFromCoreRules();
-
-    // Lint all files with each rule config in the registry
-    registry = registry.lintSourceCode(sourceCodes, newConfig, total => {
-        bar.tick((BAR_TOTAL - BAR_SOURCE_CODE_TOTAL) / total); // Subtract out ticks used at beginning
-    });
-    debug(`\nRegistry: ${util.inspect(registry.rules, { depth: null })}`);
-
-    // Create a list of recommended rules, because we don't want to disable them
-    const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId]));
-
-    // Find and disable rules which had no error-free configuration
-    const failingRegistry = registry.getFailingRulesRegistry();
-
-    Object.keys(failingRegistry.rules).forEach(ruleId => {
-
-        // If the rule is recommended, set it to error, otherwise disable it
-        disabledConfigs[ruleId] = (recRules.indexOf(ruleId) !== -1) ? 2 : 0;
-    });
-
-    // Now that we know which rules to disable, strip out configs with errors
-    registry = registry.stripFailingConfigs();
-
-    /*
-     * If there is only one config that results in no errors for a rule, we should use it.
-     * createConfig will only add rules that have one configuration in the registry.
-     */
-    const singleConfigs = registry.createConfig().rules;
-
-    /*
-     * The "sweet spot" for number of options in a config seems to be two (severity plus one option).
-     * Very often, a third option (usually an object) is available to address
-     * edge cases, exceptions, or unique situations. We will prefer to use a config with
-     * specificity of two.
-     */
-    const specTwoConfigs = registry.filterBySpecificity(2).createConfig().rules;
-
-    // Maybe a specific combination using all three options works
-    const specThreeConfigs = registry.filterBySpecificity(3).createConfig().rules;
-
-    // If all else fails, try to use the default (severity only)
-    const defaultConfigs = registry.filterBySpecificity(1).createConfig().rules;
-
-    // Combine configs in reverse priority order (later take precedence)
-    newConfig.rules = Object.assign({}, disabledConfigs, defaultConfigs, specThreeConfigs, specTwoConfigs, singleConfigs);
-
-    // Make sure progress bar has finished (floating point rounding)
-    bar.update(BAR_TOTAL);
-
-    // Log out some stats to let the user know what happened
-    const finalRuleIds = Object.keys(newConfig.rules);
-    const totalRules = finalRuleIds.length;
-    const enabledRules = finalRuleIds.filter(ruleId => (newConfig.rules[ruleId] !== 0)).length;
-    const resultMessage = [
-        `\nEnabled ${enabledRules} out of ${totalRules}`,
-        `rules based on ${fileQty}`,
-        `file${(fileQty === 1) ? "." : "s."}`
-    ].join(" ");
-
-    log.info(resultMessage);
-
-    ConfigOps.normalizeToStrings(newConfig);
-    return newConfig;
-}
-
-/**
- * process user's answers and create config object
- * @param {Object} answers answers received from enquirer
- * @returns {Object} config object
- */
-function processAnswers(answers) {
-    let config = {
-        rules: {},
-        env: {},
-        parserOptions: {},
-        extends: []
-    };
-
-    config.parserOptions.ecmaVersion = espree.latestEcmaVersion;
-    config.env.es2021 = true;
-
-    // set the module type
-    if (answers.moduleType === "esm") {
-        config.parserOptions.sourceType = "module";
-    } else if (answers.moduleType === "commonjs") {
-        config.env.commonjs = true;
-    }
-
-    // add in browser and node environments if necessary
-    answers.env.forEach(env => {
-        config.env[env] = true;
-    });
-
-    // add in library information
-    if (answers.framework === "react") {
-        config.parserOptions.ecmaFeatures = {
-            jsx: true
-        };
-        config.plugins = ["react"];
-        config.extends.push("plugin:react/recommended");
-    } else if (answers.framework === "vue") {
-        config.plugins = ["vue"];
-        config.extends.push("plugin:vue/essential");
-    }
-
-    if (answers.typescript) {
-        if (answers.framework === "vue") {
-            config.parserOptions.parser = "@typescript-eslint/parser";
-        } else {
-            config.parser = "@typescript-eslint/parser";
-        }
-
-        if (Array.isArray(config.plugins)) {
-            config.plugins.push("@typescript-eslint");
-        } else {
-            config.plugins = ["@typescript-eslint"];
-        }
-    }
-
-    // setup rules based on problems/style enforcement preferences
-    if (answers.purpose === "problems") {
-        config.extends.unshift("eslint:recommended");
-    } else if (answers.purpose === "style") {
-        if (answers.source === "prompt") {
-            config.extends.unshift("eslint:recommended");
-            config.rules.indent = ["error", answers.indent];
-            config.rules.quotes = ["error", answers.quotes];
-            config.rules["linebreak-style"] = ["error", answers.linebreak];
-            config.rules.semi = ["error", answers.semi ? "always" : "never"];
-        } else if (answers.source === "auto") {
-            config = configureRules(answers, config);
-            config = autoconfig.extendFromRecommended(config);
-        }
-    }
-    if (answers.typescript && config.extends.includes("eslint:recommended")) {
-        config.extends.push("plugin:@typescript-eslint/recommended");
-    }
-
-    // normalize extends
-    if (config.extends.length === 0) {
-        delete config.extends;
-    } else if (config.extends.length === 1) {
-        config.extends = config.extends[0];
-    }
-
-    ConfigOps.normalizeToStrings(config);
-    return config;
-}
-
-/**
- * Get the version of the local ESLint.
- * @returns {string|null} The version. If the local ESLint was not found, returns null.
- */
-function getLocalESLintVersion() {
-    try {
-        const eslintPath = ModuleResolver.resolve("eslint", path.join(process.cwd(), "__placeholder__.js"));
-        const eslint = require(eslintPath);
-
-        return eslint.linter.version || null;
-    } catch {
-        return null;
-    }
-}
-
-/**
- * Get the shareable config name of the chosen style guide.
- * @param {Object} answers The answers object.
- * @returns {string} The shareable config name.
- */
-function getStyleGuideName(answers) {
-    if (answers.styleguide === "airbnb" && answers.framework !== "react") {
-        return "airbnb-base";
-    }
-    return answers.styleguide;
-}
-
-/**
- * Check whether the local ESLint version conflicts with the required version of the chosen shareable config.
- * @param {Object} answers The answers object.
- * @returns {boolean} `true` if the local ESLint is found then it conflicts with the required version of the chosen shareable config.
- */
-function hasESLintVersionConflict(answers) {
-
-    // Get the local ESLint version.
-    const localESLintVersion = getLocalESLintVersion();
-
-    if (!localESLintVersion) {
-        return false;
-    }
-
-    // Get the required range of ESLint version.
-    const configName = getStyleGuideName(answers);
-    const moduleName = `eslint-config-${configName}@latest`;
-    const peerDependencies = getPeerDependencies(moduleName) || {};
-    const requiredESLintVersionRange = peerDependencies.eslint;
-
-    if (!requiredESLintVersionRange) {
-        return false;
-    }
-
-    answers.localESLintVersion = localESLintVersion;
-    answers.requiredESLintVersionRange = requiredESLintVersionRange;
-
-    // Check the version.
-    if (semver.satisfies(localESLintVersion, requiredESLintVersionRange)) {
-        answers.installESLint = false;
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * Install modules.
- * @param {string[]} modules Modules to be installed.
- * @returns {void}
- */
-function installModules(modules) {
-    log.info(`Installing ${modules.join(", ")}`);
-    npmUtils.installSyncSaveDev(modules);
-}
-
-/* istanbul ignore next: no need to test enquirer */
-/**
- * Ask user to install modules.
- * @param {string[]} modules Array of modules to be installed.
- * @param {boolean} packageJsonExists Indicates if package.json is existed.
- * @returns {Promise<void>} Answer that indicates if user wants to install.
- */
-function askInstallModules(modules, packageJsonExists) {
-
-    // If no modules, do nothing.
-    if (modules.length === 0) {
-        return Promise.resolve();
-    }
-
-    log.info("The config that you've selected requires the following dependencies:\n");
-    log.info(modules.join(" "));
-    return enquirer.prompt([
-        {
-            type: "toggle",
-            name: "executeInstallation",
-            message: "Would you like to install them now with npm?",
-            enabled: "Yes",
-            disabled: "No",
-            initial: 1,
-            skip() {
-                return !(modules.length && packageJsonExists);
-            },
-            result(input) {
-                return this.skipped ? null : input;
-            }
-        }
-    ]).then(({ executeInstallation }) => {
-        if (executeInstallation) {
-            installModules(modules);
-        }
-    });
-}
-
-/* istanbul ignore next: no need to test enquirer */
-/**
- * Ask use a few questions on command prompt
- * @returns {Promise<void>} The promise with the result of the prompt
- */
-function promptUser() {
-
-    return enquirer.prompt([
-        {
-            type: "select",
-            name: "purpose",
-            message: "How would you like to use ESLint?",
-
-            // The returned number matches the name value of nth in the choices array.
-            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" }
-            ]
-        },
-        {
-            type: "select",
-            name: "moduleType",
-            message: "What type of modules does your project use?",
-            initial: 0,
-            choices: [
-                { message: "JavaScript modules (import/export)", name: "esm" },
-                { message: "CommonJS (require/exports)", name: "commonjs" },
-                { message: "None of these", name: "none" }
-            ]
-        },
-        {
-            type: "select",
-            name: "framework",
-            message: "Which framework does your project use?",
-            initial: 0,
-            choices: [
-                { message: "React", name: "react" },
-                { message: "Vue.js", name: "vue" },
-                { message: "None of these", name: "none" }
-            ]
-        },
-        {
-            type: "toggle",
-            name: "typescript",
-            message: "Does your project use TypeScript?",
-            enabled: "Yes",
-            disabled: "No",
-            initial: 0
-        },
-        {
-            type: "multiselect",
-            name: "env",
-            message: "Where does your code run?",
-            hint: "(Press <space> to select, <a> to toggle all, <i> to invert selection)",
-            initial: 0,
-            choices: [
-                { message: "Browser", name: "browser" },
-                { message: "Node", name: "node" }
-            ]
-        },
-        {
-            type: "select",
-            name: "source",
-            message: "How would you like to define a style for your project?",
-            choices: [
-                { message: "Use a popular style guide", name: "guide" },
-                { message: "Answer questions about your style", name: "prompt" },
-                { message: "Inspect your JavaScript file(s)", name: "auto" }
-            ],
-            skip() {
-                return this.state.answers.purpose !== "style";
-            },
-            result(input) {
-                return this.skipped ? null : input;
-            }
-        },
-        {
-            type: "select",
-            name: "styleguide",
-            message: "Which style guide do you want to follow?",
-            choices: [
-                { message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb" },
-                { message: "Standard: https://github.com/standard/standard", name: "standard" },
-                { message: "Google: https://github.com/google/eslint-config-google", name: "google" },
-                { message: "XO: https://github.com/xojs/eslint-config-xo", name: "xo" }
-            ],
-            skip() {
-                this.state.answers.packageJsonExists = npmUtils.checkPackageJson();
-                return !(this.state.answers.source === "guide" && this.state.answers.packageJsonExists);
-            },
-            result(input) {
-                return this.skipped ? null : input;
-            }
-        },
-        {
-            type: "input",
-            name: "patterns",
-            message: "Which file(s), path(s), or glob(s) should be examined?",
-            skip() {
-                return this.state.answers.source !== "auto";
-            },
-            validate(input) {
-                if (!this.skipped && input.trim().length === 0 && input.trim() !== ",") {
-                    return "You must tell us what code to examine. Try again.";
-                }
-                return true;
-            }
-        },
-        {
-            type: "select",
-            name: "format",
-            message: "What format do you want your config file to be in?",
-            initial: 0,
-            choices: ["JavaScript", "YAML", "JSON"]
-        },
-        {
-            type: "toggle",
-            name: "installESLint",
-            message() {
-                const { answers } = this.state;
-                const verb = semver.ltr(answers.localESLintVersion, answers.requiredESLintVersionRange)
-                    ? "upgrade"
-                    : "downgrade";
-
-                return `The style guide "${answers.styleguide}" requires eslint@${answers.requiredESLintVersionRange}. You are currently using eslint@${answers.localESLintVersion}.\n  Do you want to ${verb}?`;
-            },
-            enabled: "Yes",
-            disabled: "No",
-            initial: 1,
-            skip() {
-                return !(this.state.answers.source === "guide" && this.state.answers.packageJsonExists && hasESLintVersionConflict(this.state.answers));
-            },
-            result(input) {
-                return this.skipped ? null : input;
-            }
-        }
-    ]).then(earlyAnswers => {
-
-        // early exit if no style guide is necessary
-        if (earlyAnswers.purpose !== "style") {
-            const config = processAnswers(earlyAnswers);
-            const modules = getModulesList(config);
-
-            return askInstallModules(modules, earlyAnswers.packageJsonExists)
-                .then(() => writeFile(config, earlyAnswers.format));
-        }
-
-        // early exit if you are using a style guide
-        if (earlyAnswers.source === "guide") {
-            if (!earlyAnswers.packageJsonExists) {
-                log.info("A package.json is necessary to install plugins such as style guides. Run `npm init` to create a package.json file and try again.");
-                return void 0;
-            }
-            if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
-                log.info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
-            }
-            if (earlyAnswers.styleguide === "airbnb" && earlyAnswers.framework !== "react") {
-                earlyAnswers.styleguide = "airbnb-base";
-            }
-
-            const config = processAnswers(earlyAnswers);
-
-            if (Array.isArray(config.extends)) {
-                config.extends.push(earlyAnswers.styleguide);
-            } else if (config.extends) {
-                config.extends = [config.extends, earlyAnswers.styleguide];
-            } else {
-                config.extends = [earlyAnswers.styleguide];
-            }
-
-            const modules = getModulesList(config);
-
-            return askInstallModules(modules, earlyAnswers.packageJsonExists)
-                .then(() => writeFile(config, earlyAnswers.format));
-
-        }
-
-        if (earlyAnswers.source === "auto") {
-            const combinedAnswers = Object.assign({}, earlyAnswers);
-            const config = processAnswers(combinedAnswers);
-            const modules = getModulesList(config);
-
-            return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
-        }
-
-        // continue with the style questions otherwise...
-        return enquirer.prompt([
-            {
-                type: "select",
-                name: "indent",
-                message: "What style of indentation do you use?",
-                initial: 0,
-                choices: [{ message: "Tabs", name: "tab" }, { message: "Spaces", name: 4 }]
-            },
-            {
-                type: "select",
-                name: "quotes",
-                message: "What quotes do you use for strings?",
-                initial: 0,
-                choices: [{ message: "Double", name: "double" }, { message: "Single", name: "single" }]
-            },
-            {
-                type: "select",
-                name: "linebreak",
-                message: "What line endings do you use?",
-                initial: 0,
-                choices: [{ message: "Unix", name: "unix" }, { message: "Windows", name: "windows" }]
-            },
-            {
-                type: "toggle",
-                name: "semi",
-                message: "Do you require semicolons?",
-                enabled: "Yes",
-                disabled: "No",
-                initial: 1
-            }
-        ]).then(answers => {
-            const totalAnswers = Object.assign({}, earlyAnswers, answers);
-
-            const config = processAnswers(totalAnswers);
-            const modules = getModulesList(config);
-
-            return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
-        });
-    });
-}
-
-//------------------------------------------------------------------------------
-// Public Interface
-//------------------------------------------------------------------------------
-
-const init = {
-    getModulesList,
-    hasESLintVersionConflict,
-    installModules,
-    processAnswers,
-    writeFile,
-    /* istanbul ignore next */initializeConfig() {
-        return promptUser();
-    }
-};
-
-module.exports = init;
diff --git a/lib/init/npm-utils.js b/lib/init/npm-utils.js
deleted file mode 100644
index 4a8efe964..000000000
--- a/lib/init/npm-utils.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * @fileoverview Utility for executing npm commands.
- * @author Ian VanSchooten
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const fs = require("fs"),
-    spawn = require("cross-spawn"),
-    path = require("path"),
-    log = require("../shared/logging");
-
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-/**
- * Find the closest package.json file, starting at process.cwd (by default),
- * and working up to root.
- * @param {string} [startDir=process.cwd()] Starting directory
- * @returns {string} Absolute path to closest package.json file
- */
-function findPackageJson(startDir) {
-    let dir = path.resolve(startDir || process.cwd());
-
-    do {
-        const pkgFile = path.join(dir, "package.json");
-
-        if (!fs.existsSync(pkgFile) || !fs.statSync(pkgFile).isFile()) {
-            dir = path.join(dir, "..");
-            continue;
-        }
-        return pkgFile;
-    } while (dir !== path.resolve(dir, ".."));
-    return null;
-}
-
-//------------------------------------------------------------------------------
-// Private
-//------------------------------------------------------------------------------
-
-/**
- * Install node modules synchronously and save to devDependencies in package.json
- * @param {string|string[]} packages Node module or modules to install
- * @returns {void}
- */
-function installSyncSaveDev(packages) {
-    const packageList = Array.isArray(packages) ? packages : [packages];
-    const npmProcess = spawn.sync("npm", ["i", "--save-dev"].concat(packageList), { stdio: "inherit" });
-    const error = npmProcess.error;
-
-    if (error && error.code === "ENOENT") {
-        const pluralS = packageList.length > 1 ? "s" : "";
-
-        log.error(`Could not execute npm. Please install the following package${pluralS} with a package manager of your choice: ${packageList.join(", ")}`);
-    }
-}
-
-/**
- * Fetch `peerDependencies` of the given package by `npm show` command.
- * @param {string} packageName The package name to fetch peerDependencies.
- * @returns {Object} Gotten peerDependencies. Returns null if npm was not found.
- */
-function fetchPeerDependencies(packageName) {
-    const npmProcess = spawn.sync(
-        "npm",
-        ["show", "--json", packageName, "peerDependencies"],
-        { encoding: "utf8" }
-    );
-
-    const error = npmProcess.error;
-
-    if (error && error.code === "ENOENT") {
-        return null;
-    }
-    const fetchedText = npmProcess.stdout.trim();
-
-    return JSON.parse(fetchedText || "{}");
-
-
-}
-
-/**
- * Check whether node modules are include in a project's package.json.
- * @param {string[]} packages Array of node module names
- * @param {Object} opt Options Object
- * @param {boolean} opt.dependencies Set to true to check for direct dependencies
- * @param {boolean} opt.devDependencies Set to true to check for development dependencies
- * @param {boolean} opt.startdir Directory to begin searching from
- * @throws {Error} If cannot find valid `package.json` file.
- * @returns {Object} An object whose keys are the module names
- *                                        and values are booleans indicating installation.
- */
-function check(packages, opt) {
-    const deps = new Set();
-    const pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson();
-    let fileJson;
-
-    if (!pkgJson) {
-        throw new Error("Could not find a package.json file. Run 'npm init' to create one.");
-    }
-
-    try {
-        fileJson = JSON.parse(fs.readFileSync(pkgJson, "utf8"));
-    } catch (e) {
-        const error = new Error(e);
-
-        error.messageTemplate = "failed-to-read-json";
-        error.messageData = {
-            path: pkgJson,
-            message: e.message
-        };
-        throw error;
-    }
-
-    ["dependencies", "devDependencies"].forEach(key => {
-        if (opt[key] && typeof fileJson[key] === "object") {
-            Object.keys(fileJson[key]).forEach(dep => deps.add(dep));
-        }
-    });
-
-    return packages.reduce((status, pkg) => {
-        status[pkg] = deps.has(pkg);
-        return status;
-    }, {});
-}
-
-/**
- * Check whether node modules are included in the dependencies of a project's
- * package.json.
- *
- * Convenience wrapper around check().
- * @param {string[]} packages Array of node modules to check.
- * @param {string} rootDir The directory containing a package.json
- * @returns {Object} An object whose keys are the module names
- *                               and values are booleans indicating installation.
- */
-function checkDeps(packages, rootDir) {
-    return check(packages, { dependencies: true, startDir: rootDir });
-}
-
-/**
- * Check whether node modules are included in the devDependencies of a project's
- * package.json.
- *
- * Convenience wrapper around check().
- * @param {string[]} packages Array of node modules to check.
- * @returns {Object} An object whose keys are the module names
- *                               and values are booleans indicating installation.
- */
-function checkDevDeps(packages) {
-    return check(packages, { devDependencies: true });
-}
-
-/**
- * Check whether package.json is found in current path.
- * @param {string} [startDir] Starting directory
- * @returns {boolean} Whether a package.json is found in current path.
- */
-function checkPackageJson(startDir) {
-    return !!findPackageJson(startDir);
-}
-
-//------------------------------------------------------------------------------
-// Public Interface
-//------------------------------------------------------------------------------
-
-module.exports = {
-    installSyncSaveDev,
-    fetchPeerDependencies,
-    findPackageJson,
-    checkDeps,
-    checkDevDeps,
-    checkPackageJson
-};
diff --git a/lib/init/source-code-utils.js b/lib/init/source-code-utils.js
deleted file mode 100644
index 08c20e5d5..000000000
--- a/lib/init/source-code-utils.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @fileoverview Tools for obtaining SourceCode objects.
- * @author Ian VanSchooten
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const { CLIEngine } = require("../cli-engine");
-
-/*
- * This is used for:
- *
- * 1. Enumerate target file because we have not expose such a API on `CLIEngine`
- *    (https://github.com/eslint/eslint/issues/11222).
- * 2. Create `SourceCode` instances. Because we don't have any function which
- *    instantiate `SourceCode` so it needs to take the created `SourceCode`
- *    instance out after linting.
- *
- * TODO1: Expose the API that enumerates target files.
- * TODO2: Extract the creation logic of `SourceCode` from `Linter` class.
- */
-const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require -- Todo
-
-const debug = require("debug")("eslint:source-code-utils");
-
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-/**
- * Get the SourceCode object for a single file
- * @param {string} filename The fully resolved filename to get SourceCode from.
- * @param {Object} engine A CLIEngine.
- * @throws {Error} Upon fatal errors from execution.
- * @returns {Array} Array of the SourceCode object representing the file
- *                                and fatal error message.
- */
-function getSourceCodeOfFile(filename, engine) {
-    debug("getting sourceCode of", filename);
-    const results = engine.executeOnFiles([filename]);
-
-    if (results && results.results[0] && results.results[0].messages[0] && results.results[0].messages[0].fatal) {
-        const msg = results.results[0].messages[0];
-
-        throw new Error(`(${filename}:${msg.line}:${msg.column}) ${msg.message}`);
-    }
-
-    // TODO: extract the logic that creates source code objects to `SourceCode#parse(text, options)` or something like.
-    const { linter } = getCLIEngineInternalSlots(engine);
-    const sourceCode = linter.getSourceCode();
-
-    return sourceCode;
-}
-
-//------------------------------------------------------------------------------
-// Public Interface
-//------------------------------------------------------------------------------
-
-
-/**
- * This callback is used to measure execution status in a progress bar
- * @callback progressCallback
- * @param {number} The total number of times the callback will be called.
- */
-
-/**
- * Gets the SourceCode of a single file, or set of files.
- * @param {string[]|string} patterns A filename, directory name, or glob, or an array of them
- * @param {Object} options A CLIEngine options object. If not provided, the default cli options will be used.
- * @param {progressCallback} callback Callback for reporting execution status
- * @returns {Object} The SourceCode of all processed files.
- */
-function getSourceCodeOfFiles(patterns, options, callback) {
-    const sourceCodes = {};
-    const globPatternsList = typeof patterns === "string" ? [patterns] : patterns;
-    const engine = new CLIEngine({ ...options, rules: {} });
-
-    // TODO: make file iteration as a public API and use it.
-    const { fileEnumerator } = getCLIEngineInternalSlots(engine);
-    const filenames =
-        Array.from(fileEnumerator.iterateFiles(globPatternsList))
-            .filter(entry => !entry.ignored)
-            .map(entry => entry.filePath);
-
-    if (filenames.length === 0) {
-        debug(`Did not find any files matching pattern(s): ${globPatternsList}`);
-    }
-
-    filenames.forEach(filename => {
-        const sourceCode = getSourceCodeOfFile(filename, engine);
-
-        if (sourceCode) {
-            debug("got sourceCode of", filename);
-            sourceCodes[filename] = sourceCode;
-        }
-        if (callback) {
-            callback(filenames.length); // eslint-disable-line node/callback-return -- End of function
-        }
-    });
-
-    return sourceCodes;
-}
-
-module.exports = {
-    getSourceCodeOfFiles
-};
diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js
index 61dd062ed..6bb1838a7 100644
--- a/lib/rules/camelcase.js
+++ b/lib/rules/camelcase.js
@@ -5,6 +5,12 @@
 
 "use strict";
 
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils");
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -165,7 +171,7 @@ module.exports = {
                 case "ImportSpecifier":
                     return (
                         parent.local === node &&
-                        parent.imported.name === localName
+                        astUtils.getModuleExportName(parent.imported) === localName
                     );
 
                 default:
diff --git a/lib/rules/id-match.js b/lib/rules/id-match.js
index 977e66a26..8713a5f9f 100644
--- a/lib/rules/id-match.js
+++ b/lib/rules/id-match.js
@@ -250,7 +250,7 @@ module.exports = {
                     }
 
                     // never check properties or always ignore destructuring
-                    if (!checkProperties || (ignoreDestructuring && isInsideObjectPattern(node))) {
+                    if ((!checkProperties && !parent.computed) || (ignoreDestructuring && isInsideObjectPattern(node))) {
                         return;
                     }
 
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index 6813037f1..455cc336c 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -4,6 +4,12 @@
  */
 "use strict";
 
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils");
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -269,12 +275,12 @@ module.exports = {
                     } else if (specifier.type === "ImportNamespaceSpecifier") {
                         name = "*";
                     } else if (specifier.imported) {
-                        name = specifier.imported.name;
+                        name = astUtils.getModuleExportName(specifier.imported);
                     } else if (specifier.local) {
-                        name = specifier.local.name;
+                        name = astUtils.getModuleExportName(specifier.local);
                     }
 
-                    if (name) {
+                    if (typeof name === "string") {
                         if (importNames.has(name)) {
                             importNames.get(name).push(specifierData);
                         } else {
diff --git a/lib/rules/no-useless-rename.js b/lib/rules/no-useless-rename.js
index 616ec2a43..2489f57bc 100644
--- a/lib/rules/no-useless-rename.js
+++ b/lib/rules/no-useless-rename.js
@@ -132,8 +132,10 @@ module.exports = {
                 return;
             }
 
-            if (node.imported.name === node.local.name &&
-                    node.imported.range[0] !== node.local.range[0]) {
+            if (
+                node.imported.range[0] !== node.local.range[0] &&
+                astUtils.getModuleExportName(node.imported) === node.local.name
+            ) {
                 reportError(node, node.imported, "Import");
             }
         }
@@ -148,8 +150,10 @@ module.exports = {
                 return;
             }
 
-            if (node.local.name === node.exported.name &&
-                    node.local.range[0] !== node.exported.range[0]) {
+            if (
+                node.local.range[0] !== node.exported.range[0] &&
+                astUtils.getModuleExportName(node.local) === astUtils.getModuleExportName(node.exported)
+            ) {
                 reportError(node, node.local, "Export");
             }
 
diff --git a/messages/no-config-found.js b/messages/no-config-found.js
index 1042143f9..c2f7ac73b 100644
--- a/messages/no-config-found.js
+++ b/messages/no-config-found.js
@@ -6,7 +6,7 @@ module.exports = function(it) {
     return `
 ESLint couldn't find a configuration file. To set up a configuration file for this project, please run:
 
-    eslint --init
+    npm init @eslint/config
 
 ESLint looked for configuration files in ${directoryPath} and its ancestors. If it found none, it then looked in your home directory.
 
diff --git a/package.json b/package.json
index 948d8d959..3cb6cea42 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,6 @@
     "cross-spawn": "^7.0.2",
     "debug": "^4.3.2",
     "doctrine": "^3.0.0",
-    "enquirer": "^2.3.5",
     "escape-string-regexp": "^4.0.0",
     "eslint-scope": "^7.1.0",
     "eslint-utils": "^3.0.0",
@@ -78,9 +77,7 @@
     "minimatch": "^3.0.4",
     "natural-compare": "^1.4.0",
     "optionator": "^0.9.1",
-    "progress": "^2.0.0",
     "regexpp": "^3.2.0",
-    "semver": "^7.2.1",
     "strip-ansi": "^6.0.1",
     "strip-json-comments": "^3.1.0",
     "text-table": "^0.2.0",
@@ -125,10 +122,12 @@
     "node-polyfill-webpack-plugin": "^1.0.3",
     "npm-license": "^0.3.3",
     "nyc": "^15.0.1",
+    "progress": "^2.0.3",
     "proxyquire": "^2.0.1",
     "puppeteer": "^9.1.1",
     "recast": "^0.20.4",
     "regenerator-runtime": "^0.13.2",
+    "semver": "^7.3.5",
     "shelljs": "^0.8.2",
     "sinon": "^11.0.0",
     "temp": "^0.9.0",
diff --git a/lib/init/config-rule.js b/tools/config-rule.js
similarity index 99%
rename from lib/init/config-rule.js
rename to tools/config-rule.js
index 131e84a60..91e7eaef5 100644
--- a/lib/init/config-rule.js
+++ b/tools/config-rule.js
@@ -9,7 +9,7 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const builtInRules = require("../rules");
+const builtInRules = require("../lib/rules");
 
 //------------------------------------------------------------------------------
 // Helpers
diff --git a/tools/eslint-fuzzer.js b/tools/eslint-fuzzer.js
index 6c5ed9b1b..d951ad337 100644
--- a/tools/eslint-fuzzer.js
+++ b/tools/eslint-fuzzer.js
@@ -13,7 +13,7 @@ const assert = require("assert");
 const eslump = require("eslump");
 const espree = require("espree");
 const SourceCodeFixer = require("../lib/linter/source-code-fixer");
-const ruleConfigs = require("../lib/init/config-rule").createCoreRuleConfigs(true);
+const ruleConfigs = require("./config-rule").createCoreRuleConfigs(true);
 const sampleMinimizer = require("./code-sample-minimizer");
 
 //------------------------------------------------------------------------------


Test patch:
diff --git a/tests/fixtures/autoconfig/source-with-comments.js b/tests/fixtures/autoconfig/source-with-comments.js
deleted file mode 100644
index d2e3bf9a6..000000000
--- a/tests/fixtures/autoconfig/source-with-comments.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* eslint semi: [2, "never"] */
-/* eslint import/extensions: 2 */
-
-var foo = 42;
-var baz = "baz";
-var bar = '"no-escape"';
diff --git a/tests/fixtures/autoconfig/source.js b/tests/fixtures/autoconfig/source.js
deleted file mode 100644
index 0c126ba6d..000000000
--- a/tests/fixtures/autoconfig/source.js
+++ /dev/null
@@ -1,3 +0,0 @@
-var foo = 42;
-var baz = "baz";
-var bar = '"no-escape"';
diff --git a/tests/fixtures/config-initializer/lib/doubleQuotes.js b/tests/fixtures/config-initializer/lib/doubleQuotes.js
deleted file mode 100644
index 1cd4a2abb..000000000
--- a/tests/fixtures/config-initializer/lib/doubleQuotes.js
+++ /dev/null
@@ -1,1 +0,0 @@
-var foo = "doubleQuotes";
diff --git a/tests/fixtures/config-initializer/lib/no-semi.js b/tests/fixtures/config-initializer/lib/no-semi.js
deleted file mode 100644
index bf10b1cfd..000000000
--- a/tests/fixtures/config-initializer/lib/no-semi.js
+++ /dev/null
@@ -1,1 +0,0 @@
-var name = "ESLint"
diff --git a/tests/fixtures/config-initializer/new-es-features/new-es-features.js b/tests/fixtures/config-initializer/new-es-features/new-es-features.js
deleted file mode 100644
index c3e03fc32..000000000
--- a/tests/fixtures/config-initializer/new-es-features/new-es-features.js
+++ /dev/null
@@ -1,3 +0,0 @@
-async function fn() {
-    await Promise.resolve();
-}
diff --git a/tests/fixtures/config-initializer/parse-error/parse-error.js b/tests/fixtures/config-initializer/parse-error/parse-error.js
deleted file mode 100644
index 90bd920ce..000000000
--- a/tests/fixtures/config-initializer/parse-error/parse-error.js
+++ /dev/null
@@ -1,1 +0,0 @@
-+;
diff --git a/tests/fixtures/config-initializer/singleQuotes.js b/tests/fixtures/config-initializer/singleQuotes.js
deleted file mode 100644
index db1e01fed..000000000
--- a/tests/fixtures/config-initializer/singleQuotes.js
+++ /dev/null
@@ -1,1 +0,0 @@
-var foo = 'singleQuotes';
diff --git a/tests/fixtures/config-initializer/tests/console-log.js b/tests/fixtures/config-initializer/tests/console-log.js
deleted file mode 100644
index 929e82a14..000000000
--- a/tests/fixtures/config-initializer/tests/console-log.js
+++ /dev/null
@@ -1,1 +0,0 @@
-console.log("I'm a log");
diff --git a/tests/fixtures/config-initializer/tests/doubleQuotes.js b/tests/fixtures/config-initializer/tests/doubleQuotes.js
deleted file mode 100644
index 1cd4a2abb..000000000
--- a/tests/fixtures/config-initializer/tests/doubleQuotes.js
+++ /dev/null
@@ -1,1 +0,0 @@
-var foo = "doubleQuotes";
diff --git a/tests/lib/init/autoconfig.js b/tests/lib/init/autoconfig.js
deleted file mode 100644
index 3db6a6364..000000000
--- a/tests/lib/init/autoconfig.js
+++ /dev/null
@@ -1,385 +0,0 @@
-/**
- * @fileoverview Used for creating a suggested configuration based on project code.
- * @author Ian VanSchooten
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const assert = require("chai").assert,
-    autoconfig = require("../../../lib/init/autoconfig"),
-    sourceCodeUtils = require("../../../lib/init/source-code-utils"),
-    baseDefaultOptions = require("../../../conf/default-cli-options"),
-    recommendedConfig = require("../../conf/eslint-recommended");
-
-const defaultOptions = Object.assign({}, baseDefaultOptions, { cwd: process.cwd() });
-
-//------------------------------------------------------------------------------
-// Data
-//------------------------------------------------------------------------------
-
-const SOURCE_CODE_FIXTURE_FILENAME = "./tests/fixtures/autoconfig/source.js";
-const CONFIG_COMMENTS_FILENAME = "./tests/fixtures/autoconfig/source-with-comments.js";
-const SEVERITY = 2;
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-const rulesConfig = {
-    semi: [SEVERITY, [SEVERITY, "always"], [SEVERITY, "never"]],
-    "semi-spacing": [SEVERITY,
-        [SEVERITY, { before: true, after: true }],
-        [SEVERITY, { before: true, after: false }],
-        [SEVERITY, { before: false, after: true }],
-        [SEVERITY, { before: false, after: false }]
-    ],
-    quotes: [SEVERITY,
-        [SEVERITY, "single"],
-        [SEVERITY, "double"],
-        [SEVERITY, "backtick"],
-        [SEVERITY, "single", "avoid-escape"],
-        [SEVERITY, "double", "avoid-escape"],
-        [SEVERITY, "backtick", "avoid-escape"]]
-};
-
-const errorRulesConfig = {
-    "no-unused-vars": [SEVERITY],
-    "semi-spacing": [SEVERITY,
-        [SEVERITY, { before: true, after: true }],
-        [SEVERITY, { before: true, after: false }],
-        [SEVERITY, { before: false, after: true }],
-        [SEVERITY, { before: false, after: false }]
-    ]
-};
-
-describe("autoconfig", () => {
-
-    describe("Registry", () => {
-
-        it("should set up a registry for rules in a provided rulesConfig", () => {
-            const expectedRules = Object.keys(rulesConfig);
-            const registry = new autoconfig.Registry(rulesConfig);
-
-            assert.strictEqual(Object.keys(registry.rules).length, 3);
-            assert.sameMembers(Object.keys(registry.rules), expectedRules);
-            assert.isArray(registry.rules.semi);
-            assert.isArray(registry.rules["semi-spacing"]);
-            assert.isArray(registry.rules.quotes);
-            assert.lengthOf(registry.rules.semi, 3);
-            assert.lengthOf(registry.rules["semi-spacing"], 5);
-            assert.lengthOf(registry.rules.quotes, 7);
-        });
-
-        it("should not have any rules if constructed without a config argument", () => {
-            const registry = new autoconfig.Registry();
-
-            assert.isObject(registry.rules);
-            assert.lengthOf(Object.keys(registry.rules), 0);
-        });
-
-        it("should create registryItems for each rule with the proper keys", () => {
-            const registry = new autoconfig.Registry(rulesConfig);
-
-            assert.isObject(registry.rules.semi[0]);
-            assert.isObject(registry.rules["semi-spacing"][0]);
-            assert.isObject(registry.rules.quotes[0]);
-            assert.property(registry.rules.semi[0], "config");
-            assert.property(registry.rules.semi[0], "specificity");
-            assert.property(registry.rules.semi[0], "errorCount");
-        });
-
-        it("should populate the config property correctly", () => {
-            const registry = new autoconfig.Registry(rulesConfig);
-
-            assert.strictEqual(registry.rules.quotes[0].config, SEVERITY);
-            assert.deepStrictEqual(registry.rules.quotes[1].config, [SEVERITY, "single"]);
-            assert.deepStrictEqual(registry.rules.quotes[2].config, [SEVERITY, "double"]);
-            assert.deepStrictEqual(registry.rules.quotes[3].config, [SEVERITY, "backtick"]);
-            assert.deepStrictEqual(registry.rules.quotes[4].config, [SEVERITY, "single", "avoid-escape"]);
-            assert.deepStrictEqual(registry.rules.quotes[5].config, [SEVERITY, "double", "avoid-escape"]);
-            assert.deepStrictEqual(registry.rules.quotes[6].config, [SEVERITY, "backtick", "avoid-escape"]);
-        });
-
-        it("should assign the correct specificity", () => {
-            const registry = new autoconfig.Registry(rulesConfig);
-
-            assert.strictEqual(registry.rules.quotes[0].specificity, 1);
-            assert.strictEqual(registry.rules.quotes[1].specificity, 2);
-            assert.strictEqual(registry.rules.quotes[6].specificity, 3);
-        });
-
-        it("should initially leave the errorCount as undefined", () => {
-            const registry = new autoconfig.Registry(rulesConfig);
-
-            assert.isUndefined(registry.rules.quotes[0].errorCount);
-            assert.isUndefined(registry.rules.quotes[1].errorCount);
-            assert.isUndefined(registry.rules.quotes[6].errorCount);
-        });
-
-        describe("populateFromCoreRules()", () => {
-
-            it("should add core rules to registry", () => {
-                const registry = new autoconfig.Registry();
-
-                registry.populateFromCoreRules();
-                const finalRuleCount = Object.keys(registry.rules).length;
-
-                assert(finalRuleCount > 0);
-                assert.include(Object.keys(registry.rules), "eqeqeq");
-            });
-
-            it("should not add deprecated rules", () => {
-                const registry = new autoconfig.Registry();
-
-                registry.populateFromCoreRules();
-
-                const { rules } = registry;
-
-                assert.notProperty(rules, "id-blacklist");
-                assert.notProperty(rules, "no-negated-in-lhs");
-                assert.notProperty(rules, "no-process-exit");
-                assert.notProperty(rules, "no-spaced-func");
-                assert.notProperty(rules, "prefer-reflect");
-            });
-
-            it("should not add duplicate rules", () => {
-                const registry = new autoconfig.Registry(rulesConfig);
-
-                registry.populateFromCoreRules();
-                const semiCount = Object.keys(registry.rules).filter(ruleId => ruleId === "semi").length;
-
-                assert.strictEqual(semiCount, 1);
-            });
-        });
-
-        describe("buildRuleSets()", () => {
-            let ruleSets;
-
-            beforeEach(() => {
-                const registry = new autoconfig.Registry(rulesConfig);
-
-                ruleSets = registry.buildRuleSets();
-            });
-
-            it("should create an array of rule configuration sets", () => {
-                assert.isArray(ruleSets);
-            });
-
-            it("should include configs for each rule (at least for the first set)", () => {
-                assert.sameMembers(Object.keys(ruleSets[0]), ["semi", "semi-spacing", "quotes"]);
-            });
-
-            it("should create the first set from default rule configs (severity only)", () => {
-                assert.deepStrictEqual(ruleSets[0], { semi: SEVERITY, "semi-spacing": SEVERITY, quotes: SEVERITY });
-            });
-
-            it("should create as many ruleSets as the highest number of configs in a rule", () => {
-
-                // `quotes` has 7 possible configurations
-                assert.lengthOf(ruleSets, 7);
-            });
-        });
-
-        describe("lintSourceCode()", () => {
-            let registry;
-
-            beforeEach(() => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(SOURCE_CODE_FIXTURE_FILENAME, config);
-
-                registry = new autoconfig.Registry(rulesConfig);
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-            });
-
-            it("should populate the errorCount of all registryItems", () => {
-                const expectedRules = ["semi", "semi-spacing", "quotes"];
-
-                assert.sameMembers(Object.keys(registry.rules), expectedRules);
-                expectedRules.forEach(ruleId => {
-                    assert(registry.rules[ruleId].length > 0);
-                    registry.rules[ruleId].forEach(conf => {
-                        assert.isNumber(conf.errorCount);
-                    });
-                });
-            });
-
-            it("should correctly set the error count of configurations", () => {
-                assert.strictEqual(registry.rules.semi[0].config, SEVERITY);
-                assert.strictEqual(registry.rules.semi[0].errorCount, 0);
-                assert.deepStrictEqual(registry.rules.semi[2].config, [SEVERITY, "never"]);
-                assert.strictEqual(registry.rules.semi[2].errorCount, 3);
-            });
-
-            it("should respect inline eslint config comments (and not crash when they make linting errors)", () => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(CONFIG_COMMENTS_FILENAME, config);
-                const expectedRegistry = [
-                    { config: 2, specificity: 1, errorCount: 3 },
-                    { config: [2, "always"], specificity: 2, errorCount: 3 },
-                    { config: [2, "never"], specificity: 2, errorCount: 3 }
-                ];
-
-                registry = new autoconfig.Registry(rulesConfig);
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-
-                assert.deepStrictEqual(registry.rules.semi, expectedRegistry);
-            });
-        });
-
-        describe("stripFailingConfigs()", () => {
-            let registry;
-
-            beforeEach(() => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(SOURCE_CODE_FIXTURE_FILENAME, config);
-
-                registry = new autoconfig.Registry(rulesConfig);
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-                registry = registry.stripFailingConfigs();
-            });
-
-            it("should remove all registryItems with a non-zero errorCount", () => {
-                assert.lengthOf(registry.rules.semi, 2);
-                assert.lengthOf(registry.rules["semi-spacing"], 3);
-                assert.lengthOf(registry.rules.quotes, 1);
-                registry.rules.semi.forEach(registryItem => {
-                    assert.strictEqual(registryItem.errorCount, 0);
-                });
-                registry.rules["semi-spacing"].forEach(registryItem => {
-                    assert.strictEqual(registryItem.errorCount, 0);
-                });
-                registry.rules.quotes.forEach(registryItem => {
-                    assert.strictEqual(registryItem.errorCount, 0);
-                });
-            });
-        });
-
-        describe("getFailingRulesRegistry()", () => {
-            let failingRegistry;
-
-            beforeEach(() => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(SOURCE_CODE_FIXTURE_FILENAME, config);
-                let registry = new autoconfig.Registry(errorRulesConfig);
-
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-                failingRegistry = registry.getFailingRulesRegistry();
-            });
-
-            it("should return a registry with no registryItems with an errorCount of zero", () => {
-                const failingRules = Object.keys(failingRegistry.rules);
-
-                assert.deepStrictEqual(failingRules, ["no-unused-vars"]);
-                assert.lengthOf(failingRegistry.rules["no-unused-vars"], 1);
-                assert(failingRegistry.rules["no-unused-vars"][0].errorCount > 0);
-            });
-        });
-
-        describe("createConfig()", () => {
-            let createdConfig;
-
-            beforeEach(() => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(SOURCE_CODE_FIXTURE_FILENAME, config);
-                let registry = new autoconfig.Registry(rulesConfig);
-
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-                registry = registry.stripFailingConfigs();
-                createdConfig = registry.createConfig();
-            });
-
-            it("should create a config with a rules property", () => {
-                assert.property(createdConfig, "rules");
-            });
-
-            it("should add rules which have only one registryItem to the config", () => {
-                const configuredRules = Object.keys(createdConfig.rules);
-
-                assert.deepStrictEqual(configuredRules, ["quotes"]);
-            });
-
-            it("should set the configuration of the rule to the registryItem's `config` value", () => {
-                assert.deepStrictEqual(createdConfig.rules.quotes, [2, "double", "avoid-escape"]);
-            });
-
-            it("should not care how many errors the config has", () => {
-                const config = { ignore: false };
-                const sourceCode = sourceCodeUtils.getSourceCodeOfFiles(SOURCE_CODE_FIXTURE_FILENAME, config);
-                let registry = new autoconfig.Registry(errorRulesConfig);
-
-                registry = registry.lintSourceCode(sourceCode, defaultOptions);
-                const failingRegistry = registry.getFailingRulesRegistry();
-
-                createdConfig = failingRegistry.createConfig();
-                const configuredRules = Object.keys(createdConfig.rules);
-
-                assert.deepStrictEqual(configuredRules, ["no-unused-vars"]);
-            });
-        });
-
-        describe("filterBySpecificity()", () => {
-            let registry;
-
-            beforeEach(() => {
-                registry = new autoconfig.Registry(rulesConfig);
-            });
-
-            it("should return a registry where all configs have a desired specificity", () => {
-                const filteredRegistry1 = registry.filterBySpecificity(1);
-                const filteredRegistry2 = registry.filterBySpecificity(2);
-                const filteredRegistry3 = registry.filterBySpecificity(3);
-
-                assert.lengthOf(filteredRegistry1.rules.semi, 1);
-                assert.lengthOf(filteredRegistry1.rules["semi-spacing"], 1);
-                assert.lengthOf(filteredRegistry1.rules.quotes, 1);
-                assert.lengthOf(filteredRegistry2.rules.semi, 2);
-                assert.lengthOf(filteredRegistry2.rules["semi-spacing"], 4);
-                assert.lengthOf(filteredRegistry2.rules.quotes, 3);
-                assert.lengthOf(filteredRegistry3.rules.quotes, 3);
-            });
-        });
-    });
-
-    describe("extendFromRecommended()", () => {
-        it("should return a configuration which has `extends` key with Array type value", () => {
-            const oldConfig = { extends: [], rules: {} };
-            const newConfig = autoconfig.extendFromRecommended(oldConfig);
-
-            assert.exists(newConfig.extends);
-            assert.isArray(newConfig.extends);
-        });
-
-        it("should return a configuration which has array property `extends`", () => {
-            const oldConfig = { extends: [], rules: {} };
-            const newConfig = autoconfig.extendFromRecommended(oldConfig);
-
-            assert.include(newConfig.extends, "eslint:recommended");
-        });
-
-        it("should return a configuration which preserves the previous extending configurations", () => {
-            const oldConfig = { extends: ["previous:configuration1", "previous:configuration2"], rules: {} };
-            const newConfig = autoconfig.extendFromRecommended(oldConfig);
-
-            assert.includeMembers(newConfig.extends, oldConfig.extends);
-        });
-
-        it("should return a configuration which has `eslint:recommended` at the first of `extends`", () => {
-            const oldConfig = { extends: ["previous:configuration1", "previous:configuration2"], rules: {} };
-            const newConfig = autoconfig.extendFromRecommended(oldConfig);
-            const [firstExtendInNewConfig] = newConfig.extends;
-
-            assert.strictEqual(firstExtendInNewConfig, "eslint:recommended");
-        });
-
-        it("should return a configuration which not includes rules configured in `eslint:recommended`", () => {
-            const oldConfig = { extends: [], rules: { ...recommendedConfig.rules } };
-            const newConfig = autoconfig.extendFromRecommended(oldConfig);
-
-            assert.notInclude(newConfig.rules, oldConfig.rules);
-        });
-    });
-});
diff --git a/tests/lib/init/config-file.js b/tests/lib/init/config-file.js
deleted file mode 100644
index 50a9af1d5..000000000
--- a/tests/lib/init/config-file.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * @fileoverview Tests for ConfigFile
- * @author Nicholas C. Zakas
- */
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const assert = require("chai").assert,
-    sinon = require("sinon"),
-    path = require("path"),
-    yaml = require("js-yaml"),
-    espree = require("espree"),
-    ConfigFile = require("../../../lib/init/config-file"),
-    { CLIEngine } = require("../../../lib/cli-engine");
-
-const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
-
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-/**
- * Helper function get easily get a path in the fixtures directory.
- * @param {string} filepath The path to find in the fixtures directory.
- * @returns {string} Full path in the fixtures directory.
- * @private
- */
-function getFixturePath(filepath) {
-    return path.resolve(__dirname, "../../fixtures/config-file", filepath);
-}
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-describe("ConfigFile", () => {
-    describe("write()", () => {
-        let config;
-
-        beforeEach(() => {
-            config = {
-                env: {
-                    browser: true,
-                    node: true
-                },
-                rules: {
-                    quotes: 2,
-                    semi: 1
-                }
-            };
-        });
-
-        afterEach(() => {
-            sinon.verifyAndRestore();
-        });
-
-        [
-            ["JavaScript", "foo.js", espree.parse],
-            ["JSON", "bar.json", JSON.parse],
-            ["YAML", "foo.yaml", yaml.load],
-            ["YML", "foo.yml", yaml.load]
-        ].forEach(([fileType, filename, validate]) => {
-
-            it(`should write a file through fs when a ${fileType} path is passed`, () => {
-                const fakeFS = {
-                    writeFileSync: () => {}
-                };
-
-                sinon.mock(fakeFS).expects("writeFileSync").withExactArgs(
-                    filename,
-                    sinon.match(value => !!validate(value)),
-                    "utf8"
-                );
-
-                const StubbedConfigFile = proxyquire("../../../lib/init/config-file", {
-                    fs: fakeFS
-                });
-
-                StubbedConfigFile.write(config, filename);
-            });
-
-            it("should include a newline character at EOF", () => {
-                const fakeFS = {
-                    writeFileSync: () => {}
-                };
-
-                sinon.mock(fakeFS).expects("writeFileSync").withExactArgs(
-                    filename,
-                    sinon.match(value => value.endsWith("\n")),
-                    "utf8"
-                );
-
-                const StubbedConfigFile = proxyquire("../../../lib/init/config-file", {
-                    fs: fakeFS
-                });
-
-                StubbedConfigFile.write(config, filename);
-            });
-        });
-
-        it("should make sure js config files match linting rules", () => {
-            const fakeFS = {
-                writeFileSync: () => {}
-            };
-
-            const singleQuoteConfig = {
-                rules: {
-                    quotes: [2, "single"]
-                }
-            };
-
-            sinon.mock(fakeFS).expects("writeFileSync").withExactArgs(
-                "test-config.js",
-                sinon.match(value => !value.includes("\"")),
-                "utf8"
-            );
-
-            const StubbedConfigFile = proxyquire("../../../lib/init/config-file", {
-                fs: fakeFS
-            });
-
-            StubbedConfigFile.write(singleQuoteConfig, "test-config.js");
-        });
-
-        it("should still write a js config file even if linting fails", () => {
-            const fakeFS = {
-                writeFileSync: () => {}
-            };
-            const fakeCLIEngine = sinon.mock().withExactArgs(sinon.match({
-                baseConfig: config,
-                fix: true,
-                useEslintrc: false
-            }));
-
-            Object.defineProperties(fakeCLIEngine.prototype, Object.getOwnPropertyDescriptors(CLIEngine.prototype));
-            sinon.stub(fakeCLIEngine.prototype, "executeOnText").throws();
-
-            sinon.mock(fakeFS).expects("writeFileSync").once();
-
-            const StubbedConfigFile = proxyquire("../../../lib/init/config-file", {
-                fs: fakeFS,
-                "../cli-engine": { CLIEngine: fakeCLIEngine }
-            });
-
-            assert.throws(() => {
-                StubbedConfigFile.write(config, "test-config.js");
-            });
-        });
-
-        it("should throw error if file extension is not valid", () => {
-            assert.throws(() => {
-                ConfigFile.write({}, getFixturePath("yaml/.eslintrc.class"));
-            }, /write to unknown file type/u);
-        });
-    });
-});
diff --git a/tests/lib/init/config-initializer.js b/tests/lib/init/config-initializer.js
deleted file mode 100644
index 81e4e52fa..000000000
--- a/tests/lib/init/config-initializer.js
+++ /dev/null
@@ -1,577 +0,0 @@
-/**
- * @fileoverview Tests for configInitializer.
- * @author Ilya Volodin
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const assert = require("chai").assert,
-    fs = require("fs"),
-    path = require("path"),
-    os = require("os"),
-    sinon = require("sinon"),
-    sh = require("shelljs"),
-    espree = require("espree"),
-    autoconfig = require("../../../lib/init/autoconfig"),
-    npmUtils = require("../../../lib/init/npm-utils");
-
-const originalDir = process.cwd();
-const proxyquire = require("proxyquire").noPreserveCache();
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-let answers = {};
-let pkgJSONContents = {};
-let pkgJSONPath = "";
-
-describe("configInitializer", () => {
-
-    let fixtureDir,
-        npmCheckStub,
-        npmInstallStub,
-        npmFetchPeerDependenciesStub,
-        init,
-        localESLintVersion = null;
-
-    const log = {
-        info: sinon.spy(),
-        error: sinon.spy()
-    };
-    const requireStubs = {
-        "../shared/logging": log,
-        "../shared/relative-module-resolver": {
-            resolve() {
-                if (localESLintVersion) {
-                    return `local-eslint-${localESLintVersion}`;
-                }
-                throw new Error("Cannot find module");
-            }
-        },
-        "local-eslint-3.18.0": { linter: { version: "3.18.0" }, "@noCallThru": true },
-        "local-eslint-3.19.0": { linter: { version: "3.19.0" }, "@noCallThru": true },
-        "local-eslint-4.0.0": { linter: { version: "4.0.0" }, "@noCallThru": true }
-    };
-
-    /**
-     * Returns the path inside of the fixture directory.
-     * @param {...string} args file path segments.
-     * @returns {string} The path inside the fixture directory.
-     * @private
-     */
-    function getFixturePath(...args) {
-        const filepath = path.join(fixtureDir, ...args);
-
-        try {
-            return fs.realpathSync(filepath);
-        } catch {
-            return filepath;
-        }
-    }
-
-    // copy into clean area so as not to get "infected" by this project's .eslintrc files
-    before(() => {
-        fixtureDir = path.join(os.tmpdir(), "eslint/fixtures/config-initializer");
-        sh.mkdir("-p", fixtureDir);
-        sh.cp("-r", "./tests/fixtures/config-initializer/.", fixtureDir);
-        fixtureDir = fs.realpathSync(fixtureDir);
-    });
-
-    beforeEach(() => {
-        npmInstallStub = sinon.stub(npmUtils, "installSyncSaveDev");
-        npmCheckStub = sinon.stub(npmUtils, "checkDevDeps").callsFake(packages => packages.reduce((status, pkg) => {
-            status[pkg] = false;
-            return status;
-        }, {}));
-        npmFetchPeerDependenciesStub = sinon
-            .stub(npmUtils, "fetchPeerDependencies")
-            .returns({
-                eslint: "^3.19.0",
-                "eslint-plugin-jsx-a11y": "^5.0.1",
-                "eslint-plugin-import": "^2.2.0",
-                "eslint-plugin-react": "^7.0.1"
-            });
-        init = proxyquire("../../../lib/init/config-initializer", requireStubs);
-    });
-
-    afterEach(() => {
-        log.info.resetHistory();
-        log.error.resetHistory();
-        npmInstallStub.restore();
-        npmCheckStub.restore();
-        npmFetchPeerDependenciesStub.restore();
-    });
-
-    after(() => {
-        sh.rm("-r", fixtureDir);
-    });
-
-    describe("processAnswers()", () => {
-
-        describe("prompt", () => {
-
-            beforeEach(() => {
-                answers = {
-                    purpose: "style",
-                    source: "prompt",
-                    extendDefault: true,
-                    indent: 2,
-                    quotes: "single",
-                    linebreak: "unix",
-                    semi: true,
-                    moduleType: "esm",
-                    es6Globals: true,
-                    env: ["browser"],
-                    format: "JSON"
-                };
-            });
-
-            it("should create default config", () => {
-                const config = init.processAnswers(answers);
-
-                assert.deepStrictEqual(config.rules.indent, ["error", 2]);
-                assert.deepStrictEqual(config.rules.quotes, ["error", "single"]);
-                assert.deepStrictEqual(config.rules["linebreak-style"], ["error", "unix"]);
-                assert.deepStrictEqual(config.rules.semi, ["error", "always"]);
-                assert.strictEqual(config.env.es2021, true);
-                assert.strictEqual(config.parserOptions.ecmaVersion, espree.latestEcmaVersion);
-                assert.strictEqual(config.parserOptions.sourceType, "module");
-                assert.strictEqual(config.env.browser, true);
-                assert.strictEqual(config.extends, "eslint:recommended");
-            });
-
-            it("should disable semi", () => {
-                answers.semi = false;
-                const config = init.processAnswers(answers);
-
-                assert.deepStrictEqual(config.rules.semi, ["error", "never"]);
-            });
-
-            it("should enable react plugin", () => {
-                answers.framework = "react";
-                const config = init.processAnswers(answers);
-
-                assert.strictEqual(config.parserOptions.ecmaFeatures.jsx, true);
-                assert.strictEqual(config.parserOptions.ecmaVersion, espree.latestEcmaVersion);
-                assert.deepStrictEqual(config.plugins, ["react"]);
-            });
-
-            it("should enable vue plugin", () => {
-                answers.framework = "vue";
-                const config = init.processAnswers(answers);
-
-                assert.strictEqual(config.parserOptions.ecmaVersion, espree.latestEcmaVersion);
-                assert.deepStrictEqual(config.plugins, ["vue"]);
-                assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:vue/essential"]);
-            });
-
-            it("should enable typescript parser and plugin", () => {
-                answers.typescript = true;
-                const config = init.processAnswers(answers);
-
-                assert.strictEqual(config.parser, "@typescript-eslint/parser");
-                assert.deepStrictEqual(config.plugins, ["@typescript-eslint"]);
-                assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:@typescript-eslint/recommended"]);
-            });
-
-            it("should enable typescript parser and plugin with vue", () => {
-                answers.framework = "vue";
-                answers.typescript = true;
-                const config = init.processAnswers(answers);
-
-                assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:vue/essential", "plugin:@typescript-eslint/recommended"]);
-                assert.strictEqual(config.parserOptions.parser, "@typescript-eslint/parser");
-                assert.deepStrictEqual(config.plugins, ["vue", "@typescript-eslint"]);
-            });
-
-            it("should extend eslint:recommended", () => {
-                const config = init.processAnswers(answers);
-
-                assert.strictEqual(config.extends, "eslint:recommended");
-            });
-
-            it("should not use commonjs by default", () => {
-                const config = init.processAnswers(answers);
-
-                assert.isUndefined(config.env.commonjs);
-            });
-
-            it("should use commonjs when set", () => {
-                answers.moduleType = "commonjs";
-                const config = init.processAnswers(answers);
-
-                assert.isTrue(config.env.commonjs);
-            });
-        });
-
-        describe("guide", () => {
-            it("should support the google style guide", () => {
-                const config = { extends: "google" };
-                const modules = init.getModulesList(config);
-
-                assert.deepStrictEqual(config, { extends: "google", installedESLint: true });
-                assert.include(modules, "eslint-config-google@latest");
-            });
-
-            it("should support the airbnb style guide", () => {
-                const config = { extends: "airbnb" };
-                const modules = init.getModulesList(config);
-
-                assert.deepStrictEqual(config, { extends: "airbnb", installedESLint: true });
-                assert.include(modules, "eslint-config-airbnb@latest");
-            });
-
-            it("should support the airbnb base style guide", () => {
-                const config = { extends: "airbnb-base" };
-                const modules = init.getModulesList(config);
-
-                assert.deepStrictEqual(config, { extends: "airbnb-base", installedESLint: true });
-                assert.include(modules, "eslint-config-airbnb-base@latest");
-            });
-
-            it("should support the standard style guide", () => {
-                const config = { extends: "standard" };
-                const modules = init.getModulesList(config);
-
-                assert.deepStrictEqual(config, { extends: "standard", installedESLint: true });
-                assert.include(modules, "eslint-config-standard@latest");
-            });
-
-            it("should support the xo style guide", () => {
-                const config = { extends: "xo" };
-                const modules = init.getModulesList(config);
-
-                assert.deepStrictEqual(config, { extends: "xo", installedESLint: true });
-                assert.include(modules, "eslint-config-xo@latest");
-            });
-
-            it("should install required sharable config", () => {
-                const config = { extends: "google" };
-
-                init.installModules(init.getModulesList(config));
-                assert(npmInstallStub.calledOnce);
-                assert(npmInstallStub.firstCall.args[0].some(name => name.startsWith("eslint-config-google@")));
-            });
-
-            it("should install ESLint if not installed locally", () => {
-                const config = { extends: "google" };
-
-                init.installModules(init.getModulesList(config));
-                assert(npmInstallStub.calledOnce);
-                assert(npmInstallStub.firstCall.args[0].some(name => name.startsWith("eslint@")));
-            });
-
-            it("should install peerDependencies of the sharable config", () => {
-                const config = { extends: "airbnb" };
-
-                init.installModules(init.getModulesList(config));
-
-                assert(npmFetchPeerDependenciesStub.calledOnce);
-                assert(npmFetchPeerDependenciesStub.firstCall.args[0] === "eslint-config-airbnb@latest");
-                assert(npmInstallStub.calledOnce);
-                assert.deepStrictEqual(
-                    npmInstallStub.firstCall.args[0],
-                    [
-                        "eslint-config-airbnb@latest",
-                        "eslint@^3.19.0",
-                        "eslint-plugin-jsx-a11y@^5.0.1",
-                        "eslint-plugin-import@^2.2.0",
-                        "eslint-plugin-react@^7.0.1"
-                    ]
-                );
-            });
-
-            describe("hasESLintVersionConflict (Note: peerDependencies always `eslint: \"^3.19.0\"` by stubs)", () => {
-                describe("if local ESLint is not found,", () => {
-                    before(() => {
-                        localESLintVersion = null;
-                    });
-
-                    it("should return false.", () => {
-                        const result = init.hasESLintVersionConflict({ styleguide: "airbnb" });
-
-                        assert.strictEqual(result, false);
-                    });
-                });
-
-                describe("if local ESLint is 3.19.0,", () => {
-                    before(() => {
-                        localESLintVersion = "3.19.0";
-                    });
-
-                    it("should return false.", () => {
-                        const result = init.hasESLintVersionConflict({ styleguide: "airbnb" });
-
-                        assert.strictEqual(result, false);
-                    });
-                });
-
-                describe("if local ESLint is 4.0.0,", () => {
-                    before(() => {
-                        localESLintVersion = "4.0.0";
-                    });
-
-                    it("should return true.", () => {
-                        const result = init.hasESLintVersionConflict({ styleguide: "airbnb" });
-
-                        assert.strictEqual(result, true);
-                    });
-                });
-
-                describe("if local ESLint is 3.18.0,", () => {
-                    before(() => {
-                        localESLintVersion = "3.18.0";
-                    });
-
-                    it("should return true.", () => {
-                        const result = init.hasESLintVersionConflict({ styleguide: "airbnb" });
-
-                        assert.strictEqual(result, true);
-                    });
-                });
-            });
-
-            it("should support the standard style guide with Vue.js", () => {
-                const config = {
-                    plugins: ["vue"],
-                    extends: ["plugin:vue/essential", "standard"]
-                };
-                const modules = init.getModulesList(config);
-
-                assert.include(modules, "eslint-plugin-vue@latest");
-                assert.include(modules, "eslint-config-standard@latest");
-            });
-
-            it("should support custom parser", () => {
-                const config = {
-                    parser: "@typescript-eslint/parser"
-                };
-                const modules = init.getModulesList(config);
-
-                assert.include(modules, "@typescript-eslint/parser@latest");
-            });
-
-            it("should support custom parser with Vue.js", () => {
-                const config = {
-
-                    // We should declare the parser at `parserOptions` when using with `eslint-plugin-vue`.
-                    parserOptions: {
-                        parser: "@typescript-eslint/parser"
-                    }
-                };
-                const modules = init.getModulesList(config);
-
-                assert.include(modules, "@typescript-eslint/parser@latest");
-            });
-        });
-
-        describe("auto", () => {
-            const completeSpy = sinon.spy();
-            let config;
-
-            before(() => {
-                const patterns = [
-                    getFixturePath("lib"),
-                    getFixturePath("tests")
-                ].join(" ");
-
-                answers = {
-                    purpose: "style",
-                    source: "auto",
-                    patterns,
-                    env: ["browser"],
-                    format: "JSON"
-                };
-
-                sinon.stub(console, "log"); // necessary to replace, because of progress bar
-
-                process.chdir(fixtureDir);
-                config = init.processAnswers(answers);
-                sinon.restore();
-            });
-
-            after(() => {
-                sinon.restore();
-            });
-
-            afterEach(() => {
-                process.chdir(originalDir);
-                sinon.restore();
-            });
-
-            it("should create a config", () => {
-                assert.isTrue(completeSpy.notCalled);
-                assert.ok(config);
-            });
-
-            it("should create the config based on examined files", () => {
-                assert.deepStrictEqual(config.rules.quotes, ["error", "double"]);
-                assert.strictEqual(config.rules.semi, "off");
-            });
-
-            it("should extend and not disable recommended rules", () => {
-                assert.strictEqual(config.extends, "eslint:recommended");
-                assert.notProperty(config.rules, "no-debugger");
-            });
-
-            it("should not include deprecated rules", () => {
-                assert.notProperty(config.rules, "id-blacklist");
-                assert.notProperty(config.rules, "no-negated-in-lhs");
-                assert.notProperty(config.rules, "no-process-exit");
-                assert.notProperty(config.rules, "no-spaced-func");
-                assert.notProperty(config.rules, "prefer-reflect");
-            });
-
-            it("should support new ES features if using later ES version", () => {
-                const filename = getFixturePath("new-es-features");
-
-                answers.patterns = filename;
-                answers.ecmaVersion = 2017;
-                process.chdir(fixtureDir);
-                config = init.processAnswers(answers);
-            });
-
-            it("should throw on fatal parsing error", () => {
-                const filename = getFixturePath("parse-error");
-
-                sinon.stub(autoconfig, "extendFromRecommended");
-                answers.patterns = filename;
-                process.chdir(fixtureDir);
-                assert.throws(() => {
-                    config = init.processAnswers(answers);
-                }, "Parsing error: Unexpected token ;");
-            });
-
-            it("should throw if no files are matched from patterns", () => {
-                sinon.stub(autoconfig, "extendFromRecommended");
-                answers.patterns = "not-a-real-filename";
-                process.chdir(fixtureDir);
-                assert.throws(() => {
-                    config = init.processAnswers(answers);
-                }, "No files matching 'not-a-real-filename' were found.");
-            });
-        });
-    });
-
-    describe("writeFile()", () => {
-
-        beforeEach(() => {
-            answers = {
-                purpose: "style",
-                source: "prompt",
-                extendDefault: true,
-                indent: 2,
-                quotes: "single",
-                linebreak: "unix",
-                semi: true,
-                moduleType: "esm",
-                es6Globals: true,
-                env: ["browser"],
-                format: "JSON"
-            };
-
-            pkgJSONContents = {
-                name: "config-initializer",
-                version: "1.0.0"
-            };
-
-            process.chdir(fixtureDir);
-
-            pkgJSONPath = path.resolve(fixtureDir, "package.json");
-        });
-
-        afterEach(() => {
-            process.chdir(originalDir);
-        });
-
-        it("should create .eslintrc.json", () => {
-            const config = init.processAnswers(answers);
-            const filePath = path.resolve(fixtureDir, ".eslintrc.json");
-
-            fs.writeFileSync(pkgJSONPath, JSON.stringify(pkgJSONContents));
-
-            init.writeFile(config, answers.format);
-
-            assert.isTrue(fs.existsSync(filePath));
-
-            fs.unlinkSync(filePath);
-            fs.unlinkSync(pkgJSONPath);
-        });
-
-        it("should create .eslintrc.js", () => {
-            answers.format = "JavaScript";
-
-            const config = init.processAnswers(answers);
-            const filePath = path.resolve(fixtureDir, ".eslintrc.js");
-
-            fs.writeFileSync(pkgJSONPath, JSON.stringify(pkgJSONContents));
-
-            init.writeFile(config, answers.format);
-
-            assert.isTrue(fs.existsSync(filePath));
-
-            fs.unlinkSync(filePath);
-            fs.unlinkSync(pkgJSONPath);
-        });
-
-        it("should create .eslintrc.yml", () => {
-            answers.format = "YAML";
-
-            const config = init.processAnswers(answers);
-            const filePath = path.resolve(fixtureDir, ".eslintrc.yml");
-
-            fs.writeFileSync(pkgJSONPath, JSON.stringify(pkgJSONContents));
-
-            init.writeFile(config, answers.format);
-
-            assert.isTrue(fs.existsSync(filePath));
-
-            fs.unlinkSync(filePath);
-            fs.unlinkSync(pkgJSONPath);
-        });
-
-        // For https://github.com/eslint/eslint/issues/14137
-        it("should create .eslintrc.cjs", () => {
-            answers.format = "JavaScript";
-
-            // create package.json with "type": "module"
-            pkgJSONContents.type = "module";
-
-            fs.writeFileSync(pkgJSONPath, JSON.stringify(pkgJSONContents));
-
-            const config = init.processAnswers(answers);
-            const filePath = path.resolve(fixtureDir, ".eslintrc.cjs");
-
-            init.writeFile(config, answers.format);
-
-            assert.isTrue(fs.existsSync(filePath));
-
-            fs.unlinkSync(filePath);
-            fs.unlinkSync(pkgJSONPath);
-        });
-
-        it("should create .eslintrc.json even with type: 'module'", () => {
-            answers.format = "JSON";
-
-            // create package.json with "type": "module"
-            pkgJSONContents.type = "module";
-
-            fs.writeFileSync(pkgJSONPath, JSON.stringify(pkgJSONContents));
-
-            const config = init.processAnswers(answers);
-            const filePath = path.resolve(fixtureDir, ".eslintrc.json");
-
-            init.writeFile(config, answers.format);
-
-            assert.isTrue(fs.existsSync(filePath));
-
-            fs.unlinkSync(filePath);
-            fs.unlinkSync(pkgJSONPath);
-        });
-    });
-});
diff --git a/tests/lib/init/npm-utils.js b/tests/lib/init/npm-utils.js
deleted file mode 100644
index 8465796a3..000000000
--- a/tests/lib/init/npm-utils.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * @fileoverview Tests for rule fixer.
- * @author Ian VanSchooten
- */
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const
-    assert = require("chai").assert,
-    spawn = require("cross-spawn"),
-    sinon = require("sinon"),
-    npmUtils = require("../../../lib/init/npm-utils"),
-    log = require("../../../lib/shared/logging"),
-    { defineInMemoryFs } = require("../../_utils");
-
-const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
-
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-/**
- * Import `npm-utils` with the in-memory file system.
- * @param {Object} files The file definitions.
- * @returns {Object} `npm-utils`.
- */
-function requireNpmUtilsWithInMemoryFileSystem(files) {
-    const fs = defineInMemoryFs({ files });
-
-    return proxyquire("../../../lib/init/npm-utils", { fs });
-}
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-describe("npmUtils", () => {
-    afterEach(() => {
-        sinon.verifyAndRestore();
-    });
-
-    describe("checkDevDeps()", () => {
-        let installStatus;
-
-        before(() => {
-            installStatus = npmUtils.checkDevDeps(["debug", "mocha", "notarealpackage", "jshint"]);
-        });
-
-        it("should not find a direct dependency of the project", () => {
-            assert.isFalse(installStatus.debug);
-        });
-
-        it("should find a dev dependency of the project", () => {
-            assert.isTrue(installStatus.mocha);
-        });
-
-        it("should not find non-dependencies", () => {
-            assert.isFalse(installStatus.notarealpackage);
-        });
-
-        it("should not find nested dependencies", () => {
-            assert.isFalse(installStatus.jshint);
-        });
-
-        it("should return false for a single, non-existent package", () => {
-            installStatus = npmUtils.checkDevDeps(["notarealpackage"]);
-            assert.isFalse(installStatus.notarealpackage);
-        });
-
-        it("should handle missing devDependencies key", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({
-                "package.json": JSON.stringify({ private: true, dependencies: {} })
-            });
-
-            // Should not throw.
-            stubbedNpmUtils.checkDevDeps(["some-package"]);
-        });
-
-        it("should throw with message when parsing invalid package.json", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({
-                "package.json": "{ \"not: \"valid json\" }"
-            });
-
-            assert.throws(() => {
-                try {
-                    stubbedNpmUtils.checkDevDeps(["some-package"]);
-                } catch (error) {
-                    assert.strictEqual(error.messageTemplate, "failed-to-read-json");
-                    throw error;
-                }
-            }, "SyntaxError: Unexpected token v");
-        });
-    });
-
-    describe("checkDeps()", () => {
-        let installStatus;
-
-        before(() => {
-            installStatus = npmUtils.checkDeps(["debug", "mocha", "notarealpackage", "jshint"]);
-        });
-
-        it("should find a direct dependency of the project", () => {
-            assert.isTrue(installStatus.debug);
-        });
-
-        it("should not find a dev dependency of the project", () => {
-            assert.isFalse(installStatus.mocha);
-        });
-
-        it("should not find non-dependencies", () => {
-            assert.isFalse(installStatus.notarealpackage);
-        });
-
-        it("should not find nested dependencies", () => {
-            assert.isFalse(installStatus.jshint);
-        });
-
-        it("should return false for a single, non-existent package", () => {
-            installStatus = npmUtils.checkDeps(["notarealpackage"]);
-            assert.isFalse(installStatus.notarealpackage);
-        });
-
-        it("should throw if no package.json can be found", () => {
-            assert.throws(() => {
-                installStatus = npmUtils.checkDeps(["notarealpackage"], "/fakepath");
-            }, "Could not find a package.json file");
-        });
-
-        it("should handle missing dependencies key", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({
-                "package.json": JSON.stringify({ private: true, devDependencies: {} })
-            });
-
-            // Should not throw.
-            stubbedNpmUtils.checkDeps(["some-package"]);
-        });
-
-        it("should throw with message when parsing invalid package.json", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({
-                "package.json": "{ \"not: \"valid json\" }"
-            });
-
-            assert.throws(() => {
-                try {
-                    stubbedNpmUtils.checkDeps(["some-package"]);
-                } catch (error) {
-                    assert.strictEqual(error.messageTemplate, "failed-to-read-json");
-                    throw error;
-                }
-            }, "SyntaxError: Unexpected token v");
-        });
-    });
-
-    describe("checkPackageJson()", () => {
-        it("should return true if package.json exists", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({
-                "package.json": "{ \"file\": \"contents\" }"
-            });
-
-            assert.strictEqual(stubbedNpmUtils.checkPackageJson(), true);
-        });
-
-        it("should return false if package.json does not exist", () => {
-            const stubbedNpmUtils = requireNpmUtilsWithInMemoryFileSystem({});
-
-            assert.strictEqual(stubbedNpmUtils.checkPackageJson(), false);
-        });
-    });
-
-    describe("installSyncSaveDev()", () => {
-        it("should invoke npm to install a single desired package", () => {
-            const stub = sinon.stub(spawn, "sync").returns({ stdout: "" });
-
-            npmUtils.installSyncSaveDev("desired-package");
-            assert(stub.calledOnce);
-            assert.strictEqual(stub.firstCall.args[0], "npm");
-            assert.deepStrictEqual(stub.firstCall.args[1], ["i", "--save-dev", "desired-package"]);
-            stub.restore();
-        });
-
-        it("should accept an array of packages to install", () => {
-            const stub = sinon.stub(spawn, "sync").returns({ stdout: "" });
-
-            npmUtils.installSyncSaveDev(["first-package", "second-package"]);
-            assert(stub.calledOnce);
-            assert.strictEqual(stub.firstCall.args[0], "npm");
-            assert.deepStrictEqual(stub.firstCall.args[1], ["i", "--save-dev", "first-package", "second-package"]);
-            stub.restore();
-        });
-
-        it("should log an error message if npm throws ENOENT error", () => {
-            const logErrorStub = sinon.stub(log, "error");
-            const npmUtilsStub = sinon.stub(spawn, "sync").returns({ error: { code: "ENOENT" } });
-
-            npmUtils.installSyncSaveDev("some-package");
-
-            assert(logErrorStub.calledOnce);
-
-            logErrorStub.restore();
-            npmUtilsStub.restore();
-        });
-    });
-
-    describe("fetchPeerDependencies()", () => {
-        it("should execute 'npm show --json <packageName> peerDependencies' command", () => {
-            const stub = sinon.stub(spawn, "sync").returns({ stdout: "" });
-
-            npmUtils.fetchPeerDependencies("desired-package");
-            assert(stub.calledOnce);
-            assert.strictEqual(stub.firstCall.args[0], "npm");
-            assert.deepStrictEqual(stub.firstCall.args[1], ["show", "--json", "desired-package", "peerDependencies"]);
-            stub.restore();
-        });
-
-        it("should return null if npm throws ENOENT error", () => {
-            const stub = sinon.stub(spawn, "sync").returns({ error: { code: "ENOENT" } });
-
-            const peerDependencies = npmUtils.fetchPeerDependencies("desired-package");
-
-            assert.isNull(peerDependencies);
-
-            stub.restore();
-        });
-    });
-});
diff --git a/tests/lib/init/source-code-utils.js b/tests/lib/init/source-code-utils.js
deleted file mode 100644
index 994d23d31..000000000
--- a/tests/lib/init/source-code-utils.js
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * @fileoverview Tests for source-code-util.
- * @author Ian VanSchooten
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const path = require("path"),
-    fs = require("fs"),
-    os = require("os"),
-    assert = require("chai").assert,
-    sinon = require("sinon"),
-    sh = require("shelljs"),
-    { SourceCode } = require("../../../lib/source-code");
-
-const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
-const originalDir = process.cwd();
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-describe("SourceCodeUtil", () => {
-
-    let fixtureDir,
-        getSourceCodeOfFiles;
-
-    /**
-     * Returns the path inside of the fixture directory.
-     * @param {...string} args file path segments.
-     * @returns {string} The path inside the fixture directory.
-     * @private
-     */
-    function getFixturePath(...args) {
-        let filepath = path.join(fixtureDir, ...args);
-
-        try {
-            filepath = fs.realpathSync(filepath);
-            return filepath;
-        } catch {
-            return filepath;
-        }
-    }
-
-    const log = {
-        info: sinon.spy(),
-        error: sinon.spy()
-    };
-    const requireStubs = {
-        "../logging": log
-    };
-
-    // copy into clean area so as not to get "infected" by this project's .eslintrc files
-    before(() => {
-        fixtureDir = `${os.tmpdir()}/eslint/fixtures/source-code-util`;
-        sh.mkdir("-p", fixtureDir);
-        sh.cp("-r", "./tests/fixtures/source-code-util/.", fixtureDir);
-        fixtureDir = fs.realpathSync(fixtureDir);
-    });
-
-    beforeEach(() => {
-        getSourceCodeOfFiles = proxyquire("../../../lib/init/source-code-utils", requireStubs).getSourceCodeOfFiles;
-    });
-
-    afterEach(() => {
-        log.info.resetHistory();
-        log.error.resetHistory();
-    });
-
-    after(() => {
-        sh.rm("-r", fixtureDir);
-    });
-
-    describe("getSourceCodeOfFiles()", () => {
-
-        it("should handle single string filename arguments", () => {
-            const filename = getFixturePath("foo.js");
-            const sourceCode = getSourceCodeOfFiles(filename, { cwd: fixtureDir });
-
-            assert.isObject(sourceCode);
-        });
-
-        it("should accept an array of string filenames", () => {
-            const fooFilename = getFixturePath("foo.js");
-            const barFilename = getFixturePath("bar.js");
-            const sourceCode = getSourceCodeOfFiles([fooFilename, barFilename], { cwd: fixtureDir });
-
-            assert.isObject(sourceCode);
-        });
-
-        it("should accept a glob argument", () => {
-            const glob = getFixturePath("*.js");
-            const filename = getFixturePath("foo.js");
-            const sourceCode = getSourceCodeOfFiles(glob, { cwd: fixtureDir });
-
-            assert.isObject(sourceCode);
-            assert.property(sourceCode, filename);
-        });
-
-        it("should accept a relative filename", () => {
-            const filename = "foo.js";
-            const sourceCode = getSourceCodeOfFiles(filename, { cwd: fixtureDir });
-
-            assert.isObject(sourceCode);
-            assert.property(sourceCode, getFixturePath(filename));
-        });
-
-        it("should accept a relative path to a file in a parent directory", () => {
-            const filename = "../foo.js";
-            const sourceCode = getSourceCodeOfFiles(filename, { cwd: getFixturePath("nested") });
-
-            assert.isObject(sourceCode);
-            assert.property(sourceCode, getFixturePath("foo.js"));
-        });
-
-        it("should accept a callback", () => {
-            const filename = getFixturePath("foo.js");
-            const spy = sinon.spy();
-
-            process.chdir(fixtureDir);
-            getSourceCodeOfFiles(filename, {}, spy);
-            process.chdir(originalDir);
-            assert(spy.calledOnce);
-        });
-
-        it("should call the callback with total number of files being processed", () => {
-            const filename = getFixturePath("foo.js");
-            const spy = sinon.spy();
-
-            process.chdir(fixtureDir);
-            getSourceCodeOfFiles(filename, {}, spy);
-            process.chdir(originalDir);
-            assert.strictEqual(spy.firstCall.args[0], 1);
-        });
-
-        it("should create an object with located filenames as keys", () => {
-            const fooFilename = getFixturePath("foo.js");
-            const barFilename = getFixturePath("bar.js");
-            const sourceCode = getSourceCodeOfFiles([fooFilename, barFilename], { cwd: fixtureDir });
-
-            assert.property(sourceCode, fooFilename);
-            assert.property(sourceCode, barFilename);
-        });
-
-        it("should should not include non-existent filenames in results", () => {
-            const filename = getFixturePath("missing.js");
-
-            assert.throws(() => {
-                getSourceCodeOfFiles(filename, { cwd: fixtureDir });
-            }, `No files matching '${filename}' were found.`);
-        });
-
-        it("should throw for files with parsing errors", () => {
-            const filename = getFixturePath("parse-error", "parse-error.js");
-
-            assert.throw(() => {
-                getSourceCodeOfFiles(filename, { cwd: fixtureDir });
-            }, /Parsing error: Unexpected token ;/u);
-
-        });
-
-        it("should obtain the sourceCode of a file", () => {
-            const filename = getFixturePath("foo.js");
-            const sourceCode = getSourceCodeOfFiles(filename, { cwd: fixtureDir });
-
-            assert.isObject(sourceCode);
-            assert.instanceOf(sourceCode[filename], SourceCode);
-        });
-
-        it("should obtain the sourceCode of JSX files", () => {
-            const filename = getFixturePath("jsx", "foo.jsx");
-            const options = {
-                cwd: fixtureDir,
-                parserOptions: {
-                    ecmaFeatures: {
-                        jsx: true
-                    }
-                }
-            };
-            const sourceCode = getSourceCodeOfFiles(filename, options);
-
-            assert.isObject(sourceCode);
-            assert.instanceOf(sourceCode[filename], SourceCode);
-        });
-
-        it("should honor .eslintignore files by default", () => {
-            const glob = getFixturePath("*.js");
-            const unignoredFilename = getFixturePath("foo.js");
-            const ignoredFilename = getFixturePath("ignored.js");
-            const sourceCode = getSourceCodeOfFiles(glob, { cwd: fixtureDir });
-
-            assert.property(sourceCode, unignoredFilename);
-            assert.notProperty(sourceCode, ignoredFilename);
-        });
-
-        it("should obtain the sourceCode of all files in a specified folder", () => {
-            const folder = getFixturePath("nested");
-            const fooFile = getFixturePath("nested/foo.js");
-            const barFile = getFixturePath("nested/bar.js");
-            const sourceCode = getSourceCodeOfFiles(folder, { cwd: fixtureDir });
-
-            assert.strictEqual(Object.keys(sourceCode).length, 2);
-            assert.instanceOf(sourceCode[fooFile], SourceCode);
-            assert.instanceOf(sourceCode[barFile], SourceCode);
-        });
-
-        it("should accept cli options", () => {
-            const pattern = getFixturePath("ext");
-            const abcFile = getFixturePath("ext/foo.abc");
-            const cliOptions = { extensions: [".abc"], cwd: fixtureDir };
-            const sourceCode = getSourceCodeOfFiles(pattern, cliOptions);
-
-            assert.strictEqual(Object.keys(sourceCode).length, 1);
-            assert.instanceOf(sourceCode[abcFile], SourceCode);
-        });
-
-        it("should execute the callback function, if provided", () => {
-            const callback = sinon.spy();
-            const filename = getFixturePath("foo.js");
-
-            getSourceCodeOfFiles(filename, { cwd: fixtureDir }, callback);
-            assert(callback.calledOnce);
-        });
-
-        it("should execute callback function once per file", () => {
-            const callback = sinon.spy();
-            const fooFilename = getFixturePath("foo.js");
-            const barFilename = getFixturePath("bar.js");
-
-            getSourceCodeOfFiles([fooFilename, barFilename], { cwd: fixtureDir }, callback);
-            assert.strictEqual(callback.callCount, 2);
-        });
-
-        it("should call callback function with total number of files with sourceCode", () => {
-            const callback = sinon.spy();
-            const firstFn = getFixturePath("foo.js");
-            const secondFn = getFixturePath("bar.js");
-            const thirdFn = getFixturePath("nested/foo.js");
-
-            getSourceCodeOfFiles([firstFn, secondFn, thirdFn], { cwd: fixtureDir }, callback);
-            assert(callback.calledWith(3));
-        });
-
-    });
-
-});
diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js
index 514eb85d2..3a47a1b4b 100644
--- a/tests/lib/rules/camelcase.js
+++ b/tests/lib/rules/camelcase.js
@@ -164,11 +164,32 @@ ruleTester.run("camelcase", rule, {
             options: [{ ignoreImports: true }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" }
         },
+        {
+            code: "import { snake_cased as snake_cased } from 'mod'",
+            options: [{ ignoreImports: true }],
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" }
+        },
+        {
+            code: "import { 'snake_cased' as snake_cased } from 'mod'",
+            options: [{ ignoreImports: true }],
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" }
+        },
         {
             code: "import { camelCased } from 'mod'",
             options: [{ ignoreImports: false }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" }
         },
+
+        // this rule doesn't apply to quoted module export names, as it doesn't apply to quoted property names.
+        {
+            code: "export { a as 'snake_cased' } from 'mod'",
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" }
+        },
+        {
+            code: "export * as 'snake_cased' from 'mod'",
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" }
+        },
+
         {
             code: "var _camelCased = aGlobalVariable",
             options: [{ ignoreGlobals: false }],
@@ -668,6 +689,29 @@ ruleTester.run("camelcase", rule, {
                 }
             ]
         },
+        {
+            code: "import { 'snake_cased' as snake_cased } from 'mod'",
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" },
+            errors: [
+                {
+                    messageId: "notCamelCase",
+                    data: { name: "snake_cased" },
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "import { 'snake_cased' as another_snake_cased } from 'mod'",
+            options: [{ ignoreImports: true }],
+            parserOptions: { ecmaVersion: 2022, sourceType: "module" },
+            errors: [
+                {
+                    messageId: "notCamelCase",
+                    data: { name: "another_snake_cased" },
+                    type: "Identifier"
+                }
+            ]
+        },
         {
             code: "import { camelCased, no_camelcased } from \"external-module\";",
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
diff --git a/tests/lib/rules/id-match.js b/tests/lib/rules/id-match.js
index de66d8b8d..7e469bd4d 100644
--- a/tests/lib/rules/id-match.js
+++ b/tests/lib/rules/id-match.js
@@ -894,6 +894,26 @@ ruleTester.run("id-match", rule, {
                     type: "Identifier"
                 }
             ]
+        },
+
+        // https://github.com/eslint/eslint/issues/15443
+        {
+            code: `
+            const foo = {
+                [a]: 1,
+            };
+            `,
+            options: ["^[^a]", {
+                properties: false,
+                onlyDeclarations: false
+            }],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                {
+                    message: "Identifier 'a' does not match the pattern '^[^a]'.",
+                    type: "Identifier"
+                }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js
index c86e67ecf..3cf7eb371 100644
--- a/tests/lib/rules/no-restricted-imports.js
+++ b/tests/lib/rules/no-restricted-imports.js
@@ -16,7 +16,7 @@ const rule = require("../../../lib/rules/no-restricted-imports"),
 // Tests
 //------------------------------------------------------------------------------
 
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2020, sourceType: "module" } });
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2022, sourceType: "module" } });
 
 ruleTester.run("no-restricted-imports", rule, {
     valid: [
@@ -92,6 +92,34 @@ ruleTester.run("no-restricted-imports", rule, {
                 }]
             }]
         },
+        {
+            code: "import { 'AllowedObject' as bar } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: ["DisallowedObject"],
+                    message: "Please import 'DisallowedObject' from /bar/ instead."
+                }]
+            }]
+        },
+        {
+            code: "import { ' ' as bar } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: [""]
+                }]
+            }]
+        },
+        {
+            code: "import { '' as bar } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: [" "]
+                }]
+            }]
+        },
         {
             code: "import { DisallowedObject } from \"foo\";",
             options: [{
@@ -112,6 +140,16 @@ ruleTester.run("no-restricted-imports", rule, {
                 }]
             }]
         },
+        {
+            code: "import { 'AllowedObject' as DisallowedObject } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: ["DisallowedObject"],
+                    message: "Please import 'DisallowedObject' from /bar/ instead."
+                }]
+            }]
+        },
         {
             code: "import { AllowedObject, AllowedObjectTwo } from \"foo\";",
             options: [{
@@ -196,6 +234,24 @@ ruleTester.run("no-restricted-imports", rule, {
                 name: "bar",
                 importNames: ["DisallowedObject"]
             }]
+        },
+        {
+            code: "export { 'AllowedObject' } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: ["DisallowedObject"]
+                }]
+            }]
+        },
+        {
+            code: "export { 'AllowedObject' as DisallowedObject } from \"foo\";",
+            options: [{
+                paths: [{
+                    name: "foo",
+                    importNames: ["DisallowedObject"]
+                }]
+            }]
         }
     ],
     invalid: [{
@@ -344,6 +400,70 @@ ruleTester.run("no-restricted-imports", rule, {
             column: 9,
             endColumn: 17
         }]
+    }, {
+        code: "export {'foo' as b} from \"fs\";",
+        options: [{
+            paths: [{
+                name: "fs",
+                importNames: ["foo"],
+                message: "Don't import 'foo'."
+            }]
+        }],
+        errors: [{
+            message: "'foo' import from 'fs' is restricted. Don't import 'foo'.",
+            type: "ExportNamedDeclaration",
+            line: 1,
+            column: 9,
+            endColumn: 19
+        }]
+    }, {
+        code: "export {'foo'} from \"fs\";",
+        options: [{
+            paths: [{
+                name: "fs",
+                importNames: ["foo"],
+                message: "Don't import 'foo'."
+            }]
+        }],
+        errors: [{
+            message: "'foo' import from 'fs' is restricted. Don't import 'foo'.",
+            type: "ExportNamedDeclaration",
+            line: 1,
+            column: 9,
+            endColumn: 14
+        }]
+    }, {
+        code: "export {'👍'} from \"fs\";",
+        options: [{
+            paths: [{
+                name: "fs",
+                importNames: ["👍"],
+                message: "Don't import '👍'."
+            }]
+        }],
+        errors: [{
+            message: "'👍' import from 'fs' is restricted. Don't import '👍'.",
+            type: "ExportNamedDeclaration",
+            line: 1,
+            column: 9,
+            endColumn: 13
+        }]
+    }, {
+        code: "export {''} from \"fs\";",
+        options: [{
+            paths: [{
+                name: "fs",
+                importNames: [""],
+                message: "Don't import ''."
+            }]
+        }],
+        errors: [{
+            message: "'' import from 'fs' is restricted. Don't import ''.",
+            type: "ExportNamedDeclaration",
+            line: 1,
+            column: 9,
+            endColumn: 11
+        }]
     }, {
         code: "export * as ns from \"fs\";",
         options: [{
@@ -505,6 +625,55 @@ ruleTester.run("no-restricted-imports", rule, {
             endColumn: 43
         }]
     },
+    {
+        code: "import { 'DisallowedObject' as AllowedObject } from \"foo\";",
+        options: [{
+            paths: [{
+                name: "foo",
+                importNames: ["DisallowedObject"],
+                message: "Please import 'DisallowedObject' from /bar/ instead."
+            }]
+        }],
+        errors: [{
+            message: "'DisallowedObject' import from 'foo' is restricted. Please import 'DisallowedObject' from /bar/ instead.",
+            type: "ImportDeclaration",
+            line: 1,
+            column: 10,
+            endColumn: 45
+        }]
+    },
+    {
+        code: "import { '👍' as bar } from \"foo\";",
+        options: [{
+            paths: [{
+                name: "foo",
+                importNames: ["👍"]
+            }]
+        }],
+        errors: [{
+            message: "'👍' import from 'foo' is restricted.",
+            type: "ImportDeclaration",
+            line: 1,
+            column: 10,
+            endColumn: 21
+        }]
+    },
+    {
+        code: "import { '' as bar } from \"foo\";",
+        options: [{
+            paths: [{
+                name: "foo",
+                importNames: [""]
+            }]
+        }],
+        errors: [{
+            message: "'' import from 'foo' is restricted.",
+            type: "ImportDeclaration",
+            line: 1,
+            column: 10,
+            endColumn: 19
+        }]
+    },
     {
         code: "import { AllowedObject, DisallowedObject } from \"foo\";",
         options: [{
diff --git a/tests/lib/rules/no-useless-rename.js b/tests/lib/rules/no-useless-rename.js
index 66077f2b4..262cf2cc5 100644
--- a/tests/lib/rules/no-useless-rename.js
+++ b/tests/lib/rules/no-useless-rename.js
@@ -47,11 +47,43 @@ ruleTester.run("no-useless-rename", rule, {
         "import {foo} from 'foo';",
         "import {foo as bar} from 'foo';",
         "import {foo as bar, baz as qux} from 'foo';",
+        {
+            code: "import {'foo' as bar} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
         "export {foo} from 'foo';",
         "var foo = 0;export {foo as bar};",
         "var foo = 0; var baz = 0; export {foo as bar, baz as qux};",
         "export {foo as bar} from 'foo';",
         "export {foo as bar, baz as qux} from 'foo';",
+        {
+            code: "var foo = 0; export {foo as 'bar'};",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {foo as 'bar'} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {'foo' as bar} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {'foo' as 'bar'} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {'' as ' '} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {' ' as ''} from 'baz';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
+        {
+            code: "export {'foo'} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 }
+        },
         {
             code: "const {...stuff} = myObject;",
             parserOptions: { ecmaVersion: 2018 }
@@ -380,6 +412,12 @@ ruleTester.run("no-useless-rename", rule, {
             output: "import {foo} from 'foo';",
             errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Import", name: "foo" } }]
         },
+        {
+            code: "import {'foo' as foo} from 'foo';",
+            output: "import {foo} from 'foo';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Import", name: "foo" } }]
+        },
         {
             code: "import {\\u0061 as a} from 'foo';",
             output: "import {a} from 'foo';",
@@ -418,6 +456,42 @@ ruleTester.run("no-useless-rename", rule, {
             output: "var foo = 0; export {foo};",
             errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "foo" } }]
         },
+        {
+            code: "var foo = 0; export {foo as 'foo'};",
+            output: "var foo = 0; export {foo};",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "foo" } }]
+        },
+        {
+            code: "export {foo as 'foo'} from 'bar';",
+            output: "export {foo} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "foo" } }]
+        },
+        {
+            code: "export {'foo' as foo} from 'bar';",
+            output: "export {'foo'} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "foo" } }]
+        },
+        {
+            code: "export {'foo' as 'foo'} from 'bar';",
+            output: "export {'foo'} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "foo" } }]
+        },
+        {
+            code: "export {' 👍 ' as ' 👍 '} from 'bar';",
+            output: "export {' 👍 '} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: " 👍 " } }]
+        },
+        {
+            code: "export {'' as ''} from 'bar';",
+            output: "export {''} from 'bar';",
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [{ messageId: "unnecessarilyRenamed", data: { type: "Export", name: "" } }]
+        },
         {
             code: "var a = 0; export {a as \\u0061};",
             output: "var a = 0; export {a};",
diff --git a/tests/lib/init/config-rule.js b/tests/tools/config-rule.js
similarity index 98%
rename from tests/lib/init/config-rule.js
rename to tests/tools/config-rule.js
index 425317dd2..c91f464c2 100644
--- a/tests/lib/init/config-rule.js
+++ b/tests/tools/config-rule.js
@@ -10,9 +10,9 @@
 //------------------------------------------------------------------------------
 
 const assert = require("chai").assert,
-    ConfigRule = require("../../../lib/init/config-rule"),
-    builtInRules = require("../../../lib/rules"),
-    schema = require("../../fixtures/config-rule/schemas");
+    ConfigRule = require("../../tools/config-rule"),
+    builtInRules = require("../../lib/rules"),
+    schema = require("../fixtures/config-rule/schemas");
 
 //------------------------------------------------------------------------------
 // Tests
diff --git a/tests/tools/eslint-fuzzer.js b/tests/tools/eslint-fuzzer.js
index 4723befa4..1c894b995 100644
--- a/tests/tools/eslint-fuzzer.js
+++ b/tests/tools/eslint-fuzzer.js
@@ -8,7 +8,7 @@ const assert = require("chai").assert;
 const eslint = require("../..");
 const espree = require("espree");
 const sinon = require("sinon");
-const configRule = require("../../lib/init/config-rule");
+const configRule = require("../../tools/config-rule");
 
 //------------------------------------------------------------------------------
 // Tests