Skip to content

[Experimental Feature] Opt in flag convert disable comments #246

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 24 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
29baeee
Set basic replace comment conversion
Oct 20, 2019
e84bb8c
Fix regex pattern and cli command name for convert comments
Oct 20, 2019
dcfce0c
Fix regex pattern condition to match rules without carriage return
Oct 20, 2019
300ebd3
Replace regex and use tslint functions to retrieve tslint comment data
Oct 21, 2019
fae2869
Switching rule handler
Dec 8, 2019
5dbd345
Merge branch 'master' into feature/opt-in-flag-convert-disable-comments
Dec 8, 2019
8cb8c06
Write file after switching rule comments
Dec 9, 2019
67b4d66
Merge branch 'master' into feature/opt-in-flag-convert-disable-comments
KingDarBoja Dec 26, 2019
2830122
Merge branch 'master' into feature/opt-in-flag-convert-disable-comments
KingDarBoja Mar 28, 2020
dd319f8
replace old path to rulesConverter
KingDarBoja Mar 28, 2020
f1bd492
Merge branch 'master' into feature/opt-in-flag-convert-disable-comments
JoshuaKGoldberg Apr 14, 2020
bacf9e8
Working replacements for single line changes
JoshuaKGoldberg Apr 25, 2020
35adb28
4am and it works
JoshuaKGoldberg Apr 25, 2020
63a3876
Revert .prettierrc testing change
JoshuaKGoldberg Apr 25, 2020
0456314
Love that nullish operator
JoshuaKGoldberg Apr 25, 2020
e61a434
Comments WIP
JoshuaKGoldberg Apr 25, 2020
5248447
Seems to be all working and tested now
JoshuaKGoldberg Apr 25, 2020
da1ace3
Merge branch 'master'
JoshuaKGoldberg Apr 25, 2020
425280a
Feature add: logged directive counts as a summary
JoshuaKGoldberg Apr 25, 2020
87e8953
Docs in CLI and README.md
JoshuaKGoldberg Apr 25, 2020
3098453
Merge branch 'master'
JoshuaKGoldberg Apr 26, 2020
fa7fcda
Filled in basic test for separateErrors
JoshuaKGoldberg Apr 26, 2020
2ec5b67
Normalized output per new norms
JoshuaKGoldberg Apr 26, 2020
bf6574f
Merge branch 'master' (and added --comments validation)
JoshuaKGoldberg Apr 27, 2020
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
5 changes: 5 additions & 0 deletions src/adapters/fileSystem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import * as fs from "fs";

export type ReadDirOptions = { encoding?: string | null; withFileTypes: true };

export type FileSystem = {
fileExists: (filePath: string) => Promise<boolean>;
readFile: (filePath: string) => Promise<Error | string>;
writeFile: (filePath: string, contents: string) => Promise<Error | undefined>;
readDir: (dirPath: string, options: ReadDirOptions) => Promise<Error | fs.Dirent[]>;
};
10 changes: 9 additions & 1 deletion src/adapters/fsFileSystem.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as fs from "fs";
import { promisify } from "util";

import { FileSystem } from "./fileSystem";
import { FileSystem, ReadDirOptions } from "./fileSystem";

const readFile = promisify(fs.readFile);
const readDir = promisify(fs.readdir);
const writeFile = promisify(fs.writeFile);

export const fsFileSystem: FileSystem = {
Expand All @@ -28,4 +29,11 @@ export const fsFileSystem: FileSystem = {
return error;
}
},
readDir: async (dirPath: string, options: ReadDirOptions) => {
try {
return readDir(dirPath, options);
} catch (error) {
return error;
}
},
};
6 changes: 6 additions & 0 deletions src/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { converters } from "../rules/converters";
import { convertRules } from "../rules/convertRules";
import { mergers } from "../rules/mergers";
import { runCli, RunCliDependencies } from "./runCli";
import { convertComments, ConvertCommentsResultsDependencies } from "../rules/convertComments";

const convertRulesDependencies = {
converters,
Expand Down Expand Up @@ -67,6 +68,10 @@ const simplifyPackageRulesDependencies: SimplifyPackageRulesDependencies = {
retrieveExtendsValues: bind(retrieveExtendsValues, retrieveExtendsValuesDependencies),
};

const convertCommentsResultsDependencies: ConvertCommentsResultsDependencies = {
fileSystem: fsFileSystem,
};

const writeConversionResultsDependencies: WriteConversionResultsDependencies = {
fileSystem: fsFileSystem,
};
Expand All @@ -79,6 +84,7 @@ const convertConfigDependencies: ConvertConfigDependencies = {
),
reportConversionResults: bind(reportConversionResults, reportConversionResultsDependencies),
simplifyPackageRules: bind(simplifyPackageRules, simplifyPackageRulesDependencies),
convertComments: bind(convertComments, convertCommentsResultsDependencies),
writeConversionResults: bind(writeConversionResults, writeConversionResultsDependencies),
};

Expand Down
1 change: 1 addition & 0 deletions src/cli/runCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const runCli = async (
.option("--package [package]", "package configuration file to convert using")
.option("--tslint [tslint]", "tslint configuration file to convert using")
.option("--typescript [typescript]", "typescript configuration file to convert using")
.option("-c, --convertComments", "convert all tslint:disable comments into eslint-disable")
.option("-V --version", "output the package version");

const parsedArgv = {
Expand Down
1 change: 1 addition & 0 deletions src/conversion/convertConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const createStubDependencies = (
}),
reportConversionResults: jest.fn(),
simplifyPackageRules: async (_configurations, data) => data,
convertComments: jest.fn(),
writeConversionResults: jest.fn().mockReturnValue(Promise.resolve()),
...overrides,
});
Expand Down
11 changes: 11 additions & 0 deletions src/conversion/convertConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { findOriginalConfigurations } from "../input/findOriginalConfigurations"
import { reportConversionResults } from "../reporting/reportConversionResults";
import { convertRules } from "../rules/convertRules";
import { ResultStatus, ResultWithStatus, TSLintToESLintSettings } from "../types";
import { convertComments } from "../rules/convertComments";

export type ConvertConfigDependencies = {
convertRules: SansDependencies<typeof convertRules>;
findOriginalConfigurations: SansDependencies<typeof findOriginalConfigurations>;
reportConversionResults: SansDependencies<typeof reportConversionResults>;
simplifyPackageRules: SansDependencies<typeof simplifyPackageRules>;
convertComments: SansDependencies<typeof convertComments>;
writeConversionResults: SansDependencies<typeof writeConversionResults>;
};

Expand Down Expand Up @@ -55,6 +57,15 @@ export const convertConfig = async (
};
}

// 4.B Convert comments.
const fileCommentsError = await dependencies.convertComments();
if (fileCommentsError !== undefined) {
return {
errors: [fileCommentsError],
status: ResultStatus.Failed,
};
}

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

Expand Down
74 changes: 74 additions & 0 deletions src/rules/convertComments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { FileSystem } from "../adapters/fileSystem";
import { isError } from "../utils";
import { getCommentAtPosition } from "tsutils";
import * as ts from "typescript";

// Check https://github.com/Microsoft/TypeScript/issues/21049

export type ConvertCommentsResultsDependencies = {
fileSystem: Pick<FileSystem, "readDir" | "readFile" | "writeFile">;
};

export const convertComments = async (dependencies: ConvertCommentsResultsDependencies) => {
// TODO: Remove console logs
console.log("Started");
const filenames = await dependencies.fileSystem.readDir("./", { withFileTypes: true });
if (!isError(filenames)) {
const filteredFilenames: string[] = filenames
.filter(fileEnt => fileEnt.isFile())
.map(fileEnt => fileEnt.name);
// TODO: Remove console logs
console.log("Filenames filtered");
console.log(filteredFilenames);
for (const filename of filteredFilenames) {
const fileContent: string | Error = await dependencies.fileSystem.readFile(filename);
if (!isError(fileContent)) {
const writeFileRes = await replaceComments(dependencies, filename, fileContent);
if (isError(writeFileRes)) {
return Error("Failed to convert file comments");
}
}
}
return undefined;
} else {
return Error("Failed to convert file comments");
}
};

const replaceComments = async (
dependencies: ConvertCommentsResultsDependencies,
fileName: string,
fileContent: string,
) => {
const tslintRegex: RegExp = new RegExp(
/\/[\/\*]\s*(tslint):(enable|disable)((?:-next)?-line)?(?::\s)?(:?(?:(?:[\w-]+\/)*[\w-]+\s*\s*)*(?:(?:[\w-]+\/)*[\w-]+\s*)*[\w-]+)?\s*?(?:$|\*\/)/gm,
);
const sourceFile: ts.SourceFile = ts.createSourceFile(
fileName,
fileContent,
ts.ScriptTarget.ES2015,
/*setParentNodes */ true,
);
for (
let match = tslintRegex.exec(sourceFile.text);
match !== null;
match = tslintRegex.exec(sourceFile.text)
) {
// TODO: Remove console logs
console.log("Match");
console.log(match);
console.log(match[0].length);
const comment: ts.CommentRange | undefined = getCommentAtPosition(sourceFile, match.index);
console.log("comment");
console.log(comment);
if (
comment === undefined ||
comment.pos !== match.index ||
comment.end !== match.index + match[0].length
) {
continue;
}
console.log("Passed Check");
}
return await dependencies.fileSystem.writeFile(fileName, fileContent);
};
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export type TSLintToESLintSettings = {
* Original TypeScript configuration file path, such as `tsconfig.json`.
*/
typescript?: string;

/**
* Opt-in flag to convert `tslint:disable` comments to `eslint-disable`.
*/
convertComments?: boolean;
};

export type TSLintToESLintResult = ResultWithStatus;
Expand Down