From 62c378945aac9f3f44f756e05f50a4b7a68bd8dc Mon Sep 17 00:00:00 2001 From: Timo Hocker Date: Fri, 22 May 2020 11:50:07 +0200 Subject: [PATCH] exit on interrupt --- AppTest.js | 2 +- Jenkinsfile | 2 +- README.md | 7 +++++-- lib/InteractiveOptions.ts | 8 +++++++- lib/Sources/InteractiveSource.ts | 14 +++++++++++++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/AppTest.js b/AppTest.js index 63c4bdf..18c29d7 100644 --- a/AppTest.js +++ b/AppTest.js @@ -19,7 +19,7 @@ const { InteractiveOptions } = require ('./dist/lib/index.js'); { name: 'num', type: 'number', env: 'TEST_NUM' }, { name: 'arr', type: 'array', env: 'TEST_ARR' }, { name: 'fld', type: 'folder', env: 'TEST_FOLDER' } - ]); + ], { exit_on_interrupt: true }); await reader.parse (); console.log (reader.serialize (true)); }) (); diff --git a/Jenkinsfile b/Jenkinsfile index e7ce23a..788a61b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { VERSION = VersionNumber([ versionNumberString: '${BUILDS_ALL_TIME}', - versionPrefix: '1.3.', + versionPrefix: '1.4.', worstResultForIncrement: 'SUCCESS' ]) } diff --git a/README.md b/README.md index 73cf658..7adbd6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @sapphirecode/console-app -version: 1.3.x +version: 1.4.x read parameters from env, console args or interactively @@ -56,12 +56,15 @@ the console reader automatically adds the options --help (-h) and --quiet (-q) the reader can also be constructed with additional options that specify which sources should be used. It reads from all, except config files by default +the option exit_on_interrupt determines whether an error should be thrown or the process should exit when the user presses control + c in an interactive prompt. + ```js const reader = new InteractiveOptions([], { args: true, env: true, interactive: true, - configs: ['json files to search for options'] + configs: ['json files to search for options'], + exit_on_interrupt: true }); ``` diff --git a/lib/InteractiveOptions.ts b/lib/InteractiveOptions.ts index 762a95d..64cb584 100644 --- a/lib/InteractiveOptions.ts +++ b/lib/InteractiveOptions.ts @@ -31,6 +31,7 @@ interface SourceConfig { args?: boolean; interactive?: boolean; configs?: string[]; + exit_on_interrupt?: boolean; } export class InteractiveOptions extends Persistent { @@ -62,6 +63,11 @@ export class InteractiveOptions extends Persistent { this.properties[option.name] = option.type_validation.persistent_type; } + const exit_on_interrupt + = typeof source_config.exit_on_interrupt === 'boolean' + ? source_config.exit_on_interrupt + : false; + if ( typeof source_config.configs !== 'undefined' && Array.isArray (source_config.configs) @@ -72,7 +78,7 @@ export class InteractiveOptions extends Persistent { if (source_config.args !== false) this.sources.push (new ArgSource); if (source_config.interactive !== false) - this.sources.push (new InteractiveSource); + this.sources.push (new InteractiveSource (exit_on_interrupt)); } public async parse (): Promise> { diff --git a/lib/Sources/InteractiveSource.ts b/lib/Sources/InteractiveSource.ts index e27312e..6b46480 100644 --- a/lib/Sources/InteractiveSource.ts +++ b/lib/Sources/InteractiveSource.ts @@ -12,6 +12,13 @@ import { OptionProcess, Option } from '../Option'; import { OptionSource } from './OptionSource'; export class InteractiveSource extends OptionSource { + private _exit_on_interrupt: boolean; + + public constructor (exit_on_interrupt: boolean) { + super (); + this._exit_on_interrupt = exit_on_interrupt; + } + private get_message (opt: Option): string { return typeof opt.message === 'undefined' ? `input ${opt.name}` @@ -72,7 +79,12 @@ export class InteractiveSource extends OptionSource { for (const opt of options) { while (!opt.filled) { // eslint-disable-next-line no-await-in-loop - await this.prompt (opt); + await this.prompt (opt) + .catch ((e) => { + if (this._exit_on_interrupt) + process.exit (0); + throw e; + }); if (!opt.filled) console.log ('input was invalid'); }