@definitelytyped/dtslint 0.0.203 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +8 -11
- package/dist/createProgram.d.ts +2 -0
- package/dist/createProgram.js +66 -0
- package/dist/createProgram.js.map +1 -0
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/lint.d.ts +0 -1
- package/dist/lint.js +13 -35
- package/dist/lint.js.map +1 -1
- package/package.json +4 -8
- package/src/createProgram.ts +48 -0
- package/src/index.ts +1 -2
- package/src/lint.ts +12 -35
- package/test/index.test.ts +0 -40
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/updateConfig.d.ts +0 -1
- package/dist/updateConfig.js +0 -214
- package/dist/updateConfig.js.map +0 -1
- package/dt.json +0 -3
- package/dtslint.json +0 -4
- package/src/updateConfig.ts +0 -241
- package/tslint.json +0 -17
package/src/updateConfig.ts
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
// This is a stand-alone script that updates TSLint configurations for DefinitelyTyped packages.
|
|
2
|
-
// It runs all rules specified in `dt.json`, and updates the existing configuration for a package
|
|
3
|
-
// by adding rule exemptions only for the rules that caused a lint failure.
|
|
4
|
-
// For example, if a configuration specifies `"no-trailing-whitespace": false` and this rule
|
|
5
|
-
// no longer produces an error, then it will not be disabled in the new configuration.
|
|
6
|
-
// If you update or create a rule and now it causes new failures in DT, you can update the `dt.json`
|
|
7
|
-
// configuration with your rule, then register a disabler function for your rule
|
|
8
|
-
// (check `disableRules` function below), then run this script with your rule as argument.
|
|
9
|
-
|
|
10
|
-
import cp = require("child_process");
|
|
11
|
-
import fs = require("fs");
|
|
12
|
-
import stringify = require("json-stable-stringify");
|
|
13
|
-
import path = require("path");
|
|
14
|
-
import { Configuration as Config, ILinterOptions, IRuleFailureJson, Linter, LintResult, RuleFailure } from "tslint";
|
|
15
|
-
import * as ts from "typescript";
|
|
16
|
-
import yargs = require("yargs");
|
|
17
|
-
import { isExternalDependency } from "./lint";
|
|
18
|
-
|
|
19
|
-
// Rule "expect" needs TypeScript version information, which this script doesn't collect.
|
|
20
|
-
const ignoredRules: string[] = ["expect"];
|
|
21
|
-
|
|
22
|
-
function main() {
|
|
23
|
-
const args = yargs
|
|
24
|
-
.usage(
|
|
25
|
-
`\`$0 --dt=path-to-dt\` or \`$0 --package=path-to-dt-package\`
|
|
26
|
-
'dt.json' is used as the base tslint config for running the linter.`,
|
|
27
|
-
)
|
|
28
|
-
.option("package", {
|
|
29
|
-
describe: "Path of DT package.",
|
|
30
|
-
type: "string",
|
|
31
|
-
conflicts: "dt",
|
|
32
|
-
})
|
|
33
|
-
.option("dt", {
|
|
34
|
-
describe: "Path of local DefinitelyTyped repository.",
|
|
35
|
-
type: "string",
|
|
36
|
-
conflicts: "package",
|
|
37
|
-
})
|
|
38
|
-
.option("rules", {
|
|
39
|
-
describe: "Names of the rules to be updated. Leave this empty to update all rules.",
|
|
40
|
-
type: "array",
|
|
41
|
-
string: true,
|
|
42
|
-
default: [] as string[],
|
|
43
|
-
})
|
|
44
|
-
.check((arg) => {
|
|
45
|
-
if (!arg.package && !arg.dt) {
|
|
46
|
-
throw new Error("You must provide either argument 'package' or 'dt'.");
|
|
47
|
-
}
|
|
48
|
-
const unsupportedRules = arg.rules.filter((rule) => ignoredRules.includes(rule));
|
|
49
|
-
if (unsupportedRules.length > 0) {
|
|
50
|
-
throw new Error(`Rules ${unsupportedRules.join(", ")} are not supported at the moment.`);
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
})
|
|
54
|
-
.parseSync();
|
|
55
|
-
|
|
56
|
-
if (args.package) {
|
|
57
|
-
updatePackage(args.package, dtConfig(args.rules));
|
|
58
|
-
} else if (args.dt) {
|
|
59
|
-
updateAll(args.dt, dtConfig(args.rules));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const dtConfigPath = "dt.json";
|
|
64
|
-
|
|
65
|
-
function dtConfig(updatedRules: string[]): Config.IConfigurationFile {
|
|
66
|
-
const config = Config.findConfiguration(dtConfigPath).results;
|
|
67
|
-
if (!config) {
|
|
68
|
-
throw new Error(`Could not load config at ${dtConfigPath}.`);
|
|
69
|
-
}
|
|
70
|
-
// Disable ignored or non-updated rules.
|
|
71
|
-
for (const entry of config.rules.entries()) {
|
|
72
|
-
const [rule, ruleOpts] = entry;
|
|
73
|
-
if (ignoredRules.includes(rule) || (updatedRules.length > 0 && !updatedRules.includes(rule))) {
|
|
74
|
-
ruleOpts.ruleSeverity = "off";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return config;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function updateAll(dtPath: string, config: Config.IConfigurationFile): void {
|
|
81
|
-
const packages = fs.readdirSync(path.join(dtPath, "types"));
|
|
82
|
-
for (const pkg of packages) {
|
|
83
|
-
updatePackage(path.join(dtPath, "types", pkg), config);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function updatePackage(pkgPath: string, baseConfig: Config.IConfigurationFile): void {
|
|
88
|
-
installDependencies(pkgPath);
|
|
89
|
-
const packages = walkPackageDir(pkgPath);
|
|
90
|
-
|
|
91
|
-
const linterOpts: ILinterOptions = {
|
|
92
|
-
fix: false,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
for (const pkg of packages) {
|
|
96
|
-
const results = pkg.lint(linterOpts, baseConfig);
|
|
97
|
-
if (results.failures.length > 0) {
|
|
98
|
-
const disabledRules = disableRules(results.failures);
|
|
99
|
-
const newConfig = mergeConfigRules(pkg.config(), disabledRules, baseConfig);
|
|
100
|
-
pkg.updateConfig(newConfig);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function installDependencies(pkgPath: string): void {
|
|
106
|
-
if (fs.existsSync(path.join(pkgPath, "package.json"))) {
|
|
107
|
-
cp.execSync("npm install --ignore-scripts --no-shrinkwrap --no-package-lock --no-bin-links", {
|
|
108
|
-
encoding: "utf8",
|
|
109
|
-
cwd: pkgPath,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function mergeConfigRules(
|
|
115
|
-
config: Config.RawConfigFile,
|
|
116
|
-
newRules: Config.RawRulesConfig,
|
|
117
|
-
baseConfig: Config.IConfigurationFile,
|
|
118
|
-
): Config.RawConfigFile {
|
|
119
|
-
const activeRules: string[] = [];
|
|
120
|
-
baseConfig.rules.forEach((ruleOpts, ruleName) => {
|
|
121
|
-
if (ruleOpts.ruleSeverity !== "off") {
|
|
122
|
-
activeRules.push(ruleName);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
const oldRules: Config.RawRulesConfig = config.rules || {};
|
|
126
|
-
let newRulesConfig: Config.RawRulesConfig = {};
|
|
127
|
-
for (const rule of Object.keys(oldRules)) {
|
|
128
|
-
if (activeRules.includes(rule)) {
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
newRulesConfig[rule] = oldRules[rule];
|
|
132
|
-
}
|
|
133
|
-
newRulesConfig = { ...newRulesConfig, ...newRules };
|
|
134
|
-
return { ...config, rules: newRulesConfig };
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Represents a package from the linter's perspective.
|
|
139
|
-
* For example, `DefinitelyTyped/types/react` and `DefinitelyTyped/types/react/v15` are different
|
|
140
|
-
* packages.
|
|
141
|
-
*/
|
|
142
|
-
class LintPackage {
|
|
143
|
-
private files: ts.SourceFile[] = [];
|
|
144
|
-
private program: ts.Program;
|
|
145
|
-
|
|
146
|
-
constructor(private rootDir: string) {
|
|
147
|
-
this.program = Linter.createProgram(path.join(this.rootDir, "tsconfig.json"));
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
config(): Config.RawConfigFile {
|
|
151
|
-
return Config.readConfigurationFile(path.join(this.rootDir, "tslint.json"));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
addFile(filePath: string): void {
|
|
155
|
-
const file = this.program.getSourceFile(filePath);
|
|
156
|
-
if (file) {
|
|
157
|
-
this.files.push(file);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
lint(opts: ILinterOptions, config: Config.IConfigurationFile): LintResult {
|
|
162
|
-
const linter = new Linter(opts, this.program);
|
|
163
|
-
for (const file of this.files) {
|
|
164
|
-
if (ignoreFile(file, this.rootDir, this.program)) {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
linter.lint(file.fileName, file.text, config);
|
|
168
|
-
}
|
|
169
|
-
return linter.getResult();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
updateConfig(config: Config.RawConfigFile): void {
|
|
173
|
-
fs.writeFileSync(path.join(this.rootDir, "tslint.json"), stringify(config, { space: 4 }), {
|
|
174
|
-
encoding: "utf8",
|
|
175
|
-
flag: "w",
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function ignoreFile(file: ts.SourceFile, dirPath: string, program: ts.Program): boolean {
|
|
181
|
-
return program.isSourceFileDefaultLibrary(file) || isExternalDependency(file, path.resolve(dirPath), program);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function walkPackageDir(rootDir: string): LintPackage[] {
|
|
185
|
-
const packages: LintPackage[] = [];
|
|
186
|
-
|
|
187
|
-
function walk(curPackage: LintPackage, dir: string): void {
|
|
188
|
-
for (const ent of fs.readdirSync(dir, { encoding: "utf8", withFileTypes: true })) {
|
|
189
|
-
const entPath = path.join(dir, ent.name);
|
|
190
|
-
if (ent.isFile()) {
|
|
191
|
-
curPackage.addFile(entPath);
|
|
192
|
-
} else if (ent.isDirectory() && ent.name !== "node_modules") {
|
|
193
|
-
if (isVersionDir(ent.name)) {
|
|
194
|
-
const newPackage = new LintPackage(entPath);
|
|
195
|
-
packages.push(newPackage);
|
|
196
|
-
walk(newPackage, entPath);
|
|
197
|
-
} else {
|
|
198
|
-
walk(curPackage, entPath);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const lintPackage = new LintPackage(rootDir);
|
|
205
|
-
packages.push(lintPackage);
|
|
206
|
-
walk(lintPackage, rootDir);
|
|
207
|
-
return packages;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Returns true if directory name matches a TypeScript or package version directory.
|
|
212
|
-
* Examples: `ts3.5`, `v11`, `v0.6` are all version names.
|
|
213
|
-
*/
|
|
214
|
-
function isVersionDir(dirName: string): boolean {
|
|
215
|
-
return /^ts\d+\.\d$/.test(dirName) || /^v\d+(\.\d+)?$/.test(dirName);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function disableRules(allFailures: RuleFailure[]): Config.RawRulesConfig {
|
|
219
|
-
const ruleToFailures: Map<string, IRuleFailureJson[]> = new Map();
|
|
220
|
-
for (const failure of allFailures) {
|
|
221
|
-
const failureJson = failure.toJson();
|
|
222
|
-
if (ruleToFailures.has(failureJson.ruleName)) {
|
|
223
|
-
ruleToFailures.get(failureJson.ruleName)!.push(failureJson);
|
|
224
|
-
} else {
|
|
225
|
-
ruleToFailures.set(failureJson.ruleName, [failureJson]);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const newRulesConfig: Config.RawRulesConfig = {};
|
|
230
|
-
for (const rule of ruleToFailures.keys()) {
|
|
231
|
-
if (!ignoredRules.includes(rule)) {
|
|
232
|
-
newRulesConfig[rule] = false;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return newRulesConfig;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (require.main === module) {
|
|
240
|
-
main();
|
|
241
|
-
}
|
package/tslint.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "tslint:latest",
|
|
3
|
-
"rules": {
|
|
4
|
-
"arrow-parens": [true, "ban-single-arg-parens"],
|
|
5
|
-
"indent": [true, "spaces"],
|
|
6
|
-
"interface-name": [true, "never-prefix"],
|
|
7
|
-
"max-line-length": [true, 130],
|
|
8
|
-
"member-access": [true, "no-public"],
|
|
9
|
-
"variable-name": [true, "check-format", "allow-leading-underscore"],
|
|
10
|
-
"curly": false,
|
|
11
|
-
|
|
12
|
-
"no-console": false,
|
|
13
|
-
"no-namespace": false,
|
|
14
|
-
"object-literal-sort-keys": false,
|
|
15
|
-
"switch-default": false
|
|
16
|
-
}
|
|
17
|
-
}
|