Skip to content

Used package install command for list of required ESLint-related packages #405

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
},
plugins: ["@typescript-eslint"],
rules: {
"@typescript-eslint/require-array-sort-compare": "off",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These came up during development. Annoying.

"@typescript-eslint/consistent-type-definitions": ["error", "type"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
Expand All @@ -36,6 +37,7 @@ module.exports = {
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-untyped-public-signature": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/prefer-readonly-parameter-types": "off",
"@typescript-eslint/prefer-reduce-type-parameter": "off",
Expand Down
12 changes: 10 additions & 2 deletions src/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ import { findTSLintConfiguration } from "../input/findTSLintConfiguration";
import { findTypeScriptConfiguration } from "../input/findTypeScriptConfiguration";
import { importer, ImporterDependencies } from "../input/importer";
import { mergeLintConfigurations } from "../input/mergeLintConfigurations";
import { ReportConversionResultsDependencies } from "../reporting/dependencies";
import { reportConversionResults } from "../reporting/reportConversionResults";
import { choosePackageManager } from "../reporting/packages/choosePackageManager";
import {
reportConversionResults,
ReportConversionResultsDependencies,
} from "../reporting/reportConversionResults";
import { reportEditorSettingConversionResults } from "../reporting/reportEditorSettingConversionResults";
import { convertRules, ConvertRulesDependencies } from "../rules/convertRules";
import { mergers } from "../rules/mergers";
Expand Down Expand Up @@ -86,7 +89,12 @@ const findOriginalConfigurationsDependencies: FindOriginalConfigurationsDependen
mergeLintConfigurations,
};

const choosePackageManagerDependencies = {
fileSystem: fsFileSystem,
};

const reportConversionResultsDependencies: ReportConversionResultsDependencies = {
choosePackageManager: bind(choosePackageManager, choosePackageManagerDependencies),
logger: processLogger,
};

Expand Down
2 changes: 1 addition & 1 deletion src/conversion/convertConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const convertConfig = async (
}

// 5. A summary of the results is printed to the user's console
dependencies.reportConversionResults(simplifiedConfiguration);
await dependencies.reportConversionResults(simplifiedConfiguration);

return {
status: ResultStatus.Succeeded,
Expand Down
5 changes: 0 additions & 5 deletions src/reporting/dependencies.ts

This file was deleted.

30 changes: 30 additions & 0 deletions src/reporting/packages/choosePackageManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { choosePackageManager } from "./choosePackageManager";
import { PackageManager } from "./packageManagers";

describe("choosePackageManager", () => {
it("uses a non-npm package manager when that package manager's lock file exists", async () => {
// Arrange
const fileSystem = {
fileExists: async (fileName: string) => fileName === "./yarn.lock",
};

// Act
const result = await choosePackageManager({ fileSystem });

// Assert
expect(result).toEqual(PackageManager.Yarn);
});

it("uses npm when no lock file exists", async () => {
// Arrange
const fileSystem = {
fileExists: async () => false,
};

// Act
const result = await choosePackageManager({ fileSystem });

// Assert
expect(result).toEqual(PackageManager.npm);
});
});
16 changes: 16 additions & 0 deletions src/reporting/packages/choosePackageManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FileSystem } from "../../adapters/fileSystem";
import { preferredLockfiles, PackageManager } from "./packageManagers";

export type ChoosePackageManagerDependencies = {
fileSystem: Pick<FileSystem, "fileExists">;
};

export const choosePackageManager = async (dependencies: ChoosePackageManagerDependencies) => {
for (const [packageManager, lockFile] of preferredLockfiles) {
if (await dependencies.fileSystem.fileExists(lockFile)) {
return packageManager;
}
}

return PackageManager.npm;
};
17 changes: 17 additions & 0 deletions src/reporting/packages/packageManagers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export enum PackageManager {
npm,
pnpm,
Yarn,
}

export const preferredLockfiles = new Map([
[PackageManager.npm, "./package-lock.json"],
[PackageManager.pnpm, "./pnpm-lock.yaml"],
[PackageManager.Yarn, "./yarn.lock"],
]);

export const installationMessages = {
[PackageManager.npm]: (packages: string) => `npm install ${packages} --save-dev`,
[PackageManager.pnpm]: (packages: string) => `pnpm add ${packages} --save-dev`,
[PackageManager.Yarn]: (packages: string) => `yarn add ${packages} --dev`,
};
100 changes: 52 additions & 48 deletions src/reporting/reportConversionResults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ import { EOL } from "os";
import { createStubLogger, expectEqualWrites } from "../adapters/logger.stubs";
import { createEmptyConversionResults } from "../conversion/conversionResults.stubs";
import { ESLintRuleOptions } from "../rules/types";
import { PackageManager } from "./packages/packageManagers";
import { reportConversionResults } from "./reportConversionResults";

const createStubDependencies = (packageManager = PackageManager.Yarn) => {
const choosePackageManager = jest.fn().mockResolvedValueOnce(packageManager);
const logger = createStubLogger();

return { choosePackageManager, logger };
};

describe("reportConversionResults", () => {
it("logs a successful conversion without notices when there is one converted rule without notices", () => {
it("logs a successful conversion without notices when there is one converted rule without notices", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
Expand All @@ -21,19 +29,22 @@ describe("reportConversionResults", () => {
]),
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
`✨ 1 rule replaced with its ESLint equivalent. ✨${EOL}`,
`✨ 1 rule replaced with its ESLint equivalent. ✨`,
``,
`⚡ 3 packages are required for running with ESLint. ⚡`,
` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`,
);
});

it("logs a successful conversion with notices when there is one converted rule with notices", () => {
it("logs a successful conversion with notices when there is one converted rule with notices", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
Expand All @@ -49,10 +60,10 @@ describe("reportConversionResults", () => {
]),
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
Expand All @@ -62,10 +73,13 @@ describe("reportConversionResults", () => {
` * tslint-rule-one:`,
` - 1`,
` - 2`,
``,
`⚡ 3 packages are required for running with ESLint. ⚡`,
` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`,
);
});

it("logs successful conversions when there are multiple converted rules", () => {
it("logs successful conversions when there are multiple converted rules", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
Expand All @@ -90,35 +104,39 @@ describe("reportConversionResults", () => {
]),
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
`✨ 2 rules replaced with their ESLint equivalents. ✨${EOL}`,
`✨ 2 rules replaced with their ESLint equivalents. ✨`,
``,
`❗ 2 ESLint rules behave differently from their TSLint counterparts ❗`,
` * tslint-rule-one:`,
` - 1`,
` - 2`,
` * tslint-rule-two:`,
` - 3`,
` - 4`,
``,
`⚡ 3 packages are required for running with ESLint. ⚡`,
` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`,
);
});

it("logs a failed conversion when there is one failed conversion", () => {
it("logs a failed conversion when there is one failed conversion", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
failed: [{ getSummary: () => "It broke." }],
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
Expand All @@ -128,16 +146,16 @@ describe("reportConversionResults", () => {
);
});

it("logs failed conversions when there are multiple failed conversions", () => {
it("logs failed conversions when there are multiple failed conversions", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
failed: [{ getSummary: () => "It broke." }, { getSummary: () => "It really broke." }],
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
Expand All @@ -147,7 +165,7 @@ describe("reportConversionResults", () => {
);
});

it("logs a missing rule when there is a missing rule", () => {
it("logs a missing rule when there is a missing rule", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
missing: [
Expand All @@ -159,24 +177,27 @@ describe("reportConversionResults", () => {
],
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
"❓ 1 rule does not yet have an ESLint equivalent ❓",
` See generated log file; defaulting to eslint-plugin-tslint for it.`,
"",
"⚡ 3 packages are required for running with ESLint. ⚡",
" yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev",
);
expectEqualWrites(
logger.info.write,
'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-one"',
);
});

it("logs missing rules when there are missing rules", () => {
it("logs missing rules when there are missing rules", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
missing: [
Expand All @@ -193,16 +214,19 @@ describe("reportConversionResults", () => {
],
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
"❓ 2 rules do not yet have ESLint equivalents ❓",
` See generated log file; defaulting to eslint-plugin-tslint for these rules.`,
"",
"⚡ 3 packages are required for running with ESLint. ⚡",
" yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev",
);
expectEqualWrites(
logger.info.write,
Expand All @@ -211,42 +235,22 @@ describe("reportConversionResults", () => {
);
});

it("logs a missing plugin when there is a missing plugin", () => {
// Arrange
const conversionResults = createEmptyConversionResults({
plugins: new Set(["plugin-one"]),
});

const logger = createStubLogger();

// Act
reportConversionResults({ logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
"⚡ 1 package is required for new ESLint rules. ⚡",
" plugin-one",
);
});

it("logs missing plugins when there are missing plugins", () => {
it("logs missing plugins when there are missing plugins", async () => {
// Arrange
const conversionResults = createEmptyConversionResults({
plugins: new Set(["plugin-one", "plugin-two"]),
});

const logger = createStubLogger();
const { choosePackageManager, logger } = createStubDependencies();

// Act
reportConversionResults({ logger }, conversionResults);
await reportConversionResults({ choosePackageManager, logger }, conversionResults);

// Assert
expectEqualWrites(
logger.stdout.write,
"⚡ 2 packages are required for new ESLint rules. ⚡",
" plugin-one",
" plugin-two",
"⚡ 5 packages are required for running with ESLint. ⚡",
" yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint plugin-one plugin-two --dev",
);
});
});
Loading