-
-
Notifications
You must be signed in to change notification settings - Fork 186
Fix tsconfig overridden by defaults #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,11 @@ export class CLIError extends Error { | |
|
|
||
| } | ||
|
|
||
| const optionDeclarations: { [key: string]: yargs.Options } = { | ||
| export interface YargsOptions { | ||
| [key: string]: yargs.Options; | ||
| } | ||
|
|
||
| export const optionDeclarations: YargsOptions = { | ||
| luaLibImport: { | ||
| choices: ["inline", "require", "none"], | ||
| default: "inline", | ||
|
|
@@ -38,11 +42,33 @@ const optionDeclarations: { [key: string]: yargs.Options } = { | |
| }, | ||
| }; | ||
|
|
||
| /** | ||
| * Removes defaults from the arguments. | ||
| * Returns a tuple where [0] is a copy of the options without defaults and [1] is the extracted defaults. | ||
| */ | ||
| function getYargOptionsWithoutDefaults(options: YargsOptions): [YargsOptions, yargs.Arguments] { | ||
| // options is a deep object, Object.assign or {...options} still keeps the referece | ||
| const copy = JSON.parse(JSON.stringify(options)); | ||
|
|
||
| const optionDefaults: yargs.Arguments = {_: null, $0: null}; | ||
| for (const optionName in copy) { | ||
| const section = copy[optionName]; | ||
|
|
||
| optionDefaults[optionName] = section.default; | ||
| delete section.default; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really like deleting, shouldn't the result be an empty object anyway?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if I understand your question. What result should be an empty object anyway?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nevermind I missread, looks a bit strange but okay. |
||
| } | ||
|
|
||
| return [copy, optionDefaults]; | ||
| } | ||
|
|
||
| /** | ||
| * Pares the supplied arguments. | ||
| * The result will include arguments supplied via CLI and arguments from tsconfig. | ||
| */ | ||
| export function parseCommandLine(args: string[]): ParsedCommandLine { | ||
| // Get a copy of the options without defaults to prevent defaults overriding project config | ||
| const [tstlOptions, tstlDefaults] = getYargOptionsWithoutDefaults(optionDeclarations); | ||
|
|
||
| const parsedArgs = yargs | ||
| .usage("Syntax: tstl [options] [files...]\n\n" + | ||
| "In addition to the options listed below you can also pass options" + | ||
|
|
@@ -51,7 +77,7 @@ export function parseCommandLine(args: string[]): ParsedCommandLine { | |
| .example("tstl path/to/file.ts [...]", "Compile files") | ||
| .example("tstl -p path/to/tsconfig.json", "Compile project") | ||
| .wrap(yargs.terminalWidth()) | ||
| .options(optionDeclarations) | ||
| .options(tstlOptions) | ||
| .fail((msg, err) => { | ||
| throw new CLIError(msg); | ||
| }) | ||
|
|
@@ -82,6 +108,9 @@ export function parseCommandLine(args: string[]): ParsedCommandLine { | |
| // Add TSTL options from tsconfig | ||
| addTSTLOptions(commandLine); | ||
|
|
||
| // Add TSTL defaults last | ||
| addTSTLOptions(commandLine, tstlDefaults); | ||
|
|
||
| // Run diagnostics again to check for errors in tsconfig | ||
| runDiagnostics(commandLine); | ||
|
|
||
|
|
@@ -158,13 +187,15 @@ export function findConfigFile(commandLine: ts.ParsedCommandLine): void { | |
| if (!commandLine.options.project) { | ||
| throw new CLIError(`error no base path provided, could not find config.`); | ||
| } | ||
| let configPath; | ||
| /* istanbul ignore else: Testing else part is not really possible via automated tests */ | ||
| if (path.isAbsolute(commandLine.options.project)) { | ||
| configPath = commandLine.options.project; | ||
| } else { | ||
| let configPath = commandLine.options.project; | ||
| // If the project path is wrapped in double quotes, remove them | ||
| if (/^".*"$/.test(configPath)) { | ||
| configPath = configPath.substring(1, configPath.length - 1); | ||
| } | ||
| /* istanbul ignore if: Testing else part is not really possible via automated tests */ | ||
| if (!path.isAbsolute(configPath)) { | ||
| // TODO check if commandLine.options.project can even contain non absolute paths | ||
| configPath = path.join(process.cwd(), commandLine.options.project); | ||
| configPath = path.join(process.cwd(), configPath); | ||
| } | ||
| if (fs.statSync(configPath).isDirectory()) { | ||
| configPath = path.join(configPath, "tsconfig.json"); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { Expect, Test, TestCase, Teardown } from "alsatian"; | ||
| import * as path from 'path'; | ||
| import * as fs from 'fs'; | ||
| import * as ts from "typescript"; | ||
|
|
||
| import { CompilerOptions, findConfigFile, parseCommandLine, ParsedCommandLine, optionDeclarations } from "../../../../../src/CommandLineParser"; | ||
| import { LuaLibImportKind } from "../../../../../src/Transpiler"; | ||
|
|
||
| export class MixedConfigurationTests { | ||
|
|
||
| @Test("tsconfig.json mixed with cmd line args") | ||
| public tsconfigMixedWithCmdLineArgs() { | ||
| const rootPath = __dirname; | ||
| const tsConfigPath = path.join(rootPath, "project-tsconfig.json"); | ||
| const expectedTsConfig = ts.parseJsonConfigFileContent( | ||
| ts.parseConfigFileTextToJson(tsConfigPath, fs.readFileSync(tsConfigPath).toString()).config, | ||
| ts.sys, | ||
| path.dirname(tsConfigPath) | ||
| ); | ||
|
|
||
| const parsedArgs = parseCommandLine([ | ||
| "-p", | ||
| `"${tsConfigPath}"`, | ||
| "--luaLibImport", | ||
| LuaLibImportKind.Inline, | ||
| `${path.join(rootPath, 'test.ts')}`, | ||
| ]); | ||
|
|
||
| Expect(parsedArgs.options).toEqual(<CompilerOptions>{ | ||
| ...expectedTsConfig.options, | ||
| // Overridden by cmd args (set to "none" in project-tsconfig.json) | ||
| luaLibImport: LuaLibImportKind.Inline, | ||
| // Only set in tsconfig, TSTL default is "JIT" | ||
| luaTarget: "5.1", | ||
| // Only present in TSTL dfaults | ||
| noHeader: optionDeclarations["noHeader"].default, | ||
| project: tsConfigPath | ||
| }); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "outDir": "./dist/foo/bar", | ||
| "rootDir": "./src/foo/bar" | ||
| }, | ||
| "luaTarget": "5.1", | ||
| "luaLibImport": "none" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these 2 values for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The typing of the object requires those as its yargs.Arguments (non-optional props). I didn't want to use
as anylater when they are returned as yargs.Arguments, although in this context it's probably fine.yargs.Arguments type: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/yargs/index.d.ts#L227
I suppose one option is to use Partial<> and then force it to yargs.Arguments to retain at least some type info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks a bit strange but okay, I'm fine with it for now.