From cc141ff2f6d5f06008793662b05452c6c0531d9a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 14 Mar 2018 14:36:03 -0700 Subject: [PATCH] Invert boolean options that are on by default on CLI. Fixes #671 --- src/Language/Swift.ts | 3 ++- src/RendererOptions.ts | 40 +++++++++++++++++++++++++++++++++++----- src/TargetLanguage.ts | 4 ++++ src/cli.ts | 4 ++-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/Language/Swift.ts b/src/Language/Swift.ts index 6cf321fe..659f7318 100644 --- a/src/Language/Swift.ts +++ b/src/Language/Swift.ts @@ -49,7 +49,8 @@ export default class SwiftTargetLanguage extends TargetLanguage { private readonly _convenienceInitializers = new BooleanOption( "initializers", "Convenience initializers", - true + true, + "No convenience initializers" ); private readonly _alamofireHandlers = new BooleanOption("alamofire", "Alamofire extensions", false); diff --git a/src/RendererOptions.ts b/src/RendererOptions.ts index 5b5da5f4..124296ef 100644 --- a/src/RendererOptions.ts +++ b/src/RendererOptions.ts @@ -1,6 +1,6 @@ "use strict"; -import { panic } from "./Support"; +import { panic, assert } from "./Support"; export interface OptionDefinition { name: string; @@ -22,6 +22,10 @@ export abstract class UntypedOption { definition.renderer = true; this.definition = definition; } + + get cliDefinition(): OptionDefinition { + return this.definition; + } } export abstract class Option extends UntypedOption { @@ -35,14 +39,40 @@ export abstract class Option extends UntypedOption { } export class BooleanOption extends Option { - constructor(name: string, description: string, defaultValue: boolean) { - const definition = { + constructor(name: string, description: string, defaultValue: boolean, private readonly _cliDescription?: string) { + super({ name, type: Boolean, description, defaultValue - }; - super(definition); + }); + if (defaultValue === true) { + assert(_cliDescription !== undefined, "We need a CLI description for boolean options that are true by default"); + } + } + + get cliDefinition(): OptionDefinition { + const definition = Object.assign({}, this.definition); + if (this._cliDescription !== undefined) { + definition.description = this._cliDescription; + } + if (this.definition.defaultValue === true) { + definition.name = `no-${definition.name}`; + } + definition.defaultValue = false; + return definition; + } + + getValue(values: { [name: string]: any }): boolean { + const definition = this.cliDefinition; + const value = values[definition.name]; + if (value === undefined) { + return this.definition.defaultValue; + } + if (this.definition.defaultValue === true) { + return !value; + } + return value; } } diff --git a/src/TargetLanguage.ts b/src/TargetLanguage.ts index 84c6d10a..96e81d9a 100644 --- a/src/TargetLanguage.ts +++ b/src/TargetLanguage.ts @@ -19,6 +19,10 @@ export abstract class TargetLanguage { return this.getOptions().map(o => o.definition); } + get cliOptionDefinitions(): OptionDefinition[] { + return this.getOptions().map(o => o.cliDefinition); + } + protected abstract get rendererClass(): new ( graph: TypeGraph, leadingComments: string[] | undefined, diff --git a/src/cli.ts b/src/cli.ts index e7fad01d..41bee7eb 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -450,7 +450,7 @@ const sectionsAfterRenderers: UsageSection[] = [ ]; function getOptionDefinitions(opts: CLIOptions): OptionDefinition[] { - return getTargetLanguage(opts.lang).optionDefinitions; + return getTargetLanguage(opts.lang).cliOptionDefinitions; } function parseArgv(argv: string[]): CLIOptions { @@ -501,7 +501,7 @@ function usage() { const rendererSections: UsageSection[] = []; _.forEach(targetLanguages.all, language => { - const definitions = language.optionDefinitions; + const definitions = language.cliOptionDefinitions; if (definitions.length === 0) return; rendererSections.push({