mirror of
https://github.com/chenasraf/DefinitelyTyped.git
synced 2026-05-17 17:48:06 +00:00
[infra] Port scripts from TS -> JS (#61102)
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,8 +3,6 @@
|
||||
*.cmd
|
||||
*.pdb
|
||||
*.suo
|
||||
*.js
|
||||
*.cjs
|
||||
*.user
|
||||
*.cache
|
||||
*.cs
|
||||
@@ -31,9 +29,6 @@ _infrastructure/tests/build
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
*.js.map
|
||||
!*.js/
|
||||
|
||||
# npm
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
"node": ">=7.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-scripts": "tsc -p scripts",
|
||||
"not-needed": "node scripts/not-needed.js",
|
||||
"update-codeowners": "node scripts/update-codeowners.js",
|
||||
"test-all": "node node_modules/@definitelytyped/dtslint-runner/dist/index.js --path .",
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Usage: ts-node fix-tslint.ts
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
@@ -25,29 +23,25 @@ for (const dirName of fs.readdirSync(home)) {
|
||||
}
|
||||
}
|
||||
|
||||
function fixTslint(dir: URL): void {
|
||||
/**
|
||||
* @param {URL} dir
|
||||
*/
|
||||
function fixTslint(dir) {
|
||||
const target = new URL('tslint.json', dir);
|
||||
if (!fs.existsSync(target)) return;
|
||||
let json = JSON.parse(fs.readFileSync(target, 'utf-8'));
|
||||
json = fix(json);
|
||||
const text = Object.keys(json).length === 1 ? '{ "extends": "@definitelytyped/dtslint/dt.json" }' : JSON.stringify(json, undefined, 4);
|
||||
fs.writeFileSync(target, text + "\n", "utf-8");
|
||||
const json = JSON.parse(fs.readFileSync(target, 'utf-8'));
|
||||
json.rules = fixRules(json.rules);
|
||||
const text =
|
||||
Object.keys(json).length === 1
|
||||
? '{ "extends": "@definitelytyped/dtslint/dt.json" }'
|
||||
: JSON.stringify(json, undefined, 4);
|
||||
fs.writeFileSync(target, text + '\n', 'utf-8');
|
||||
}
|
||||
|
||||
function fix(config: any): any {
|
||||
const out: any = {};
|
||||
for (const key in config) {
|
||||
let value = config[key];
|
||||
out[key] = key === "rules" ? fixRules(value) : value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function fixRules(rules: any): any {
|
||||
const out: any = {};
|
||||
for (const key in rules) {
|
||||
out[key] = rules[key];
|
||||
}
|
||||
return out;
|
||||
/**
|
||||
* @param {{}} rules
|
||||
*/
|
||||
function fixRules(rules) {
|
||||
return Object.fromEntries(Object.entries(rules).map(([key, value]) => [key, value]));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Usage: ts-node generate-tsconfigs.ts
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
@@ -24,30 +22,20 @@ for (const dirName of fs.readdirSync(home)) {
|
||||
}
|
||||
}
|
||||
|
||||
function fixTsconfig(dir: URL): void {
|
||||
/**
|
||||
* @param {URL} dir
|
||||
*/
|
||||
function fixTsconfig(dir) {
|
||||
const target = new URL('tsconfig.json', dir);
|
||||
let json = JSON.parse(fs.readFileSync(target, 'utf-8'));
|
||||
json = fix(json);
|
||||
const json = JSON.parse(fs.readFileSync(target, 'utf-8'));
|
||||
json.compilerOptions = fixCompilerOptions(json.compilerOptions);
|
||||
fs.writeFileSync(target, JSON.stringify(json, undefined, 4), 'utf-8');
|
||||
}
|
||||
|
||||
function fix(config: any): any {
|
||||
const out: any = {};
|
||||
for (const key in config) {
|
||||
let value = config[key];
|
||||
if (key === 'compilerOptions') {
|
||||
value = fixCompilerOptions(value);
|
||||
}
|
||||
out[key] = value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function fixCompilerOptions(config: any): any {
|
||||
const out: any = {};
|
||||
for (const key in config) {
|
||||
out[key] = config[key];
|
||||
// Do something interesting here
|
||||
}
|
||||
return out;
|
||||
/**
|
||||
* @param {{}} compilerOptions
|
||||
*/
|
||||
function fixCompilerOptions(compilerOptions) {
|
||||
// Do something interesting here
|
||||
return Object.fromEntries(Object.entries(compilerOptions).map(([key, value]) => [key, value]));
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
// @ts-check
|
||||
import { flatMap, mapDefined } from "@definitelytyped/utils";
|
||||
import * as os from "node:os";
|
||||
import fsExtra from 'fs-extra';
|
||||
import fsExtra from "fs-extra";
|
||||
const { writeFileSync, readFileSync, readdirSync, existsSync } = fsExtra;
|
||||
import hp from "@definitelytyped/header-parser";
|
||||
import { Octokit } from "@octokit/core";
|
||||
@@ -71,7 +69,7 @@ function getAllHeaders() {
|
||||
parsed = hp.parseHeaderOrFail(indexContent);
|
||||
} catch (e) {}
|
||||
if (parsed) {
|
||||
headers[index] = { ...parsed, raw: indexContent };
|
||||
headers[/** @type {never} */ (index)] = { ...parsed, raw: indexContent };
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -87,6 +85,7 @@ async function fetchGhosts(users) {
|
||||
const maxPageSize = 2000;
|
||||
const pages = Math.ceil(users.size / maxPageSize);
|
||||
const userArray = Array.from(users);
|
||||
/** @type string[] */
|
||||
const ghosts = [];
|
||||
for (let page = 0; page < pages; page++) {
|
||||
const startIndex = page * maxPageSize;
|
||||
@@ -124,7 +123,8 @@ async function tryGQL(fn) {
|
||||
const result = await fn();
|
||||
if (result.data) return result.data;
|
||||
return result;
|
||||
} catch (resultWithErrors) {
|
||||
// @ts-expect-error
|
||||
} catch (/** @type {{}} */ resultWithErrors) {
|
||||
if (resultWithErrors.data) {
|
||||
return resultWithErrors.data;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"exclude": ["fix-tslint.ts", "update-config"],
|
||||
"exclude": ["close-old-issues.js", "fix-tslint.js"],
|
||||
"compilerOptions": {
|
||||
"noUnusedLocals": true,
|
||||
"target": "es6",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
@@ -9,7 +10,8 @@
|
||||
"resolveJsonModule": true,
|
||||
"typeRoots": ["../types"],
|
||||
"types": [],
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
"checkJs": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["es2019"]
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@ notNeededPackages.packages[typingsPackageName] = { libraryName, asOfVersion };
|
||||
notNeededPackages.packages = Object.fromEntries(Object.entries(notNeededPackages.packages).sort());
|
||||
fs.writeFileSync('notNeededPackages.json', JSON.stringify(notNeededPackages, undefined, 4) + '\n', 'utf-8');
|
||||
|
||||
/**
|
||||
* @param {string} dir
|
||||
*/
|
||||
function rmdirRecursive(dir) {
|
||||
for (let entry of fs.readdirSync(dir)) {
|
||||
entry = path.join(dir, entry);
|
||||
|
||||
@@ -25,18 +25,21 @@ const supported = Object.entries(data)
|
||||
|
||||
const x = scaleTime()
|
||||
.domain([
|
||||
min(
|
||||
supported,
|
||||
(d) =>
|
||||
// Clip 1/4 of the earliest supported version. Cuts off the
|
||||
// release date (unimportant?) but gives the visual impression
|
||||
// of additional, unsupported versions?
|
||||
new Date(
|
||||
Number(d.releaseDate) +
|
||||
((d.endDate as never) - (d.releaseDate as never)) / 4
|
||||
)
|
||||
)!,
|
||||
max(supported, (d) => d.endDate)!,
|
||||
/** @type {never} */ (
|
||||
min(
|
||||
supported,
|
||||
(d) =>
|
||||
// Clip 1/4 of the earliest supported version. Cuts off the
|
||||
// release date (unimportant?) but gives the visual impression
|
||||
// of additional, unsupported versions?
|
||||
new Date(
|
||||
Number(d.releaseDate) +
|
||||
// prettier-ignore
|
||||
(/** @type {never} */ (d.endDate) - /** @type {never} */ (d.releaseDate)) / 4
|
||||
)
|
||||
)
|
||||
),
|
||||
/** @type {never} */ (max(supported, (d) => d.endDate)),
|
||||
])
|
||||
.nice()
|
||||
.range([margin.left, width - margin.right]);
|
||||
@@ -80,7 +83,7 @@ svg
|
||||
.data(supported)
|
||||
.join("rect")
|
||||
.attr("x", (d) => x(d.releaseDate))
|
||||
.attr("y", (d) => y(d.version)!)
|
||||
.attr("y", (d) => /** @type {never} */ (y(d.version)))
|
||||
.attr("width", (d) => x(d.endDate) - x(d.releaseDate))
|
||||
.attr("height", y.bandwidth())
|
||||
.attr("fill", (d, i) => (i % 2 === 0 ? "#3178c6" : "#235a97"));
|
||||
@@ -106,7 +109,7 @@ texts
|
||||
.attr("fill", "#ffffff")
|
||||
.append("text")
|
||||
.attr("x", (d) => x(d.releaseDate) + (x(d.endDate) - x(d.releaseDate)) / 2)
|
||||
.attr("y", (d) => y(d.version)!)
|
||||
.attr("y", (d) => /** @type {never} */ (y(d.version)))
|
||||
.attr("dy", "0.35em")
|
||||
.text((d) => d.version);
|
||||
texts
|
||||
@@ -116,7 +119,7 @@ texts
|
||||
.data(supported)
|
||||
.join("text")
|
||||
.attr("x", (d) => x(d.releaseDate) + (x(d.endDate) - x(d.releaseDate)) / 4)
|
||||
.attr("y", (d) => y(d.version)!)
|
||||
.attr("y", (d) => /** @type {never} */ (y(d.version)))
|
||||
.attr("dy", "0.35em")
|
||||
.text((d) => formatDate(d.releaseDate));
|
||||
texts
|
||||
@@ -129,7 +132,7 @@ texts
|
||||
"x",
|
||||
(d) => x(d.releaseDate) + ((x(d.endDate) - x(d.releaseDate)) * 3) / 4
|
||||
)
|
||||
.attr("y", (d) => y(d.version)!)
|
||||
.attr("y", (d) => /** @type {never} */ (y(d.version)))
|
||||
.attr("dy", "0.35em")
|
||||
.text((d) => formatDate(d.endDate));
|
||||
process.stdout.write(serialize(svg.node()!));
|
||||
process.stdout.write(serialize(/** @type {never} */ (svg.node())));
|
||||
73
scripts/update-config/LintPackage.js
Normal file
73
scripts/update-config/LintPackage.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as stringify from "json-stable-stringify";
|
||||
import * as path from "node:path";
|
||||
import { Configuration as Config, Linter } from "tslint";
|
||||
import { isExternalDependency } from "./dependencies";
|
||||
|
||||
/**
|
||||
* Represents a package from the linter's perspective.
|
||||
* For example, `DefinitelyTyped/types/react` and `DefinitelyTyped/types/react/v15` are different
|
||||
* packages.
|
||||
*/
|
||||
export class LintPackage {
|
||||
/** @type {import("typescript").SourceFile[]} */
|
||||
#files = [];
|
||||
#rootDir;
|
||||
#program;
|
||||
|
||||
/**
|
||||
* @param {string} rootDir
|
||||
*/
|
||||
constructor(rootDir) {
|
||||
this.#rootDir = rootDir;
|
||||
this.#program = Linter.createProgram(path.join(this.#rootDir, "tsconfig.json"));
|
||||
}
|
||||
|
||||
config() {
|
||||
return Config.readConfigurationFile(path.join(this.#rootDir, "tslint.json"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
*/
|
||||
addFile(filePath) {
|
||||
const file = this.#program.getSourceFile(filePath);
|
||||
if (file) {
|
||||
this.#files.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("tslint").ILinterOptions} opts
|
||||
* @param {import("tslint").Configuration.IConfigurationFile} config
|
||||
*/
|
||||
lint(opts, config) {
|
||||
const linter = new Linter(opts, this.#program);
|
||||
for (const file of this.#files) {
|
||||
if (ignoreFile(file, this.#rootDir, this.#program)) {
|
||||
continue;
|
||||
}
|
||||
linter.lint(file.fileName, file.text, config);
|
||||
}
|
||||
return linter.getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("tslint").Configuration.RawConfigFile} config
|
||||
*/
|
||||
updateConfig(config) {
|
||||
fs.writeFileSync(path.join(this.#rootDir, "tslint.json"), stringify(config, { space: 4 }), {
|
||||
encoding: "utf8",
|
||||
flag: "w",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("typescript").SourceFile} file
|
||||
* @param {string} dirPath
|
||||
* @param {import("typescript").Program} program
|
||||
*/
|
||||
function ignoreFile(file, dirPath, program) {
|
||||
return program.isSourceFileDefaultLibrary(file) || isExternalDependency(file, path.resolve(dirPath), program);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as stringify from "json-stable-stringify";
|
||||
import * as path from "node:path";
|
||||
import { Configuration as Config, ILinterOptions, Linter, LintResult } from "tslint";
|
||||
import ts from "typescript";
|
||||
import { isExternalDependency } from "./dependencies";
|
||||
|
||||
/**
|
||||
* Represents a package from the linter's perspective.
|
||||
* For example, `DefinitelyTyped/types/react` and `DefinitelyTyped/types/react/v15` are different
|
||||
* packages.
|
||||
*/
|
||||
export class LintPackage {
|
||||
private files: ts.SourceFile[] = [];
|
||||
private program: ts.Program;
|
||||
|
||||
constructor(private rootDir: string) {
|
||||
this.program = Linter.createProgram(path.join(this.rootDir, "tsconfig.json"));
|
||||
}
|
||||
|
||||
config(): Config.RawConfigFile {
|
||||
return Config.readConfigurationFile(path.join(this.rootDir, "tslint.json"));
|
||||
}
|
||||
|
||||
addFile(filePath: string): void {
|
||||
const file = this.program.getSourceFile(filePath);
|
||||
if (file) {
|
||||
this.files.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
lint(opts: ILinterOptions, config: Config.IConfigurationFile): LintResult {
|
||||
const linter = new Linter(opts, this.program);
|
||||
for (const file of this.files) {
|
||||
if (ignoreFile(file, this.rootDir, this.program)) {
|
||||
continue;
|
||||
}
|
||||
linter.lint(file.fileName, file.text, config);
|
||||
}
|
||||
return linter.getResult();
|
||||
}
|
||||
|
||||
updateConfig(config: Config.RawConfigFile): void {
|
||||
fs.writeFileSync(
|
||||
path.join(this.rootDir, "tslint.json"),
|
||||
stringify(config, { space: 4 }),
|
||||
{ encoding: "utf8", flag: "w" });
|
||||
}
|
||||
}
|
||||
|
||||
function ignoreFile(file: ts.SourceFile, dirPath: string, program: ts.Program): boolean {
|
||||
return program.isSourceFileDefaultLibrary(file) || isExternalDependency(file, path.resolve(dirPath), program);
|
||||
}
|
||||
@@ -1,18 +1,29 @@
|
||||
import * as path from "node:path";
|
||||
import ts from "typescript";
|
||||
|
||||
export function isExternalDependency(file: ts.SourceFile, dirPath: string, program: ts.Program): boolean {
|
||||
/**
|
||||
* @param {import("typescript").SourceFile} file
|
||||
* @param {string} dirPath
|
||||
* @param {import("typescript").Program} program
|
||||
*/
|
||||
export function isExternalDependency(file, dirPath, program) {
|
||||
return !startsWithDirectory(file.fileName, dirPath) || program.isSourceFileFromExternalLibrary(file);
|
||||
}
|
||||
|
||||
export function normalizePath(file: string) {
|
||||
/**
|
||||
* @param {string} file
|
||||
*/
|
||||
export function normalizePath(file) {
|
||||
// replaces '\' with '/' and forces all DOS drive letters to be upper-case
|
||||
return path.normalize(file)
|
||||
.replace(/\\/g, "/")
|
||||
.replace(/^[a-z](?=:)/, c => c.toUpperCase());
|
||||
}
|
||||
|
||||
function startsWithDirectory(filePath: string, dirPath: string): boolean {
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {string} dirPath
|
||||
*/
|
||||
function startsWithDirectory(filePath, dirPath) {
|
||||
const normalFilePath = normalizePath(filePath);
|
||||
const normalDirPath = normalizePath(dirPath).replace(/\/$/, "");
|
||||
return normalFilePath.startsWith(normalDirPath + "/") || normalFilePath.startsWith(normalDirPath + "\\");
|
||||
@@ -39,6 +39,7 @@ async function main() {
|
||||
if (!arg.package && !arg.dt) {
|
||||
throw new Error("You must provide either argument 'package' or 'dt'.");
|
||||
}
|
||||
// @ts-expect-error
|
||||
const unsupportedRules = arg.rules.filter(rule => ignoredRules.has(rule));
|
||||
if (unsupportedRules.length > 0) {
|
||||
throw new Error(`Rules ${unsupportedRules.join(", ")} are not supported at the moment.`);
|
||||
@@ -55,8 +56,11 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
function dtConfig(updatedRules: string[]): Config.IConfigurationFile {
|
||||
const resolvedDtslint = require.resolve('dtslint');
|
||||
/**
|
||||
* @param {string[]} updatedRules
|
||||
*/
|
||||
function dtConfig(updatedRules) {
|
||||
const resolvedDtslint = require.resolve("dtslint");
|
||||
const dtConfigPath = normalizePath(
|
||||
path.join(
|
||||
resolvedDtslint.slice(0, resolvedDtslint.lastIndexOf("dtslint")),
|
||||
@@ -77,7 +81,11 @@ function dtConfig(updatedRules: string[]): Config.IConfigurationFile {
|
||||
return config;
|
||||
}
|
||||
|
||||
function updateAll(dtPath: string, config: Config.IConfigurationFile): void {
|
||||
/**
|
||||
* @param {string} dtPath
|
||||
* @param {Config.IConfigurationFile} config
|
||||
*/
|
||||
function updateAll(dtPath, config) {
|
||||
const packages = fs.readdirSync(path.join(dtPath, "types"));
|
||||
for (const pkg of packages) {
|
||||
updatePackage(path.join(dtPath, "types", pkg), config);
|
||||
@@ -1,11 +1,11 @@
|
||||
import { defaultErrors, ErrorKind, ExportErrorKind, Mode } from "dts-critic";
|
||||
import * as Lint from "tslint";
|
||||
import { defaultErrors, ErrorKind, Mode } from "@definitelytyped/dts-critic";
|
||||
|
||||
/**
|
||||
* Given npm-naming lint failures, returns a rule configuration that prevents such failures.
|
||||
* @param {import("tslint").IRuleFailureJson[]} failures
|
||||
*/
|
||||
export function npmNamingDisabler(failures: Lint.IRuleFailureJson[]) {
|
||||
const disabledErrors = new Set<ExportErrorKind>();
|
||||
export function npmNamingDisabler(failures) {
|
||||
const disabledErrors = new Set();
|
||||
for (const ruleFailure of failures) {
|
||||
if (ruleFailure.ruleName !== "npm-naming") {
|
||||
throw new Error(`Expected failures of rule "npm-naming", found failures of rule ${ruleFailure.ruleName}.`);
|
||||
@@ -28,10 +28,9 @@ export function npmNamingDisabler(failures: Lint.IRuleFailureJson[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((defaultErrors as ExportErrorKind[]).every(error => disabledErrors.has(error))) {
|
||||
if (defaultErrors.every(error => disabledErrors.has(error))) {
|
||||
return [true, { mode: Mode.NameOnly }];
|
||||
}
|
||||
const errors: Array<[ExportErrorKind, boolean]> = [];
|
||||
disabledErrors.forEach(error => errors.push([error, false]));
|
||||
const errors = [...disabledErrors].map(error => [error, false]);
|
||||
return [true, { mode: Mode.Code, errors }];
|
||||
}
|
||||
@@ -1,17 +1,20 @@
|
||||
import * as cp from "node:child_process";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import { Configuration as Config, ILinterOptions, IRuleFailureJson, RuleFailure } from "tslint";
|
||||
|
||||
import { ignoredRules } from "./ignoredRules";
|
||||
import { LintPackage } from "./LintPackage";
|
||||
import { npmNamingDisabler } from "./npmNamingDisabler";
|
||||
|
||||
export function updatePackage(pkgPath: string, baseConfig: Config.IConfigurationFile): void {
|
||||
/**
|
||||
* @param {string} pkgPath
|
||||
* @param {import("tslint").Configuration.IConfigurationFile} baseConfig
|
||||
*/
|
||||
export function updatePackage(pkgPath, baseConfig) {
|
||||
installDependencies(pkgPath);
|
||||
const packages = walkPackageDir(pkgPath);
|
||||
|
||||
const linterOpts: ILinterOptions = {
|
||||
const linterOpts = {
|
||||
fix: false,
|
||||
};
|
||||
|
||||
@@ -25,10 +28,17 @@ export function updatePackage(pkgPath: string, baseConfig: Config.IConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
function walkPackageDir(rootDir: string): LintPackage[] {
|
||||
const packages: LintPackage[] = [];
|
||||
/**
|
||||
* @param {string} rootDir
|
||||
*/
|
||||
function walkPackageDir(rootDir) {
|
||||
const packages = [];
|
||||
|
||||
function walk(curPackage: LintPackage, dir: string): void {
|
||||
/**
|
||||
* @param {LintPackage} curPackage
|
||||
* @param {string} dir
|
||||
*/
|
||||
function walk(curPackage, dir) {
|
||||
for (const ent of fs.readdirSync(dir, { encoding: "utf8", withFileTypes: true })) {
|
||||
const entPath = path.join(dir, ent.name);
|
||||
if (ent.isFile()) {
|
||||
@@ -54,12 +64,16 @@ function walkPackageDir(rootDir: string): LintPackage[] {
|
||||
/**
|
||||
* Returns true if directory name matches a TypeScript or package version directory.
|
||||
* Examples: `ts3.5`, `v11`, `v0.6` are all version names.
|
||||
* @param {string} dirName
|
||||
*/
|
||||
function isVersionDir(dirName: string): boolean {
|
||||
function isVersionDir(dirName) {
|
||||
return /^ts\d+\.\d$/.test(dirName) || /^v\d+(\.\d+)?$/.test(dirName);
|
||||
}
|
||||
|
||||
function installDependencies(pkgPath: string): void {
|
||||
/**
|
||||
* @param {string} pkgPath
|
||||
*/
|
||||
function installDependencies(pkgPath) {
|
||||
if (fs.existsSync(path.join(pkgPath, "package.json"))) {
|
||||
cp.execSync(
|
||||
"npm install --ignore-scripts --no-shrinkwrap --no-package-lock --no-bin-links",
|
||||
@@ -70,55 +84,41 @@ function installDependencies(pkgPath: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function mergeConfigRules(
|
||||
config: Config.RawConfigFile,
|
||||
newRules: Config.RawRulesConfig,
|
||||
baseConfig: Config.IConfigurationFile): Config.RawConfigFile {
|
||||
const activeRules: string[] = [];
|
||||
baseConfig.rules.forEach((ruleOpts, ruleName) => {
|
||||
if (ruleOpts.ruleSeverity !== "off") {
|
||||
activeRules.push(ruleName);
|
||||
}
|
||||
});
|
||||
const oldRules: Config.RawRulesConfig = config.rules || {};
|
||||
let newRulesConfig: Config.RawRulesConfig = {};
|
||||
for (const rule of Object.keys(oldRules)) {
|
||||
if (activeRules.includes(rule)) {
|
||||
continue;
|
||||
}
|
||||
newRulesConfig[rule] = oldRules[rule];
|
||||
}
|
||||
newRulesConfig = { ...newRulesConfig, ...newRules };
|
||||
/**
|
||||
* @param {import("tslint").Configuration.RawConfigFile} config
|
||||
* @param {import("tslint").Configuration.RawRulesConfig} newRules
|
||||
* @param {import("tslint").Configuration.IConfigurationFile} baseConfig
|
||||
*/
|
||||
function mergeConfigRules(config, newRules, baseConfig) {
|
||||
const activeRules = [...baseConfig.rules.entries()]
|
||||
.filter(([, ruleOpts]) => ruleOpts.ruleSeverity !== "off")
|
||||
.map(([ruleName]) => ruleName);
|
||||
const oldRules = config.rules || {};
|
||||
const newRulesConfig = {
|
||||
...Object.fromEntries(Object.entries(oldRules).filter(([rule]) => !activeRules.includes(rule))),
|
||||
...newRules,
|
||||
};
|
||||
return { ...config, rules: newRulesConfig };
|
||||
}
|
||||
|
||||
function disableRules(allFailures: RuleFailure[]): Config.RawRulesConfig {
|
||||
const ruleToFailures: Map<string, IRuleFailureJson[]> = new Map();
|
||||
/**
|
||||
* @param {import("tslint").RuleFailure[]} allFailures
|
||||
*/
|
||||
function disableRules(allFailures) {
|
||||
/** @type {Record<string, import("tslint").IRuleFailureJson[]>} */
|
||||
const ruleToFailures = {};
|
||||
for (const failure of allFailures) {
|
||||
const failureJson = failure.toJson();
|
||||
if (ruleToFailures.has(failureJson.ruleName)) {
|
||||
ruleToFailures.get(failureJson.ruleName)!.push(failureJson);
|
||||
} else {
|
||||
ruleToFailures.set(failureJson.ruleName, [failureJson]);
|
||||
}
|
||||
if (ignoredRules.has(failureJson.ruleName)) continue;
|
||||
(ruleToFailures[failureJson.ruleName] ||= []).push(failureJson);
|
||||
}
|
||||
|
||||
const newRulesConfig: Config.RawRulesConfig = {};
|
||||
ruleToFailures.forEach((failures, rule) => {
|
||||
if (ignoredRules.has(rule)) {
|
||||
return;
|
||||
}
|
||||
const disabler = rule === "npm-naming" ? npmNamingDisabler : defaultDisabler;
|
||||
const opts: RuleOptions = disabler(failures);
|
||||
newRulesConfig[rule] = opts;
|
||||
});
|
||||
|
||||
return newRulesConfig;
|
||||
return Object.fromEntries(
|
||||
Object.entries(ruleToFailures).map(([rule, failures]) => [
|
||||
rule,
|
||||
(rule === "npm-naming" ? npmNamingDisabler : defaultDisabler)(failures),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
type RuleOptions = boolean | unknown[];
|
||||
type RuleDisabler = (failures: IRuleFailureJson[]) => RuleOptions;
|
||||
|
||||
const defaultDisabler: RuleDisabler = () => {
|
||||
return false;
|
||||
};
|
||||
const defaultDisabler = () => false;
|
||||
Reference in New Issue
Block a user