console-app/lib/Sources/ConfigSource.ts

70 lines
2.1 KiB
TypeScript
Raw Normal View History

2020-05-18 19:18:02 +02:00
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of console-app which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
/* eslint-disable no-await-in-loop */
2020-05-27 09:55:52 +02:00
import { dirname, join } from 'path';
2020-05-18 19:18:02 +02:00
import fs from 'fs-extra';
2020-05-27 09:55:52 +02:00
import { run_regex } from '@sapphirecode/utilities';
2020-05-27 17:39:32 +02:00
import hjson from 'hjson';
2020-06-09 21:03:10 +02:00
import { OptionValue, Option } from '../Option';
2020-06-09 13:13:27 +02:00
import { ErrorCallback } from '../ErrorCallback';
2020-05-18 19:18:02 +02:00
import { OptionSource } from './OptionSource';
export class ConfigSource extends OptionSource {
private _config_files: string[];
2020-05-28 18:54:34 +02:00
public constructor (config_files: string[], error_callback?:ErrorCallback) {
super (error_callback);
2020-05-18 19:18:02 +02:00
this._config_files = config_files;
}
2020-05-27 09:55:52 +02:00
private async read_json_file (file: string):
Promise<Record<string, unknown>> {
if (!await fs.pathExists (file))
return {};
const dir = dirname (file);
const contents = await fs.readFile (file, 'utf-8');
const obj: Record<string, unknown> = {};
const regex = /^#include (?<f>.+)/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];
}
2020-05-27 17:39:32 +02:00
const config = hjson.parse (contents);
2020-05-27 09:55:52 +02:00
for (const key of Object.keys (config))
obj[key] = config[key];
return obj;
}
2020-06-09 21:03:10 +02:00
public async parse (opt: Option, val: OptionValue): Promise<void> {
2020-05-18 19:18:02 +02:00
const data: Record<string, unknown> = {};
for (const f of this._config_files) {
2020-05-27 09:55:52 +02:00
try {
const json = await this.read_json_file (f);
for (const key of Object.keys (json))
data[key] = json[key];
}
catch (e) {
2020-05-28 18:54:34 +02:00
if (typeof this.error_callback !== 'undefined')
this.error_callback ('*', `config file: ${f}`, e);
2020-05-27 09:55:52 +02:00
continue;
2020-05-18 19:18:02 +02:00
}
}
const keys = Object.keys (data);
2020-06-09 21:03:10 +02:00
if (keys.includes (opt.name))
2020-06-15 11:56:33 +02:00
await val.assign_arg (opt, data[opt.name]);
2020-05-18 19:18:02 +02:00
}
}