Skip to content

Commit

Permalink
fix: expand tsconfig.json include lists
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaKGoldberg committed Aug 5, 2022
1 parent 15d70e3 commit fde4338
Show file tree
Hide file tree
Showing 19 changed files with 5,328 additions and 5,364 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"commander": "^8.0.0",
"enquirer": "^2.3.6",
"glob": "^7.1.7",
"minimatch": "^5.1.0",
"mz": "^2.7.0",
"strip-ansi": "^6.0.0",
"tsutils": "^3.21.0",
Expand All @@ -25,6 +26,7 @@
"@babel/preset-typescript": "7.14.5",
"@types/glob": "7.1.3",
"@types/jest": "26.0.23",
"@types/minimatch": "^3.0.5",
"@types/mz": "2.7.3",
"@types/node": "16.0.0",
"@types/prop-types": "15.7.3",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const typeStat = async (argv: TypeStatArgv, output: ProcessOutput): Promi
if (typeof fileNames !== "object") {
return {
error: new Error(
`Could not run options at index ${i + 1}: ${fileNames ?? `No files included by the 'include' setting were found.`}`,
`Could not run options object ${i + 1}: ${fileNames ?? `No files included by the 'include' setting were found.`}`,
),
status: ResultStatus.Failed,
};
Expand Down
7 changes: 3 additions & 4 deletions src/options/fillOutRawOptions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as ts from "typescript";

import { TypeStatArgv } from "../index";
import { ProcessOutput } from "../output/types";
import { collectOptionals } from "../shared/arrays";
import { ReactPropTypesHint, ReactPropTypesOptionality } from "./enums";
import { ParsedCompilerOptions } from "./parseRawCompilerOptions";

import { collectAddedMutators } from "./parsing/collectAddedMutators";
import { collectFileOptions } from "./parsing/collectFileOptions";
Expand All @@ -15,7 +14,7 @@ import { PendingTypeStatOptions, RawTypeStatOptions } from "./types";

export interface OptionsFromRawOptionsSettings {
argv: TypeStatArgv;
compilerOptions: Readonly<ts.CompilerOptions>;
compilerOptions: Readonly<ParsedCompilerOptions>;
cwd: string;
output: ProcessOutput;
projectPath: string;
Expand Down Expand Up @@ -71,7 +70,7 @@ export const fillOutRawOptions = ({
propTypesOptionality: rawOptions.hints?.react?.propTypesOptionality ?? ReactPropTypesOptionality.AsWritten,
},
},
include: rawOptions.include,
include: rawOptions.include ?? compilerOptions.include,
mutators: collectAddedMutators(rawOptions, packageOptions.directory, output),
output,
package: packageOptions,
Expand Down
2 changes: 1 addition & 1 deletion src/options/loadPendingOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const loadPendingOptions = async (argv: TypeStatArgv, output: ProcessOutp
for (let i = 0; i < allRawOptions.length; i += 1) {
const rawOptions = allRawOptions[i];
const projectPath = getProjectPath(cwd, filePath, rawOptions);
const compilerOptions = await parseRawCompilerOptions(projectPath);
const compilerOptions = await parseRawCompilerOptions(cwd, projectPath);

const filledOutOptions = fillOutRawOptions({ argv, compilerOptions, cwd, output, projectPath, rawOptions });
const complaint = findComplaintForOptions(filledOutOptions);
Expand Down
36 changes: 34 additions & 2 deletions src/options/parseRawCompilerOptions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
import minimatch from "minimatch";
import * as fs from "mz/fs";
import * as path from "path";
import * as ts from "typescript";

export const parseRawCompilerOptions = async (projectPath: string): Promise<ts.CompilerOptions> => {
export interface ParsedCompilerOptions extends ts.CompilerOptions {
include?: string[];
}

export const parseRawCompilerOptions = async (cwd: string, projectPath: string): Promise<ts.CompilerOptions> => {
const configRaw = (await fs.readFile(projectPath)).toString();
const compilerOptions = ts.parseConfigFileTextToJson(projectPath, configRaw);
if (compilerOptions.error !== undefined) {
throw new Error(`Could not parse compiler options from '${projectPath}': ${compilerOptions.error}`);
}

return compilerOptions.config as ts.CompilerOptions;
const config = compilerOptions.config as ParsedCompilerOptions;

// TSConfig includes often come in a glob form like ["src"]
if (config.include) {
config.include = ts.parseJsonConfigFileContent(
compilerOptions.config,
{
useCaseSensitiveFileNames: true,
readDirectory: (rootDir, extensions, excludes, includes) =>
includes
.flatMap((include) =>
fs.readdirSync(path.join(rootDir, include)).map((fileName) => path.join(rootDir, include, fileName)),
)
.filter(
(filePath) =>
!excludes?.some((exclude) => minimatch(filePath, exclude)) &&
extensions.some((extension) => filePath.endsWith(extension)),
)
.map((filePath) => path.relative(rootDir, filePath)),
fileExists: (filePath) => fs.statSync(filePath).isFile(),
readFile: (filePath) => fs.readFileSync(filePath).toString(),
},
cwd,
).fileNames;
}

return config;
};
28 changes: 28 additions & 0 deletions src/services/parseJsonConfigFileContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import minimatch from "minimatch";
import * as fs from "mz/fs";
import * as path from "path";
import * as ts from "typescript";

export const parseJsonConfigFileContent = (config: unknown, cwd: string, existingOptions?: ts.CompilerOptions) => {
return ts.parseJsonConfigFileContent(
config,
{
useCaseSensitiveFileNames: true,
readDirectory: (rootDir, extensions, excludes, includes) =>
includes
.flatMap((include) =>
fs.readdirSync(path.join(rootDir, include)).map((fileName) => path.join(rootDir, include, fileName)),
)
.filter(
(filePath) =>
!excludes?.some((exclude) => minimatch(filePath, exclude)) &&
extensions.some((extension) => filePath.endsWith(extension)),
)
.map((filePath) => path.relative(rootDir, filePath)),
fileExists: (filePath) => fs.statSync(filePath).isFile(),
readFile: (filePath) => fs.readFileSync(filePath).toString(),
},
cwd,
existingOptions,
);
};
2 changes: 1 addition & 1 deletion src/shared/glob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export const globAsync = async (include: string, options: glob.IOptions = {}): P

export const globAllAsync = async (includes: ReadonlyArray<string>, options: glob.IOptions = {}) =>
(await Promise.all(includes.map(async (include: string) => globAsync(include, options)))).reduce(
(allResults: ReadonlyArray<string>, nextResults: ReadonlyArray<string>) => allResults.concat(nextResults),
(allResults: string[], nextResults: ReadonlyArray<string>) => allResults.concat(nextResults),
[],
);
7 changes: 7 additions & 0 deletions test/cases/include/asterisk/expected.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* foo */ /* foo */ (function() {
console.log("Hello, world!");

function ignoreChanges(): string {
return undefined;
}
})();
7 changes: 7 additions & 0 deletions test/cases/include/asterisk/original.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function() {
console.log("Hello, world!");

function ignoreChanges(): string {
return undefined;
}
})();
15 changes: 15 additions & 0 deletions test/cases/include/asterisk/sampleMutator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const prefix = "/* foo */ ";

module.exports.fileMutator = (request) => {
return request.sourceFile.getText().indexOf(prefix) === -1
? [
{
insertion: prefix,
range: {
begin: 0,
},
type: "text-insert",
},
]
: [];
};
3 changes: 3 additions & 0 deletions test/cases/include/asterisk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"include": ["*"]
}
3 changes: 3 additions & 0 deletions test/cases/include/asterisk/typestat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"mutators": ["./sampleMutator.js"]
}
7 changes: 7 additions & 0 deletions test/cases/include/directory/expected.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* foo */ /* foo */ (function() {
console.log("Hello, world!");

function ignoreChanges(): string {
return undefined;
}
})();
7 changes: 7 additions & 0 deletions test/cases/include/directory/original.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function() {
console.log("Hello, world!");

function ignoreChanges(): string {
return undefined;
}
})();
15 changes: 15 additions & 0 deletions test/cases/include/directory/sampleMutator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const prefix = "/* foo */ ";

module.exports.fileMutator = (request) => {
return request.sourceFile.getText().indexOf(prefix) === -1
? [
{
insertion: prefix,
range: {
begin: 0,
},
type: "text-insert",
},
]
: [];
};
3 changes: 3 additions & 0 deletions test/cases/include/directory/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"include": ["."]
}
3 changes: 3 additions & 0 deletions test/cases/include/directory/typestat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"mutators": ["./sampleMutator.js"]
}
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"esModuleInterop": true,
"lib": ["es2015"],
"lib": ["es2020"],
"module": "commonjs",
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
Expand All @@ -14,7 +14,7 @@
"resolveJsonModule": true,
"sourceMap": true,
"strict": true,
"target": "es2015"
"target": "es2020"
},
"exclude": ["test/**/*.ts"],
"include": ["src/**/*.ts"]
Expand Down
Loading

0 comments on commit fde4338

Please sign in to comment.