Verified tests on Dart 1 + 2
This commit is contained in:
parent
7b1dd6d86c
commit
4e3e8de157
11 changed files with 30 additions and 196 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
# Created by .ignore support plugin (hsz.mobi)
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
### JetBrains template
|
### JetBrains template
|
||||||
.idea
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
@ -74,3 +75,5 @@ doc/api/
|
||||||
# Don't commit pubspec lock file
|
# Don't commit pubspec lock file
|
||||||
# (Library packages only! Remove pattern if developing an application package)
|
# (Library packages only! Remove pattern if developing an application package)
|
||||||
pubspec.lock
|
pubspec.lock
|
||||||
|
|
||||||
|
.dart_tool
|
|
@ -1 +1,4 @@
|
||||||
language: dart
|
language: dart
|
||||||
|
dart:
|
||||||
|
- dev
|
||||||
|
- stable
|
|
@ -1,3 +1,8 @@
|
||||||
|
# 2.0.0
|
||||||
|
* Removed the `Configuration` class.
|
||||||
|
* Removed the `ConfigurationTransformer` class.
|
||||||
|
* Use `Map` casting to prevent runtime cast errors.
|
||||||
|
|
||||||
# 1.0.5
|
# 1.0.5
|
||||||
* Now using `package:merge_map` to merge configurations. Resolves
|
* Now using `package:merge_map` to merge configurations. Resolves
|
||||||
[#5](https://github.com/angel-dart/configuration/issues/5).
|
[#5](https://github.com/angel-dart/configuration/issues/5).
|
||||||
|
|
25
README.md
25
README.md
|
@ -99,28 +99,3 @@ foo:
|
||||||
quux: goodbye
|
quux: goodbye
|
||||||
yellow: submarine
|
yellow: submarine
|
||||||
```
|
```
|
||||||
|
|
||||||
**In the Browser**
|
|
||||||
|
|
||||||
You can easily load configuration values within your client-side app,
|
|
||||||
and they will be automatically replaced by a Barback transformer.
|
|
||||||
|
|
||||||
In your `pubspec.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
transformers:
|
|
||||||
- angel_configuration
|
|
||||||
```
|
|
||||||
|
|
||||||
In your app:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
import 'package:angel_configuration/browser.dart';
|
|
||||||
|
|
||||||
main() async {
|
|
||||||
print(config("some_key.other.nested_key"));
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also provide a `dir` or `env` argument, corresponding to
|
|
||||||
the ones on the server-side.
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
analyzer:
|
analyzer:
|
||||||
strong-mode: true
|
strong-mode:
|
||||||
|
implicit-casts: true
|
9
example/main.dart
Normal file
9
example/main.dart
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:angel_configuration/angel_configuration.dart';
|
||||||
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
|
import 'package:file/local.dart';
|
||||||
|
|
||||||
|
main() async {
|
||||||
|
var app = new Angel();
|
||||||
|
var fs = const LocalFileSystem();
|
||||||
|
await app.configure(configuration(fs));
|
||||||
|
}
|
|
@ -6,35 +6,6 @@ import 'package:file/file.dart';
|
||||||
import 'package:merge_map/merge_map.dart';
|
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 _sym = new RegExp(r'Symbol\("([^"]+)"\)');
|
|
||||||
|
|
||||||
/// A proxy object that encapsulates a server's configuration.
|
|
||||||
@proxy
|
|
||||||
class Configuration {
|
|
||||||
/// The [Angel] instance that loaded this configuration.
|
|
||||||
final Angel app;
|
|
||||||
Configuration(this.app);
|
|
||||||
|
|
||||||
operator [](key) => app.configuration[key];
|
|
||||||
operator []=(key, value) => app.configuration[key] = value;
|
|
||||||
|
|
||||||
noSuchMethod(Invocation invocation) {
|
|
||||||
if (invocation.memberName != null) {
|
|
||||||
String name = _sym.firstMatch(invocation.memberName.toString()).group(1);
|
|
||||||
|
|
||||||
if (invocation.isMethod) {
|
|
||||||
return Function.apply(app.configuration[name],
|
|
||||||
invocation.positionalArguments, invocation.namedArguments);
|
|
||||||
} else if (invocation.isGetter) {
|
|
||||||
return app.configuration[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.noSuchMethod(invocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_loadYamlFile(Angel app, File yamlFile, Map<String, String> env) async {
|
_loadYamlFile(Angel app, File yamlFile, Map<String, String> env) async {
|
||||||
if (await yamlFile.exists()) {
|
if (await yamlFile.exists()) {
|
||||||
var config = loadYaml(await yamlFile.readAsString());
|
var config = loadYaml(await yamlFile.readAsString());
|
||||||
|
@ -89,8 +60,7 @@ _applyEnv(var v, Map<String, String> env, Angel app) {
|
||||||
/// load from a [overrideEnvironmentName].
|
/// load from a [overrideEnvironmentName].
|
||||||
///
|
///
|
||||||
/// You can also specify a custom [envPath] to load system configuration from.
|
/// You can also specify a custom [envPath] to load system configuration from.
|
||||||
AngelConfigurer configuration(
|
AngelConfigurer configuration(FileSystem fileSystem,
|
||||||
FileSystem fileSystem,
|
|
||||||
{String directoryPath: "./config",
|
{String directoryPath: "./config",
|
||||||
String overrideEnvironmentName,
|
String overrideEnvironmentName,
|
||||||
String envPath}) {
|
String envPath}) {
|
||||||
|
@ -121,6 +91,5 @@ AngelConfigurer configuration(
|
||||||
var configFile = sourceDirectory.childFile(configFilePath);
|
var configFile = sourceDirectory.childFile(configFilePath);
|
||||||
|
|
||||||
await _loadYamlFile(app, configFile, env);
|
await _loadYamlFile(app, configFile, env);
|
||||||
app.container.singleton(new Configuration(app));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:barback/barback.dart';
|
|
||||||
import 'package:analyzer/analyzer.dart';
|
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
|
||||||
import 'package:file/local.dart';
|
|
||||||
import 'angel_configuration.dart';
|
|
||||||
|
|
||||||
class ConfigurationTransformer extends Transformer {
|
|
||||||
final BarbackSettings _settings;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get allowedExtensions => ".dart";
|
|
||||||
|
|
||||||
ConfigurationTransformer.asPlugin(this._settings) {}
|
|
||||||
|
|
||||||
Future apply(Transform transform) async {
|
|
||||||
try {
|
|
||||||
var app = new Angel();
|
|
||||||
|
|
||||||
await app.configure(configuration(
|
|
||||||
const LocalFileSystem(),
|
|
||||||
directoryPath: _settings.configuration["dir"] ?? "./config",
|
|
||||||
overrideEnvironmentName: _settings.configuration["env"],
|
|
||||||
));
|
|
||||||
|
|
||||||
var text = await transform.primaryInput.readAsString();
|
|
||||||
var compilationUnit = parseCompilationUnit(text);
|
|
||||||
var visitor = new ConfigAstVisitor(app.properties);
|
|
||||||
visitor.visitCompilationUnit(compilationUnit);
|
|
||||||
|
|
||||||
await for (Map replaced in visitor.onReplaced) {
|
|
||||||
text = text.replaceAll(replaced["needle"], replaced["with"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
transform
|
|
||||||
.addOutput(new Asset.fromString(transform.primaryInput.id, text));
|
|
||||||
} catch (e) {
|
|
||||||
// Fail silently...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigAstVisitor extends GeneralizingAstVisitor {
|
|
||||||
Map _config;
|
|
||||||
var _onReplaced = new StreamController<Map>();
|
|
||||||
String _prefix = "";
|
|
||||||
Stream<Map> get onReplaced => _onReplaced.stream;
|
|
||||||
|
|
||||||
ConfigAstVisitor(this._config);
|
|
||||||
|
|
||||||
bool isConfigMethod(Expression function) =>
|
|
||||||
function is SimpleIdentifier && function.name == "${_prefix}config";
|
|
||||||
|
|
||||||
resolveItem(String key) {
|
|
||||||
var split = key.split(".");
|
|
||||||
var parent = _config;
|
|
||||||
|
|
||||||
for (int i = 0; i < split.length; i++) {
|
|
||||||
if (parent != null && parent is Map) parent = parent[split[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
visitCompilationUnit(CompilationUnit ctx) {
|
|
||||||
var result = super.visitCompilationUnit(ctx);
|
|
||||||
_onReplaced.close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
visitImportDirective(ImportDirective ctx) {
|
|
||||||
String uri = ctx.uri.stringValue;
|
|
||||||
|
|
||||||
if (uri == "package:angel_configuration/browser.dart") {
|
|
||||||
_onReplaced.add({"needle": ctx.toString(), "with": ""});
|
|
||||||
|
|
||||||
if (ctx.asKeyword != null) {
|
|
||||||
_prefix = ctx.prefix.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.visitImportDirective(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
visitExpression(Expression ctx) {
|
|
||||||
if (ctx is MethodInvocation) {
|
|
||||||
if (isConfigMethod(ctx.function)) {
|
|
||||||
StringLiteral key = ctx.argumentList.arguments[0];
|
|
||||||
var resolved = resolveItem(key.stringValue);
|
|
||||||
|
|
||||||
_onReplaced
|
|
||||||
.add({"needle": ctx.toString(), "with": JSON.encode(resolved)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.visitExpression(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,14 @@
|
||||||
name: angel_configuration
|
name: angel_configuration
|
||||||
description: Automatic YAML configuration loader for Angel.
|
description: Automatic YAML configuration loader for Angel.
|
||||||
version: 1.1.0
|
version: 2.0.0-rc.0
|
||||||
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:
|
environment:
|
||||||
sdk: ">=1.19.0"
|
sdk: ">=1.8.0 <3.0.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
analyzer: ">=0.28.1 <1.0.0"
|
|
||||||
angel_framework: ^1.1.0-alpha
|
angel_framework: ^1.1.0-alpha
|
||||||
barback: ^0.15.2
|
dotenv:
|
||||||
dotenv: ^0.1.0
|
git: https://github.com/thosakwe/dotenv.git
|
||||||
file: ^2.0.0
|
file: ^2.0.0
|
||||||
merge_map: ^1.0.0
|
merge_map: ^1.0.0
|
||||||
yaml: ^2.0.0
|
yaml: ^2.0.0
|
||||||
|
|
|
@ -2,7 +2,6 @@ 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:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'transformer.dart' as transformer;
|
|
||||||
|
|
||||||
main() async {
|
main() async {
|
||||||
// Note: Set ANGEL_ENV to 'development'
|
// Note: Set ANGEL_ENV to 'development'
|
||||||
|
@ -45,6 +44,4 @@ main() async {
|
||||||
directoryPath: './test/config', overrideEnvironmentName: 'override'));
|
directoryPath: './test/config', overrideEnvironmentName: 'override'));
|
||||||
expect(app.configuration['merge'], {'map': true, 'hello': 'goodbye'});
|
expect(app.configuration['merge'], {'map': true, 'hello': 'goodbye'});
|
||||||
});
|
});
|
||||||
|
|
||||||
group("transformer", transformer.main);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import 'package:analyzer/analyzer.dart';
|
|
||||||
import 'package:angel_configuration/transformer.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
main() {
|
|
||||||
test("simple replacement", () async {
|
|
||||||
var visitor = new ConfigAstVisitor({"foo": "bar"});
|
|
||||||
var source = '''
|
|
||||||
import 'package:angel_configuration/browser.dart';
|
|
||||||
|
|
||||||
main() async {
|
|
||||||
var foo = config('foo');
|
|
||||||
}
|
|
||||||
''';
|
|
||||||
|
|
||||||
var compilationUnit = parseCompilationUnit(source);
|
|
||||||
visitor.visitCompilationUnit(compilationUnit);
|
|
||||||
|
|
||||||
var replaced = await visitor.onReplaced.take(2).last;
|
|
||||||
|
|
||||||
expect(replaced["needle"], equals("config('foo')"));
|
|
||||||
expect(replaced["with"], equals('"bar"'));
|
|
||||||
|
|
||||||
print(source.replaceAll(replaced["needle"], replaced["with"]));
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in a new issue