mirror of
https://github.com/java-james/flutter_dotenv.git
synced 2025-07-15 05:53:52 +08:00
wip subs
This commit is contained in:
@ -12,7 +12,7 @@ HEAD
|
|||||||
----
|
----
|
||||||
|
|
||||||
- [deprecated] `Parser` methods will become private. [#3][]
|
- [deprecated] `Parser` methods will become private. [#3][]
|
||||||
- `#unquote` `#strip`, `#swallow`, `#parseOne`, `#surroundingQuote`
|
- `#unquote` `#strip`, `#swallow`, `#parseOne`, `#surroundingQuote`, `#interpolate`
|
||||||
- [deps] migrate to [test][]
|
- [deps] migrate to [test][]
|
||||||
- [deps] bump [logging][]
|
- [deps] bump [logging][]
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ bool get hasEnv => dotenv.isEveryDefined(_requiredEnvVars);
|
|||||||
|
|
||||||
### limitations
|
### limitations
|
||||||
|
|
||||||
Does **not** yet support escaping or substitution. Pull requests gleefully considered.
|
Does **not** yet support escaping. Pull requests gleefully considered.
|
||||||
|
|
||||||
###### prior art
|
###### prior art
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ class Parser {
|
|||||||
static final _comment = new RegExp(r'#.*$');
|
static final _comment = new RegExp(r'#.*$');
|
||||||
static final _keyword = 'export';
|
static final _keyword = 'export';
|
||||||
static final _surroundQuotes = new RegExp(r'''^(['"])(.*)\1$''');
|
static final _surroundQuotes = new RegExp(r'''^(['"])(.*)\1$''');
|
||||||
|
static final _bashVar = new RegExp(r'(?:\\)?(\$)([a-zA-Z_][\w]*)+');
|
||||||
|
|
||||||
const Parser();
|
const Parser();
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ class Parser {
|
|||||||
Map<String, String> parse(Iterable<String> lines) {
|
Map<String, String> parse(Iterable<String> lines) {
|
||||||
var out = {};
|
var out = {};
|
||||||
lines.forEach((line) {
|
lines.forEach((line) {
|
||||||
var kv = parseOne(line);
|
var kv = parseOne(line, env: out);
|
||||||
if (kv.isEmpty) return;
|
if (kv.isEmpty) return;
|
||||||
out.putIfAbsent(kv.keys.single, () => kv.values.single);
|
out.putIfAbsent(kv.keys.single, () => kv.values.single);
|
||||||
});
|
});
|
||||||
@ -26,7 +27,8 @@ class Parser {
|
|||||||
|
|
||||||
/// Parse a single line into a key-value pair.
|
/// Parse a single line into a key-value pair.
|
||||||
@Deprecated('Exposed for testing') // FIXME
|
@Deprecated('Exposed for testing') // FIXME
|
||||||
Map<String, String> parseOne(String line) {
|
Map<String, String> parseOne(String line,
|
||||||
|
{Map<String, String> env: const {}}) {
|
||||||
var stripped = strip(line);
|
var stripped = strip(line);
|
||||||
if (!_isValid(stripped)) return {};
|
if (!_isValid(stripped)) return {};
|
||||||
|
|
||||||
@ -42,11 +44,18 @@ class Parser {
|
|||||||
if (quotChar == "'") // skip substitution in single-quoted values
|
if (quotChar == "'") // skip substitution in single-quoted values
|
||||||
return {k: v};
|
return {k: v};
|
||||||
|
|
||||||
// TODO: variable substitution
|
return {k: interpolate(v, env)};
|
||||||
|
|
||||||
return {k: v};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Substitute $bash_vars in [val] with values from [env].
|
||||||
|
@Deprecated('Exposed for testing') // FIXME
|
||||||
|
String interpolate(String val, Map<String, String> env) => val
|
||||||
|
.replaceAllMapped(_bashVar, (m) {
|
||||||
|
var k = m.group(2);
|
||||||
|
if (!env.containsKey(k) || env[k] == null) return '';
|
||||||
|
return env[k];
|
||||||
|
});
|
||||||
|
|
||||||
/// If [val] is wrapped in single or double quotes, return the quote character.
|
/// If [val] is wrapped in single or double quotes, return the quote character.
|
||||||
/// Otherwise, return the empty string.
|
/// Otherwise, return the empty string.
|
||||||
@Deprecated('Exposed for testing') // FIXME
|
@Deprecated('Exposed for testing') // FIXME
|
||||||
|
@ -16,16 +16,36 @@ void main() {
|
|||||||
|
|
||||||
test('it skips empty lines', subj.parse_empty);
|
test('it skips empty lines', subj.parse_empty);
|
||||||
test('it ignores duplicate keys', subj.parse_dup);
|
test('it ignores duplicate keys', subj.parse_dup);
|
||||||
|
test('it substitutes known variables into other values', subj.parse_subs);
|
||||||
|
|
||||||
test('it detects unquoted values', subj.surroundingQuote_none);
|
test('it detects unquoted values', subj.surroundingQuote_none);
|
||||||
test('it detects double-quoted values', subj.surroundingQuote_double);
|
test('it detects double-quoted values', subj.surroundingQuote_double);
|
||||||
test('it detects single-quoted values', subj.surroundingQuote_single);
|
test('it detects single-quoted values', subj.surroundingQuote_single);
|
||||||
|
|
||||||
|
test('it performs variable substitution', subj.interpolate);
|
||||||
|
test('it skips undefined variables', subj.interpolate_missing);
|
||||||
|
test('it handles explicitly null values in env', subj.interpolate_missing2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const _psr = const Parser();
|
const _psr = const Parser();
|
||||||
|
|
||||||
class ParserTest {
|
class ParserTest {
|
||||||
|
void interpolate() {
|
||||||
|
var out = _psr.interpolate(r'a$foo$baz', {'foo': 'bar', 'baz': 'qux'});
|
||||||
|
expect(out, equals('abarqux'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void interpolate_missing() {
|
||||||
|
var out = _psr.interpolate(r'a$foo$baz', {});
|
||||||
|
expect(out, equals('a'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void interpolate_missing2() {
|
||||||
|
var out = _psr.interpolate(r'a$foo$baz', {'foo': null});
|
||||||
|
expect(out, equals('a'));
|
||||||
|
}
|
||||||
|
|
||||||
void surroundingQuote_none() {
|
void surroundingQuote_none() {
|
||||||
var out = _psr.surroundingQuote('no quotes here!');
|
var out = _psr.surroundingQuote('no quotes here!');
|
||||||
expect(out, isEmpty);
|
expect(out, isEmpty);
|
||||||
@ -93,4 +113,9 @@ class ParserTest {
|
|||||||
var out = _psr.parse(['foo=bar', 'foo=baz']);
|
var out = _psr.parse(['foo=bar', 'foo=baz']);
|
||||||
expect(out, equals({'foo': 'bar'}));
|
expect(out, equals({'foo': 'bar'}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse_subs() {
|
||||||
|
var out = _psr.parse(['foo=bar', r'baz=super$foo']);
|
||||||
|
expect(out, equals({'foo': 'bar', 'baz': 'superbar'}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user