aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Spek <Tyil@users.noreply.github.com>2017-04-26 09:57:40 +0200
committerGitHub <noreply@github.com>2017-04-26 09:57:39 +0200
commit845c2d891e12b7abe006aa1e36c1201266b29a51 (patch)
tree0ebf21647bd4bcea5b71a493302bea264a4f87e5
parentacdac7ea2f81e739c7e2b5cb37d3f3cdc71962a8 (diff)
parent7313624f98295bb80416009cf21012cec10bdc15 (diff)
Merge pull request #2 from scriptkitties/with-hash-mergev1.1.0
Merge hashes instead of overwriting them
-rw-r--r--META6.json4
-rw-r--r--lib/Config.pm698
-rw-r--r--t/having.t4
-rw-r--r--t/reading.t27
-rw-r--r--t/setting.t4
5 files changed, 111 insertions, 26 deletions
diff --git a/META6.json b/META6.json
index a3614c3..ccf33e7 100644
--- a/META6.json
+++ b/META6.json
@@ -1,12 +1,12 @@
{
"perl": "6",
"name": "Config",
- "version": "1.0.0",
+ "version": "1.1.0",
"auth": "github:scriptkitties",
"description": "Extensible library for reading and writing configuration files.",
"license": "GPL-3.0",
"depends": [
-
+ "Hash::Merge"
],
"provides": {
"Config": "lib/Config.pm6",
diff --git a/lib/Config.pm6 b/lib/Config.pm6
index 2fa01bf..40bfa27 100644
--- a/lib/Config.pm6
+++ b/lib/Config.pm6
@@ -2,6 +2,8 @@
use v6.c;
+use Hash::Merge;
+
use Config::Exception::MissingParserException;
use Config::Exception::UnknownTypeException;
use Config::Exception::FileNotFoundException;
@@ -10,28 +12,38 @@ use Config::Parser;
class Config is export
{
- has $!content = {};
- has $!path;
- has $!parser;
+ has Hash $!content = {};
+ has Str $!path = "";
+ has Str $!parser = "";
- multi method get(Str $key, Any $default = Nil)
+ #| Clear the config.
+ method clear()
{
- my $index = $!content;
-
- for $key.split(".") -> $part {
- return $default unless defined($index{$part});
+ $!content = {};
+ $!path = "";
+ $!parser = "";
+ }
- $index = $index{$part};
- }
+ #| Return the entire config hash.
+ multi method get()
+ {
+ return $!content;
+ }
- $index;
+ #| Get a value from the config object. To get a nested
+ #| key, use a . to descent a level.
+ multi method get(Str $key, Any $default = Nil)
+ {
+ self.get($key.split(".").list, $default);
}
- multi method get(@keyparts, Any $default = Nil)
+ #| Get a value from the config object using a list
+ #| to indicate the nested key to get.
+ multi method get(List $keyparts, Any $default = Nil)
{
my $index = $!content;
- for @keyparts -> $part {
+ for $keyparts.list -> $part {
return $default unless defined($index{$part});
$index = $index{$part};
@@ -40,6 +52,8 @@ class Config is export
$index;
}
+ #| Get the name of the parser module to use for the
+ #| given path.
method get-parser(Str $path, Str $parser = "")
{
if ($parser ne "") {
@@ -49,12 +63,13 @@ class Config is export
my $type = self.get-parser-type($path);
Config::Exception::UnknownTypeException.new(
- type => $type
+ file => $path
).throw() if $type eq Config::Type::unknown;
"Config::Parser::" ~ $type;
}
+ #| Get the type of parser required for the given path.
method get-parser-type(Str $path)
{
given ($path) {
@@ -74,23 +89,40 @@ class Config is export
return Config::Type::unknown;
}
- method has(Str $key) {
+ #| Check wether a given key exists.
+ multi method has(Str $key) {
+ self.has($key.split(".").list);
+ }
+
+ #| Check wether a given key exists using a list to supply
+ #| the nested key to check.
+ multi method has(List $keyparts)
+ {
my $index = $!content;
- for $key.split(".") -> $part {
+ for $keyparts.list -> $part {
return False unless defined($index{$part});
$index = $index{$part};
}
- True;
+ defined($index);
}
+ #| Reload the configuration. Requires the configuration to
+ #| have been loaded from a file.
multi method read()
{
+ if ($!path eq "") {
+ return False;
+ }
+
return self.load($!path);
}
+ #| Load a configuration file from the given path. Optionally
+ #| set a parser module name to use. If not set, Config will
+ #| attempt to deduce the parser to use.
multi method read(Str $path, Str $parser = "")
{
Config::Exception::FileNotFoundException.new(
@@ -109,22 +141,43 @@ class Config is export
}
require ::($!parser);
- $!content = ::($!parser).read($path);
+
+ self.read(::($!parser).read($path));
}
return True;
}
+ #| Read a list of paths. Will fail on the first file that
+ #| fails to load for whatever reason.
+ multi method read(List $paths, Str $parser = "")
+ {
+ for $paths.list -> $path {
+ self.read($path, $parser);
+ }
+
+ return True;
+ }
+
+ #| Read a plain Hash into the configuration.
multi method read(Hash $hash)
{
- $!content = $hash;
+ $!content.merge($hash);
+
+ return True;
+ }
+
+ #| Set a single key to a given value;
+ multi method set(Str $key, Any $value)
+ {
+ self.set($key.split(".").list, $value);
}
- method set(Str $key, Any $value)
+ multi method set(List $keyparts, Any $value)
{
my $index := $!content;
- for $key.split(".") -> $part {
+ for $keyparts.list -> $part {
$index{$part} = {} unless defined($index{$part});
$index := $index{$part};
@@ -135,6 +188,9 @@ class Config is export
self;
}
+ #| Write the current configuration to the given path. If
+ #| no parser is given, it tries to use the parser that
+ #| was used when loading the configuration.
method write(Str $path, Str $parser = "")
{
$parser = self.get-parser($path, $parser);
diff --git a/t/having.t b/t/having.t
index 3be2935..0627ed5 100644
--- a/t/having.t
+++ b/t/having.t
@@ -4,7 +4,7 @@ use v6.c;
use Test;
use lib "lib";
-plan 2;
+plan 4;
use Config;
@@ -19,3 +19,5 @@ $config.read({
ok $config.has("a"), "Check existence of simple key";
ok $config.has("b.c"), "Check existence of nested key";
+ok $config.has(["a"]), "Check existence of simple key using array";
+ok $config.has(["b", "c"]), "Check existence of nested key using array";
diff --git a/t/reading.t b/t/reading.t
index 52859af..e43252a 100644
--- a/t/reading.t
+++ b/t/reading.t
@@ -4,7 +4,7 @@ use v6.c;
use Test;
use lib "lib";
-plan 3;
+plan 5;
use Config;
@@ -13,3 +13,28 @@ my $config = Config.new();
throws-like { $config.read("nonexistant-config") }, Config::Exception::FileNotFoundException, "Reading nonexisting file";
throws-like { $config.read("t/test-stub") }, Config::Exception::UnknownTypeException, "Reading file of unknown type";
throws-like { $config.read("t/test-stub", "Config::Parser:NoSuchParserForTest") }, Config::Exception::MissingParserException, "Using non-existing parser";
+
+my $hash = {
+ "a" => "a",
+ "b" => {
+ "c" => "test"
+ }
+};
+
+$config.read($hash);
+
+is-deeply $config.get(), $hash, "Correctly sets hash";
+
+$config.read({
+ "b" => {
+ "d" => "another"
+ }
+});
+
+is-deeply $config.get(), {
+ "a" => "a",
+ "b" => {
+ "c" => "test",
+ "d" => "another"
+ }
+}, "Correctly merges new hash into existing config";
diff --git a/t/setting.t b/t/setting.t
index d9f0854..7e3a457 100644
--- a/t/setting.t
+++ b/t/setting.t
@@ -4,7 +4,7 @@ use v6.c;
use Test;
use lib "lib";
-plan 2;
+plan 4;
use Config;
@@ -12,3 +12,5 @@ my $config = Config.new();
ok $config.set("a", "test").get("a") eq "test", "Setting simple key";
ok $config.set("b.c", "test").get("b.c") eq "test", "Setting nested key";
+ok $config.set(["d"], "test").get("d") eq "test", "Setting simple key using array";
+ok $config.set(["e", "f"], "test").get("e.f") eq "test", "Setting nested key using array";