exit on interrupt

This commit is contained in:
Timo Hocker 2020-05-22 11:50:07 +02:00
parent 3766958b20
commit 62c378945a
5 changed files with 27 additions and 6 deletions

View File

@ -19,7 +19,7 @@ const { InteractiveOptions } = require ('./dist/lib/index.js');
{ name: 'num', type: 'number', env: 'TEST_NUM' }, { name: 'num', type: 'number', env: 'TEST_NUM' },
{ name: 'arr', type: 'array', env: 'TEST_ARR' }, { name: 'arr', type: 'array', env: 'TEST_ARR' },
{ name: 'fld', type: 'folder', env: 'TEST_FOLDER' } { name: 'fld', type: 'folder', env: 'TEST_FOLDER' }
]); ], { exit_on_interrupt: true });
await reader.parse (); await reader.parse ();
console.log (reader.serialize (true)); console.log (reader.serialize (true));
}) (); }) ();

2
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ pipeline {
VERSION = VersionNumber([ VERSION = VersionNumber([
versionNumberString: versionNumberString:
'${BUILDS_ALL_TIME}', '${BUILDS_ALL_TIME}',
versionPrefix: '1.3.', versionPrefix: '1.4.',
worstResultForIncrement: 'SUCCESS' worstResultForIncrement: 'SUCCESS'
]) ])
} }

View File

@ -1,6 +1,6 @@
# @sapphirecode/console-app # @sapphirecode/console-app
version: 1.3.x version: 1.4.x
read parameters from env, console args or interactively 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 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 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 ```js
const reader = new InteractiveOptions([], { const reader = new InteractiveOptions([], {
args: true, args: true,
env: true, env: true,
interactive: true, interactive: true,
configs: ['json files to search for options'] configs: ['json files to search for options'],
exit_on_interrupt: true
}); });
``` ```

View File

@ -31,6 +31,7 @@ interface SourceConfig {
args?: boolean; args?: boolean;
interactive?: boolean; interactive?: boolean;
configs?: string[]; configs?: string[];
exit_on_interrupt?: boolean;
} }
export class InteractiveOptions extends Persistent { export class InteractiveOptions extends Persistent {
@ -62,6 +63,11 @@ export class InteractiveOptions extends Persistent {
this.properties[option.name] = option.type_validation.persistent_type; 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 ( if (
typeof source_config.configs !== 'undefined' typeof source_config.configs !== 'undefined'
&& Array.isArray (source_config.configs) && Array.isArray (source_config.configs)
@ -72,7 +78,7 @@ export class InteractiveOptions extends Persistent {
if (source_config.args !== false) if (source_config.args !== false)
this.sources.push (new ArgSource); this.sources.push (new ArgSource);
if (source_config.interactive !== false) if (source_config.interactive !== false)
this.sources.push (new InteractiveSource); this.sources.push (new InteractiveSource (exit_on_interrupt));
} }
public async parse (): Promise<Record<string, unknown>> { public async parse (): Promise<Record<string, unknown>> {

View File

@ -12,6 +12,13 @@ import { OptionProcess, Option } from '../Option';
import { OptionSource } from './OptionSource'; import { OptionSource } from './OptionSource';
export class InteractiveSource extends 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 { private get_message (opt: Option): string {
return typeof opt.message === 'undefined' return typeof opt.message === 'undefined'
? `input ${opt.name}` ? `input ${opt.name}`
@ -72,7 +79,12 @@ export class InteractiveSource extends OptionSource {
for (const opt of options) { for (const opt of options) {
while (!opt.filled) { while (!opt.filled) {
// eslint-disable-next-line no-await-in-loop // 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) if (!opt.filled)
console.log ('input was invalid'); console.log ('input was invalid');
} }