configuration: Load files via _include

This commit is contained in:
Tobe O 2020-05-04 11:59:33 -04:00
parent 0bd135c9cd
commit 8738154537
4 changed files with 53 additions and 33 deletions

View file

@ -1,3 +1,8 @@
# 2.2.0
* Allow including one configuration within another.
* Badly-formatted `.env` files will no longer issue a warning,
but instead throw an exception.
# 2.1.0 # 2.1.0
* Add `loadStandaloneConfiguration`. * Add `loadStandaloneConfiguration`.

View file

@ -21,8 +21,31 @@ Future<void> _loadYamlFile(Map map, File yamlFile, Map<String, String> env,
var out = {}; var out = {};
for (String key in config.keys) { var configMap = config as Map;
out[key] = _applyEnv(config[key], env ?? {}, warn);
// Check for _include
if (configMap.containsKey('_include')) {
var include = configMap.remove('_include');
var includeList = include is Iterable ? include.toList() : [include];
for (var inc in includeList) {
if (inc is! String) {
warn('Included item $inc is not a String.');
} else {
var p = yamlFile.fileSystem.path;
var includeFilePath = p.join(yamlFile.parent.path, inc);
var includeFile = yamlFile.fileSystem.file(includeFilePath);
if (!await includeFile.exists()) {
warn(
'Included configuration file "$includeFilePath" does not exist.');
} else {
await _loadYamlFile(out, includeFile, env, warn);
}
}
}
}
for (String key in configMap.keys) {
out[key] = _applyEnv(configMap[key], env ?? {}, warn);
} }
map.addAll(mergeMap( map.addAll(mergeMap(
@ -107,35 +130,21 @@ AngelConfigurer configuration(FileSystem fileSystem,
String overrideEnvironmentName, String overrideEnvironmentName,
String envPath}) { String envPath}) {
return (Angel app) async { return (Angel app) async {
var sourceDirectory = fileSystem.directory(directoryPath); var config = await loadStandaloneConfiguration(
var env = dotenv.env; fileSystem,
var envFile = sourceDirectory.childFile(envPath ?? '.env'); directoryPath: directoryPath,
overrideEnvironmentName: overrideEnvironmentName,
if (await envFile.exists()) { envPath: envPath,
try { onWarning: app.logger == null
dotenv.load(envFile.absolute.uri.toFilePath()); ? null
} catch (_) { : (msg) => app.logger?.warning('WARNING: $msg'),
app.logger?.warning( );
'WARNING: Found an environment configuration at ${envFile.absolute.path}, but it was invalidly formatted. Refusing to load it.'); app.configuration.addAll(mergeMap(
} [
} app.configuration,
config,
var environmentName = env['ANGEL_ENV'] ?? 'development'; ],
acceptNull: true,
if (overrideEnvironmentName != null) { ));
environmentName = overrideEnvironmentName;
}
void warn(String message) {
app.logger?.warning('WARNING: $message');
}
var defaultYaml = sourceDirectory.childFile('default.yaml');
await _loadYamlFile(app.configuration, defaultYaml, env, warn);
var configFilePath = '$environmentName.yaml';
var configFile = sourceDirectory.childFile(configFilePath);
await _loadYamlFile(app.configuration, configFile, env, warn);
}; };
} }

View file

@ -13,5 +13,7 @@ dependencies:
yaml: ^2.0.0 yaml: ^2.0.0
dev_dependencies: dev_dependencies:
io: ^0.3.2 io: ^0.3.2
logging: ^0.11.0
pedantic: ^1.0.0 pedantic: ^1.0.0
pretty_logging: ^1.0.0
test: ^1.0.0 test: ^1.0.0

View file

@ -4,11 +4,15 @@ import 'package:angel_framework/angel_framework.dart';
import 'package:angel_configuration/angel_configuration.dart'; import 'package:angel_configuration/angel_configuration.dart';
import 'package:file/local.dart'; import 'package:file/local.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:logging/logging.dart';
import 'package:pretty_logging/pretty_logging.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
Future<void> main() async { Future<void> main() async {
Logger.root.onRecord.listen(prettyLog);
// Note: Set ANGEL_ENV to 'development' // Note: Set ANGEL_ENV to 'development'
var app = Angel(); var app = Angel(logger: Logger('angel_configuration'));
var fileSystem = const LocalFileSystem(); var fileSystem = const LocalFileSystem();
await app.configure(configuration( await app.configure(configuration(