mirror of
https://github.com/mbierlee/mirage-config.git
synced 2024-11-15 04:44:01 +01:00
Support semicolons as comments in keyvalue config
This commit is contained in:
parent
5a34831b03
commit
42e93e64d0
|
@ -12,12 +12,15 @@
|
||||||
module mirage.java;
|
module mirage.java;
|
||||||
|
|
||||||
import mirage.config : ConfigDictionary;
|
import mirage.config : ConfigDictionary;
|
||||||
import mirage.keyvalue : KeyValueConfigFactory;
|
import mirage.keyvalue : KeyValueConfigFactory, SupportHashtagComments, SupportSemicolonComments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates configuration files from Java properties.
|
* Creates configuration files from Java properties.
|
||||||
*/
|
*/
|
||||||
class JavaPropertiesFactory : KeyValueConfigFactory {
|
class JavaPropertiesFactory : KeyValueConfigFactory!(
|
||||||
|
SupportHashtagComments.yes,
|
||||||
|
SupportSemicolonComments.no
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,12 +17,19 @@ import std.string : lineSplitter, strip, startsWith, split, indexOf;
|
||||||
import std.array : array;
|
import std.array : array;
|
||||||
import std.exception : enforce;
|
import std.exception : enforce;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
|
import std.typecons : Flag;
|
||||||
|
|
||||||
|
alias SupportHashtagComments = Flag!"supportHashtagComment";
|
||||||
|
alias SupportSemicolonComments = Flag!"supportSemicolonComments";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic reusable key/value config factory that can be configured to parse
|
* A generic reusable key/value config factory that can be configured to parse
|
||||||
* the specifics of certain key/value formats.
|
* the specifics of certain key/value formats.
|
||||||
*/
|
*/
|
||||||
class KeyValueConfigFactory : ConfigFactory {
|
class KeyValueConfigFactory(
|
||||||
|
SupportHashtagComments supportHashtagComments = SupportHashtagComments.no,
|
||||||
|
SupportSemicolonComments supportSemicolonComments = SupportSemicolonComments.no
|
||||||
|
) : ConfigFactory {
|
||||||
/**
|
/**
|
||||||
* Parse a configuration file following the configured key/value conventions.
|
* Parse a configuration file following the configured key/value conventions.
|
||||||
*
|
*
|
||||||
|
@ -35,15 +42,26 @@ class KeyValueConfigFactory : ConfigFactory {
|
||||||
auto lines = contents.lineSplitter().array;
|
auto lines = contents.lineSplitter().array;
|
||||||
auto properties = new ConfigDictionary();
|
auto properties = new ConfigDictionary();
|
||||||
foreach (size_t index, string line; lines) {
|
foreach (size_t index, string line; lines) {
|
||||||
auto normalizedLine = line.strip;
|
auto normalizedLine = line;
|
||||||
if (normalizedLine.length == 0 || normalizedLine.startsWith('#')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (supportHashtagComments) {
|
||||||
auto commentPosition = normalizedLine.indexOf('#');
|
auto commentPosition = normalizedLine.indexOf('#');
|
||||||
if (commentPosition >= 0) {
|
if (commentPosition >= 0) {
|
||||||
normalizedLine = normalizedLine[0 .. commentPosition];
|
normalizedLine = normalizedLine[0 .. commentPosition];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportSemicolonComments) {
|
||||||
|
auto commentPosition = normalizedLine.indexOf(';');
|
||||||
|
if (commentPosition >= 0) {
|
||||||
|
normalizedLine = normalizedLine[0 .. commentPosition];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizedLine = normalizedLine.strip;
|
||||||
|
if (normalizedLine.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto parts = normalizedLine.split('=');
|
auto parts = normalizedLine.split('=');
|
||||||
enforce!ConfigCreationException(parts.length <= 2, "Line has too many equals signs and cannot be parsed (L" ~ index
|
enforce!ConfigCreationException(parts.length <= 2, "Line has too many equals signs and cannot be parsed (L" ~ index
|
||||||
|
@ -60,10 +78,12 @@ version (unittest) {
|
||||||
import std.exception : assertThrown;
|
import std.exception : assertThrown;
|
||||||
import std.process : environment;
|
import std.process : environment;
|
||||||
|
|
||||||
|
class TestKeyValueConfigFactory : KeyValueConfigFactory!() {
|
||||||
|
}
|
||||||
|
|
||||||
@("Parse standard key/value config")
|
@("Parse standard key/value config")
|
||||||
unittest {
|
unittest {
|
||||||
auto config = new KeyValueConfigFactory().parseConfig("
|
auto config = new TestKeyValueConfigFactory().parseConfig("
|
||||||
# I have a comment
|
|
||||||
bla=one
|
bla=one
|
||||||
di.bla=two
|
di.bla=two
|
||||||
");
|
");
|
||||||
|
@ -72,29 +92,43 @@ version (unittest) {
|
||||||
assert(config.get("di.bla") == "two");
|
assert(config.get("di.bla") == "two");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@("Parse and ignore comments")
|
||||||
|
unittest {
|
||||||
|
auto config = new KeyValueConfigFactory!(SupportHashtagComments.yes,
|
||||||
|
SupportSemicolonComments.yes
|
||||||
|
)().parseConfig("
|
||||||
|
# this is a comment
|
||||||
|
; this is another comment
|
||||||
|
iamset=true
|
||||||
|
");
|
||||||
|
|
||||||
|
assert(config.get!bool("iamset"));
|
||||||
|
}
|
||||||
|
|
||||||
@("Fail to parse when there are too many equals signs")
|
@("Fail to parse when there are too many equals signs")
|
||||||
unittest {
|
unittest {
|
||||||
assertThrown!ConfigCreationException(new KeyValueConfigFactory()
|
assertThrown!ConfigCreationException(new TestKeyValueConfigFactory()
|
||||||
.parseConfig("one=two=three"));
|
.parseConfig("one=two=three"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@("Fail to parse when value assignment is missing")
|
@("Fail to parse when value assignment is missing")
|
||||||
unittest {
|
unittest {
|
||||||
assertThrown!ConfigCreationException(new KeyValueConfigFactory().parseConfig(
|
assertThrown!ConfigCreationException(new TestKeyValueConfigFactory()
|
||||||
|
.parseConfig(
|
||||||
"answertolife"));
|
"answertolife"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@("Substitute env vars")
|
@("Substitute env vars")
|
||||||
unittest {
|
unittest {
|
||||||
environment["MIRAGE_TEST_ENVY"] = "Much";
|
environment["MIRAGE_TEST_ENVY"] = "Much";
|
||||||
auto config = new KeyValueConfigFactory().parseConfig("envy=$MIRAGE_TEST_ENVY");
|
auto config = new TestKeyValueConfigFactory().parseConfig("envy=$MIRAGE_TEST_ENVY");
|
||||||
|
|
||||||
assert(config.get("envy") == "Much");
|
assert(config.get("envy") == "Much");
|
||||||
}
|
}
|
||||||
|
|
||||||
@("Use value from other key")
|
@("Use value from other key")
|
||||||
unittest {
|
unittest {
|
||||||
auto config = new KeyValueConfigFactory().parseConfig("
|
auto config = new TestKeyValueConfigFactory().parseConfig("
|
||||||
one=money
|
one=money
|
||||||
two=${one}
|
two=${one}
|
||||||
");
|
");
|
||||||
|
@ -104,7 +138,7 @@ version (unittest) {
|
||||||
|
|
||||||
@("Values and keys are trimmed")
|
@("Values and keys are trimmed")
|
||||||
unittest {
|
unittest {
|
||||||
auto config = new KeyValueConfigFactory().parseConfig("
|
auto config = new TestKeyValueConfigFactory().parseConfig("
|
||||||
one = money
|
one = money
|
||||||
");
|
");
|
||||||
|
|
||||||
|
@ -113,10 +147,13 @@ version (unittest) {
|
||||||
|
|
||||||
@("Remove end-of-line comments")
|
@("Remove end-of-line comments")
|
||||||
unittest {
|
unittest {
|
||||||
auto config = new KeyValueConfigFactory().parseConfig("
|
auto config = new KeyValueConfigFactory!(SupportHashtagComments.yes,
|
||||||
|
SupportSemicolonComments.yes)().parseConfig("
|
||||||
server=localhost #todo: change me. default=localhost when not set.
|
server=localhost #todo: change me. default=localhost when not set.
|
||||||
|
port=9876; I think this port = right?
|
||||||
");
|
");
|
||||||
|
|
||||||
assert(config.get("server") == "localhost");
|
assert(config.get("server") == "localhost");
|
||||||
|
assert(config.get("port") == "9876");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue