Skip to content

Commit 10e7902

Browse files
author
Josh Goldberg
authored
Factored rule directories from original TSLint configs into output (#26)
Fixes #6.
1 parent 54590cf commit 10e7902

11 files changed

+100
-49
lines changed

src/cli/main.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { promisify } from "util";
55

66
import { convertConfig } from "../convertConfig";
77
import { createNewConfiguration } from "../creation/createNewConfiguration";
8-
import { findTslintRules } from "../input/findTslintRules";
8+
import { findTslintConfiguration } from "../input/findTslintConfiguration";
99
import { TSLintToESLintSettings } from "../types";
1010
import { runCli } from "./runCli";
1111

@@ -18,22 +18,24 @@ const logger = {
1818
stdout: process.stdout,
1919
};
2020

21-
const ruleFinder = (config: string) => findTslintRules(config, promisify(exec));
22-
2321
const fileExists = (filePath: string) => Promise.resolve(fs.existsSync(filePath));
2422

2523
const runtime = {
2624
convertConfig: (settings: TSLintToESLintSettings) =>
2725
convertConfig({
28-
createNewConfiguration: configConversionResults =>
29-
createNewConfiguration(configConversionResults, fs.promises.writeFile),
26+
createNewConfiguration: (conversionResults, originalConfiguration) =>
27+
createNewConfiguration(
28+
conversionResults,
29+
originalConfiguration,
30+
fs.promises.writeFile,
31+
),
3032
fileExists,
33+
findTslintConfiguration: (config: string) =>
34+
findTslintConfiguration(config, promisify(exec)),
3135
logger,
32-
ruleFinder,
3336
settings,
3437
}),
3538
logger,
36-
ruleFinder,
3739
};
3840

3941
export const main = async (argv: string[]) => {

src/convertConfig.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ResultStatus } from "./types";
55
const defaultRequest = {
66
settings: {},
77
logger: createStubLogger(),
8-
ruleFinder: jest.fn().mockReturnValue(Promise.resolve(new Error())),
8+
findTslintConfiguration: jest.fn().mockReturnValue(Promise.resolve(new Error())),
99
fileExists: jest.fn().mockReturnValue(Promise.resolve(true)),
1010
createNewConfiguration: jest.fn().mockReturnValue(Promise.resolve()),
1111
};
@@ -41,7 +41,7 @@ describe("convertConfig", () => {
4141
await convertConfig(request);
4242

4343
// Assert
44-
expect(request.ruleFinder).toHaveBeenLastCalledWith(request.settings.config);
44+
expect(request.findTslintConfiguration).toHaveBeenLastCalledWith(request.settings.config);
4545
});
4646

4747
it("searches for ./tslint.json by default when no settings.config is provided", async () => {
@@ -55,15 +55,15 @@ describe("convertConfig", () => {
5555
await convertConfig(request);
5656

5757
// Assert
58-
expect(request.ruleFinder).toHaveBeenLastCalledWith("./tslint.json");
58+
expect(request.findTslintConfiguration).toHaveBeenLastCalledWith("./tslint.json");
5959
});
6060

61-
it("returns a failure result when ruleFinder returns an error", async () => {
61+
it("returns a failure result when findTslintConfiguration returns an error", async () => {
6262
// Arrange
6363
const error = new Error("oh no");
6464
const request = {
6565
...defaultRequest,
66-
ruleFinder: jest.fn().mockReturnValue(Promise.resolve(error)),
66+
findTslintConfiguration: jest.fn().mockReturnValue(Promise.resolve(error)),
6767
};
6868

6969
// Act
@@ -76,11 +76,11 @@ describe("convertConfig", () => {
7676
});
7777
});
7878

79-
it("creates a new configuration when ruleFinder returns rules", async () => {
79+
it("creates a new configuration when findTslintConfiguration returns rules", async () => {
8080
// Arrange
8181
const request = {
8282
...defaultRequest,
83-
ruleFinder: jest.fn().mockReturnValue({
83+
findTslintConfiguration: jest.fn().mockReturnValue({
8484
rules: {
8585
"sample-rule": {
8686
ruleArguments: ["one", "two"],

src/convertConfig.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
1-
import { FoundTSLintRules } from "./input/findTslintRules";
1+
import { TSLintConfiguration } from "./input/findTslintConfiguration";
22
import { ProcessLogger } from "./logger";
33
import { reportConversionResults } from "./reportConversionResults";
44
import { convertRules, ConfigConversionResults } from "./rules/convertRules";
55
import { converters } from "./rules/converters";
66
import { TSLintToESLintSettings, TSLintToESLintResult, ResultStatus } from "./types";
77

8-
export type CreateNewConfiguration = (conversionResults: ConfigConversionResults) => Promise<void>;
8+
export type CreateNewConfiguration = (
9+
conversionResults: ConfigConversionResults,
10+
originalConfiguration: TSLintConfiguration,
11+
) => Promise<void>;
912

1013
export type FileExists = (filePath: string) => Promise<boolean>;
1114

12-
export type RuleFinder = (config: string) => Promise<FoundTSLintRules | Error>;
15+
export type findTslintConfiguration = (config: string) => Promise<TSLintConfiguration | Error>;
1316

1417
export type ConvertConfigRequest = {
1518
createNewConfiguration: CreateNewConfiguration;
1619
fileExists: FileExists;
20+
findTslintConfiguration: findTslintConfiguration;
1721
logger: ProcessLogger;
18-
ruleFinder: RuleFinder;
1922
settings: TSLintToESLintSettings;
2023
};
2124

2225
export const convertConfig = async ({
2326
createNewConfiguration,
2427
fileExists,
28+
findTslintConfiguration,
2529
logger,
26-
ruleFinder,
2730
settings,
2831
}: ConvertConfigRequest): Promise<TSLintToESLintResult> => {
2932
const { config = "./tslint.json" } = settings;
@@ -34,23 +37,23 @@ export const convertConfig = async ({
3437
};
3538
}
3639

37-
const originalRules = await ruleFinder(config);
38-
if (originalRules instanceof Error) {
40+
const originalConfiguration = await findTslintConfiguration(config);
41+
if (originalConfiguration instanceof Error) {
3942
return {
40-
error: originalRules,
43+
error: originalConfiguration,
4144
status: ResultStatus.Failed,
4245
};
4346
}
4447

4548
const convertedRules = convertRules(
46-
Object.entries(originalRules.rules).map(([ruleName, value]) => ({
49+
Object.entries(originalConfiguration.rules).map(([ruleName, value]) => ({
4750
ruleName,
4851
...value,
4952
})),
5053
converters,
5154
);
5255

53-
await createNewConfiguration(convertedRules);
56+
await createNewConfiguration(convertedRules, originalConfiguration);
5457
reportConversionResults(convertedRules, logger);
5558

5659
return {

src/creation/createNewConfiguration.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { emptyConversionResults } from "../stubs";
22
import { createNewConfiguration } from "./createNewConfiguration";
33
import { ConfigConversionResults } from "../rules/convertRules";
44

5+
const originalConfiguration = {
6+
ruleDirectories: [],
7+
rules: {},
8+
};
9+
510
describe("createNewConfiguration", () => {
611
it("excludes the tslint plugin when there are no missing rules", async () => {
712
// Arrange
@@ -12,7 +17,7 @@ describe("createNewConfiguration", () => {
1217
const writeFile = jest.fn().mockReturnValue(Promise.resolve());
1318

1419
// Act
15-
await createNewConfiguration(conversionResults, writeFile);
20+
await createNewConfiguration(conversionResults, originalConfiguration, writeFile);
1621

1722
// Assert
1823
expect(writeFile).toHaveBeenLastCalledWith(
@@ -47,7 +52,7 @@ describe("createNewConfiguration", () => {
4752
const writeFile = jest.fn().mockReturnValue(Promise.resolve());
4853

4954
// Act
50-
await createNewConfiguration(conversionResults, writeFile);
55+
await createNewConfiguration(conversionResults, originalConfiguration, writeFile);
5156

5257
// Assert
5358
expect(writeFile).toHaveBeenLastCalledWith(

src/creation/createNewConfiguration.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { TSLintConfiguration } from "../input/findTslintConfiguration";
12
import { ConfigConversionResults } from "../rules/convertRules";
23
import { formatConvertedRules } from "./formatConvertedRules";
34

45
export type WriteFile = (filePath: string, contents: string) => Promise<void>;
56

67
export const createNewConfiguration = async (
78
conversionResults: ConfigConversionResults,
9+
originalConfiguration: TSLintConfiguration,
810
writeFile: WriteFile,
911
) => {
1012
const output = {
@@ -15,7 +17,7 @@ export const createNewConfiguration = async (
1517
...(conversionResults.missing.length && {
1618
plugins: ["@typescript-eslint/tslint"],
1719
}),
18-
rules: formatConvertedRules(conversionResults),
20+
rules: formatConvertedRules(conversionResults, originalConfiguration),
1921
};
2022

2123
await writeFile(".eslintrc.json", JSON.stringify(output, undefined, 4));

src/creation/formatConvertedRules.test.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { ConfigConversionResults } from "../rules/convertRules";
22
import { emptyConversionResults } from "../stubs";
33
import { formatConvertedRules } from "./formatConvertedRules";
44

5+
const originalConfiguration = {
6+
ruleDirectories: [],
7+
rules: {},
8+
};
9+
510
describe("formatConvertedRules", () => {
611
it("prints rules sorted by name when there are multiple rules", () => {
712
// Arrange
@@ -26,7 +31,7 @@ describe("formatConvertedRules", () => {
2631
};
2732

2833
// Act
29-
const output = formatConvertedRules(results);
34+
const output = formatConvertedRules(results, originalConfiguration);
3035

3136
// Assert
3237
expect(output).toEqual({
@@ -51,7 +56,7 @@ describe("formatConvertedRules", () => {
5156
};
5257

5358
// Act
54-
const output = formatConvertedRules(results);
59+
const output = formatConvertedRules(results, originalConfiguration);
5560

5661
// Assert
5762
expect(output).toEqual({
@@ -76,7 +81,7 @@ describe("formatConvertedRules", () => {
7681
};
7782

7883
// Act
79-
const output = formatConvertedRules(results);
84+
const output = formatConvertedRules(results, originalConfiguration);
8085

8186
// Assert
8287
expect(output).toEqual({
@@ -101,7 +106,7 @@ describe("formatConvertedRules", () => {
101106
};
102107

103108
// Act
104-
const output = formatConvertedRules(results);
109+
const output = formatConvertedRules(results, originalConfiguration);
105110

106111
// Assert
107112
expect(output).toEqual({
@@ -133,7 +138,7 @@ describe("formatConvertedRules", () => {
133138
};
134139

135140
// Act
136-
const output = formatConvertedRules(results);
141+
const output = formatConvertedRules(results, originalConfiguration);
137142

138143
// Assert
139144
expect(output).toEqual({

src/creation/formatConvertedRules.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { ConfigConversionResults } from "../rules/convertRules";
22
import { ESLintRuleOptions } from "../rules/types";
33
import { formatMissingRules } from "./formatMissingRules";
4+
import { TSLintConfiguration } from "../input/findTslintConfiguration";
45

5-
export const formatConvertedRules = (conversionResults: ConfigConversionResults) => {
6+
export const formatConvertedRules = (
7+
conversionResults: ConfigConversionResults,
8+
originalConfiguration: TSLintConfiguration,
9+
) => {
610
const output: { [i: string]: string | any[] } = {};
711
const sortedRuleEntries = Array.from(conversionResults.converted).sort(
812
([ruleNameA], [ruleNameB]) => ruleNameA.localeCompare(ruleNameB),
@@ -13,7 +17,10 @@ export const formatConvertedRules = (conversionResults: ConfigConversionResults)
1317
}
1418

1519
if (conversionResults.missing.length !== 0) {
16-
output["@typescript-eslint/tslint/config"] = formatMissingRules(conversionResults.missing);
20+
output["@typescript-eslint/tslint/config"] = formatMissingRules(
21+
conversionResults.missing,
22+
originalConfiguration.ruleDirectories,
23+
);
1724
}
1825

1926
return output;

src/creation/formatMissingRules.test.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe("formatMissingRules", () => {
1313
];
1414

1515
// Act
16-
const output = formatMissingRules(missing);
16+
const output = formatMissingRules(missing, []);
1717

1818
// Assert
1919
expect(output).toEqual([
@@ -37,7 +37,7 @@ describe("formatMissingRules", () => {
3737
];
3838

3939
// Act
40-
const output = formatMissingRules(missing);
40+
const output = formatMissingRules(missing, []);
4141

4242
// Assert
4343
expect(output).toEqual([
@@ -66,7 +66,7 @@ describe("formatMissingRules", () => {
6666
];
6767

6868
// Act
69-
const output = formatMissingRules(missing);
69+
const output = formatMissingRules(missing, []);
7070

7171
// Assert
7272
expect(output).toEqual([
@@ -96,7 +96,7 @@ describe("formatMissingRules", () => {
9696
];
9797

9898
// Act
99-
const output = formatMissingRules(missing);
99+
const output = formatMissingRules(missing, []);
100100

101101
// Assert
102102
expect(output).toEqual([
@@ -108,4 +108,30 @@ describe("formatMissingRules", () => {
108108
},
109109
]);
110110
});
111+
112+
it("includes rule directories when there are rule directories", () => {
113+
// Arrange
114+
const ruleDirectories = ["./path/to/rules"];
115+
const missing: TSLintRuleOptions[] = [
116+
{
117+
ruleArguments: [],
118+
ruleName: "tslint-rule-a",
119+
ruleSeverity: "warning",
120+
},
121+
];
122+
123+
// Act
124+
const output = formatMissingRules(missing, ruleDirectories);
125+
126+
// Assert
127+
expect(output).toEqual([
128+
"error",
129+
{
130+
ruleDirectories,
131+
rules: {
132+
"tslint-rule-a": true,
133+
},
134+
},
135+
]);
136+
});
111137
});

src/creation/formatMissingRules.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { TSLintRuleOptions } from "../rules/types";
22

3-
export const formatMissingRules = (missing: TSLintRuleOptions[]) => {
3+
export const formatMissingRules = (missing: TSLintRuleOptions[], ruleDirectories: string[]) => {
44
const rules: { [i: string]: unknown } = {};
55

66
for (const rule of missing.sort((a, b) => a.ruleName.localeCompare(b.ruleName))) {
@@ -12,8 +12,8 @@ export const formatMissingRules = (missing: TSLintRuleOptions[]) => {
1212
return [
1313
"error",
1414
{
15+
...(ruleDirectories.length !== 0 && { ruleDirectories }),
1516
rules,
16-
// TODO: rulesDirectory?
1717
},
1818
];
1919
};

0 commit comments

Comments
 (0)