forked from bazel-contrib/rules_nodejs
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Validate ts project (bazel-contrib#1722)
* feat(typescript): validate that ts_project configuration matches the tsconfig settings
- Loading branch information
Showing
11 changed files
with
199 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
packages/typescript/src/internal/ts_project_options_validator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import * as ts from 'typescript'; | ||
|
||
const diagnosticsHost: ts.FormatDiagnosticsHost = { | ||
getCurrentDirectory: () => ts.sys.getCurrentDirectory(), | ||
getNewLine: () => ts.sys.newLine, | ||
// Print filenames including their relativeRoot, so they can be located on | ||
// disk | ||
getCanonicalFileName: (f: string) => f | ||
}; | ||
|
||
function main([tsconfigPath, output, target, attrsStr]: string[]): 0|1 { | ||
// The Bazel ts_project attributes were json-encoded | ||
// (on Windows the quotes seem to be quoted wrong, so replace backslash with quotes :shrug:) | ||
const attrs = JSON.parse(attrsStr.replace(/\\/g, '"')); | ||
|
||
// Parse your typescript settings from the tsconfig | ||
// This will understand the "extends" semantics. | ||
const {config, error} = ts.readConfigFile(tsconfigPath, ts.sys.readFile); | ||
if (error) throw new Error(tsconfigPath + ':' + ts.formatDiagnostic(error, diagnosticsHost)); | ||
const {errors, options} = | ||
ts.parseJsonConfigFileContent(config, ts.sys, require('path').dirname(tsconfigPath)); | ||
// We don't pass the srcs to this action, so it can't know if the program has the right sources. | ||
// Diagnostics look like | ||
// error TS18002: The 'files' list in config file 'tsconfig.json' is empty. | ||
// error TS18003: No inputs were found in config file 'tsconfig.json'. Specified 'include'... | ||
const fatalErrors = errors.filter(e => e.code !== 18002 && e.code != 18003); | ||
if (fatalErrors.length > 0) | ||
throw new Error(tsconfigPath + ':' + ts.formatDiagnostics(fatalErrors, diagnosticsHost)); | ||
|
||
const failures: string[] = []; | ||
const buildozerCmds: string[] = []; | ||
function check(option: string, attr?: string) { | ||
attr = attr || option; | ||
// treat compilerOptions undefined as false | ||
const optionVal = options[option] === undefined ? false : options[option]; | ||
if (optionVal !== attrs[attr]) { | ||
failures.push( | ||
`attribute ${attr}=${attrs[attr]} does not match compilerOptions.${option}=${optionVal}`); | ||
buildozerCmds.push(`set ${attr} ${optionVal ? 'True' : 'False'}`); | ||
} | ||
} | ||
|
||
check('declarationMap', 'declaration_map'); | ||
check('emitDeclarationOnly', 'emit_declaration_only'); | ||
check('sourceMap', 'source_map'); | ||
check('composite'); | ||
check('declaration'); | ||
check('incremental'); | ||
|
||
if (failures.length > 0) { | ||
console.error(`ERROR: ts_project rule ${ | ||
target} was configured with attributes that don't match the tsconfig`); | ||
failures.forEach(f => console.error(' - ' + f)); | ||
console.error('You can automatically fix this by running:'); | ||
console.error(` npx @bazel/buildozer ${buildozerCmds.map(c => `'${c}'`).join(' ')} ${target}`); | ||
console.error('Or to suppress this error, run:'); | ||
console.error(` npx @bazel/buildozer 'set validate False' ${target}`); | ||
return 1; | ||
} | ||
|
||
// We have to write an output so that Bazel needs to execute this action. | ||
// Make the output change whenever the attributes changed. | ||
require('fs').writeFileSync( | ||
output, ` | ||
// ${process.argv[1]} checked attributes for ${target} | ||
// composite: ${attrs.composite} | ||
// declaration: ${attrs.declaration} | ||
// declaration_map: ${attrs.declaration_map} | ||
// incremental: ${attrs.incremental} | ||
// source_map: ${attrs.source_map} | ||
// emit_declaration_only: ${attrs.emit_declaration_only} | ||
`, | ||
'utf-8'); | ||
return 0; | ||
} | ||
|
||
if (require.main === module) { | ||
try { | ||
process.exitCode = main(process.argv.slice(2)); | ||
} catch (e) { | ||
console.error(process.argv[1], e); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 1 addition & 4 deletions
5
packages/typescript/test/ts_project/empty_intermediate/tsconfig-a.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
{ | ||
"files": ["a.ts"], | ||
"compilerOptions": { | ||
"declaration": true | ||
} | ||
"files": ["a.d.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
load("@npm_bazel_typescript//:index.bzl", "ts_project") | ||
|
||
ts_project( | ||
composite = True, | ||
declaration = True, | ||
declaration_map = True, | ||
incremental = True, | ||
source_map = True, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const a: number = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"compilerOptions": { | ||
"incremental": true, | ||
"composite": true, | ||
"declarationMap": true, | ||
"declaration": true, | ||
"sourceMap": true, | ||
} | ||
} |