diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..af6d2d4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +## 1.5.0 + +- added changelog +- config files: include other config files + +## 1.4.0 + +option to end the program when the user interrupts a prompt + +## 1.3.0 + +new source: config files + +## 1.2.0 + +preset option: +an array of strings to choose from when using one of the string types + +## 1.1.0 + +- readme file +- options to select which sources should be used +- array type + +## 1.0.0 + +initial version diff --git a/Jenkinsfile b/Jenkinsfile index 788a61b..92f12d7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { VERSION = VersionNumber([ versionNumberString: '${BUILDS_ALL_TIME}', - versionPrefix: '1.4.', + versionPrefix: '1.5.', worstResultForIncrement: 'SUCCESS' ]) } diff --git a/README.md b/README.md index 7adbd6f..7ce7256 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @sapphirecode/console-app -version: 1.4.x +version: 1.5.x read parameters from env, console args or interactively @@ -56,6 +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 +config files can import other config files with #include. example: + +```json +#include base.json +{ + "foo": "bar" +} +``` + 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 diff --git a/lib/Sources/ConfigSource.ts b/lib/Sources/ConfigSource.ts index f639bd5..2319653 100644 --- a/lib/Sources/ConfigSource.ts +++ b/lib/Sources/ConfigSource.ts @@ -6,7 +6,9 @@ */ /* eslint-disable no-await-in-loop */ +import { dirname, join } from 'path'; import fs from 'fs-extra'; +import { run_regex } from '@sapphirecode/utilities'; import { OptionProcess } from '../Option'; import { OptionSource } from './OptionSource'; @@ -18,26 +20,48 @@ export class ConfigSource extends OptionSource { this._config_files = config_files; } + private async read_json_file (file: string): + Promise> { + if (!await fs.pathExists (file)) + return {}; + const dir = dirname (file); + const contents = await fs.readFile (file, 'utf-8'); + const obj: Record = {}; + const regex = /^#include (?.+)/gmui; + const includes: string[] = []; + run_regex (regex, contents, (res: {groups:{f:string}}) => { + includes.push (join (dir, res.groups.f)); + }); + for (const inc of includes) { + const data = await this.read_json_file (inc); + for (const key of Object.keys (data)) + obj[key] = data[key]; + } + const config = JSON.parse (contents.replace (regex, '')); + for (const key of Object.keys (config)) + obj[key] = config[key]; + + return obj; + } + public async parse (options: OptionProcess[]): Promise { const data: Record = {}; for (const f of this._config_files) { - if (await fs.pathExists (f)) { - try { - const json = JSON.parse (await fs.readFile (f, 'utf-8')); - for (const key of Object.keys (json)) - data[key] = json[key]; - } - catch { - continue; - } + try { + const json = await this.read_json_file (f); + for (const key of Object.keys (json)) + data[key] = json[key]; + } + catch { + continue; } } const keys = Object.keys (data); - await Promise.all (options.map (async (opt) => { + for (const opt of options) { if (keys.includes (opt.name)) await this.assign_arg (opt, data[opt.name]); - })); + } } } diff --git a/package.json b/package.json index aca87df..0a7dabf 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ ], "dependencies": { "@sapphirecode/modelling": "^1.0.35", + "@sapphirecode/utilities": "^1.3.4", "enquirer": "^2.3.5", "fs-extra": "^9.0.0", "yargs": "^15.3.1" diff --git a/yarn.lock b/yarn.lock index a4e0fee..41a10da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -276,7 +276,7 @@ dependencies: "@sapphirecode/utilities" "^1.3.2" -"@sapphirecode/utilities@^1.3.2": +"@sapphirecode/utilities@^1.3.2", "@sapphirecode/utilities@^1.3.4": version "1.3.4" resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.3.4.tgz#fc9476d183d789dd32e6a5e3ec8517d633bc513b" integrity sha512-WZAinOnMB9oW0+xdXTxjDbVf0RGlCRxbA8ImBzqYNiwnnX1qWIGXnOHZ6xWtrlSOZCSRWJCAxRYw5ymTuyFpjA==