merge map

This commit is contained in:
thosakwe 2017-08-15 20:29:13 -04:00
parent 920fe93c92
commit a116cb4515
8 changed files with 75 additions and 15 deletions

4
CHANGELOG.md Normal file
View file

@ -0,0 +1,4 @@
# 1.0.5
* Now using `package:merge_map` to merge configurations. Resolves
[#5](https://github.com/angel-dart/configuration/issues/5).
* You can now specify a custom `envPath`.

View file

@ -73,6 +73,30 @@ main() async {
The former will allow you to search in a directory other than `config`, and the latter lets you The former will allow you to search in a directory other than `config`, and the latter lets you
override `$ANGEL_ENV` by specifying a specific configuration name to look for (i.e. `production`). override `$ANGEL_ENV` by specifying a specific configuration name to look for (i.e. `production`).
This package uses
[`package:merge_map`](https://github.com/thosakwe/merge_map)
internally, so existing configurations can be deeply merged.
Example:
```yaml
# default.yaml
foo:
bar: baz
quux: hello
# production.yaml
foo:
quux: goodbye
yellow: submarine
# Propagates to:
foo:
bar: baz
quux: goodbye
yellow: submarine
```
**In the Browser** **In the Browser**
You can easily load configuration values within your client-side app, You can easily load configuration values within your client-side app,

2
analysis_options.yaml Normal file
View file

@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View file

@ -3,6 +3,7 @@ library angel_configuration;
import 'dart:io'; import 'dart:io';
import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/angel_framework.dart';
import 'package:dotenv/dotenv.dart' as dotenv; import 'package:dotenv/dotenv.dart' as dotenv;
import 'package:merge_map/merge_map.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
final RegExp _equ = new RegExp(r'=$'); final RegExp _equ = new RegExp(r'=$');
@ -42,9 +43,20 @@ _loadYamlFile(Angel app, File yamlFile, Map<String, String> env) async {
'WARNING: The configuration at "${yamlFile.absolute.path}" is not a Map. Refusing to load it.'); 'WARNING: The configuration at "${yamlFile.absolute.path}" is not a Map. Refusing to load it.');
return; return;
} }
Map<String, dynamic> out = {};
for (String key in config.keys) { for (String key in config.keys) {
app.properties[key] = _applyEnv(config[key], env ?? {}); out[key] = _applyEnv(config[key], env ?? {});
} }
app.properties.addAll(mergeMap(
[
app.properties,
out,
],
acceptNull: true,
));
} }
} }
@ -71,12 +83,20 @@ _applyEnv(var v, Map<String, String> env) {
} }
/// Dynamically loads application configuration from configuration files. /// Dynamically loads application configuration from configuration files.
///
/// You can modify which [directoryPath] to search in, or explicitly
/// load from a [overrideEnvironmentName].
///
/// You can also specify a custom [envPath] to load system configuration from.
AngelConfigurer loadConfigurationFile( AngelConfigurer loadConfigurationFile(
{String directoryPath: "./config", String overrideEnvironmentName}) { {String directoryPath: "./config",
String overrideEnvironmentName,
String envPath}) {
return (Angel app) async { return (Angel app) async {
Directory sourceDirectory = new Directory(directoryPath); Directory sourceDirectory = new Directory(directoryPath);
var env = dotenv.env; var env = dotenv.env;
var envFile = new File.fromUri(sourceDirectory.uri.resolve('.env')); var envFile =
new File.fromUri(sourceDirectory.uri.resolve(envPath ?? '.env'));
if (await envFile.exists()) { if (await envFile.exists()) {
try { try {

View file

@ -1,14 +1,16 @@
name: angel_configuration name: angel_configuration
description: Automatic YAML configuration loader for Angel. description: Automatic YAML configuration loader for Angel.
version: 1.0.4 version: 1.0.5
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_configuration homepage: https://github.com/angel-dart/angel_configuration
environment:
sdk: ">=1.19.0"
dependencies: dependencies:
analyzer: ">=0.28.1 <1.0.0" analyzer: ">=0.28.1 <1.0.0"
angel_framework: ">=1.0.0-dev < 2.0.0" angel_framework: ^1.0.0-dev
angel_route: ">=1.0.0-dev < 2.0.0" barback: ^0.15.2
barback: ">=0.15.2 < 0.16.0" dotenv: ^0.1.0
dotenv: ">=0.1.3 <0.2.0" merge_map: ^1.0.0
yaml: ">= 2.1.8 < 2.2.0" yaml: ^2.0.0
dev_dependencies: dev_dependencies:
test: ">= 0.12.13 < 0.13.0" test: ^0.12.0

View file

@ -6,8 +6,7 @@ import 'transformer.dart' as transformer;
main() async { main() async {
// Note: Set ANGEL_ENV to 'development' // Note: Set ANGEL_ENV to 'development'
var app = new Angel(); var app = new Angel();
await app.configure( await app.configure(loadConfigurationFile(directoryPath: './test/config'));
loadConfigurationFile(directoryPath: './test/config'));
test('can load based on ANGEL_ENV', () async { test('can load based on ANGEL_ENV', () async {
expect(app.properties['hello'], equals('world')); expect(app.properties['hello'], equals('world'));
@ -35,7 +34,11 @@ main() async {
expect(app.properties['foo']['version'], equals('baz')); expect(app.properties['foo']['version'], equals('baz'));
}); });
test('merges configuration', () async {
await app.configure(loadConfigurationFile(
directoryPath: './test/config', overrideEnvironmentName: 'override'));
expect(app.properties['merge'], {'map': true, 'hello': 'goodbye'});
});
group("transformer", transformer.main); group("transformer", transformer.main);
} }

View file

@ -3,3 +3,6 @@ artist: $JUSTIN
angel: angel:
framework: $ANGEL_FRAMEWORK framework: $ANGEL_FRAMEWORK
must_be_null: $NONEXISTENT_KEY_FOO_BAR_BAZ_QUUX must_be_null: $NONEXISTENT_KEY_FOO_BAR_BAZ_QUUX
merge:
map: true
hello: world

View file

@ -1,3 +1,5 @@
hello: goodbye hello: goodbye
foo: foo:
version: baz version: baz
merge:
hello: goodbye