forked from andoshin11/typescript-error-reporter-action
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.ts
122 lines (104 loc) · 3.27 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import Module from "module"
import * as path from "path"
import * as fs from "fs"
import { getInput, setFailed } from "@actions/core"
import { reporter } from "./reporter"
import type { CompilerOptions, Diagnostic, ParsedCommandLine } from "typescript"
type TS = typeof import("typescript")
async function main() {
try {
const project = getInput("project") || "tsconfig.json"
const projectPath = resolveProjectPath(path.resolve(process.cwd(), project))
if (projectPath == null) {
throw new Error(
`No valid typescript project was not found at: ${projectPath}`
)
}
typecheck(projectPath)
} catch (error) {
console.error(error)
setFailed(error as Error)
}
}
/**
* Attempts to resolve ts config file and returns either path to it or `null`.
*/
const resolveProjectPath = (projectPath: string) => {
try {
if (fs.statSync(projectPath).isFile()) {
return projectPath
} else {
const configPath = path.resolve(projectPath, "tsconfig.json")
return fs.statSync(configPath).isFile() ? configPath : null
}
} catch {
return null
}
}
const typecheck = (projectPath: string) => {
const ts = loadTS(projectPath)
const json = ts.readConfigFile(projectPath, ts.sys.readFile)
const config = ts.parseJsonConfigFileContent(
json.config,
ts.sys,
path.dirname(projectPath),
undefined,
path.basename(projectPath)
)
const errors = isIncrementalCompilation(config.options)
? performIncrementalCompilation(ts, projectPath)
: performCompilation(ts, config)
const errThreshold = Number(getInput("error_fail_threshold") || 0)
const logString = `Found ${errors} errors!`
console.log(logString)
if (errors > errThreshold) {
setFailed(logString)
}
}
const performIncrementalCompilation = (ts: TS, projectPath: string) => {
const report = reporter(ts)
const host = ts.createSolutionBuilderHost(ts.sys, undefined, report, report)
const builder = ts.createSolutionBuilder(host, [projectPath], {
noEmit: true,
})
return builder.build()
}
const performCompilation = (ts: TS, config: ParsedCommandLine) => {
const report = reporter(ts)
const host = ts.createCompilerHost(config.options)
const program = ts.createProgram({
rootNames: config.fileNames,
options: config.options,
projectReferences: config.projectReferences,
configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(config),
})
const configuration = program.getConfigFileParsingDiagnostics()
let all: Diagnostic[] = [...program.getSyntacticDiagnostics()]
if (all.length === 0) {
all = [
...program.getOptionsDiagnostics(),
...program.getGlobalDiagnostics(),
]
if (all.length == 0) {
all = [...program.getSemanticDiagnostics()]
}
}
const diagnostics = ts.sortAndDeduplicateDiagnostics(all)
diagnostics.forEach(report)
return all.length
}
const isIncrementalCompilation = (options: CompilerOptions) =>
options.incremental || options.composite
const loadTS = (projectPath: string): TS => {
try {
const require = Module.createRequire(projectPath)
const ts = require("typescript")
return ts
} catch (error) {
throw Object.assign(
new Error(`Failed to find project specific typescript at ${projectPath}`),
{ cause: error }
)
}
}
main()