embulk 0.6.21 → 0.6.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/build.gradle +27 -15
- data/embulk-core/build.gradle +17 -1
- data/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java +216 -0
- data/embulk-core/src/main/java/org/embulk/EmbulkService.java +13 -7
- data/embulk-core/src/main/java/org/embulk/command/LiquidTemplate.java +8 -0
- data/embulk-core/src/main/java/org/embulk/command/Runner.java +63 -27
- data/embulk-core/src/main/java/org/embulk/config/ConfigLoader.java +5 -0
- data/embulk-core/src/main/java/org/embulk/config/DataSourceImpl.java +3 -3
- data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +1 -1
- data/embulk-core/src/main/java/org/embulk/exec/PooledBufferAllocator.java +3 -1
- data/embulk-core/src/main/java/org/embulk/guice/Bootstrap.java +150 -0
- data/embulk-core/src/main/java/org/embulk/guice/CloseableInjector.java +22 -0
- data/embulk-core/src/main/java/org/embulk/guice/CloseableInjectorProxy.java +47 -0
- data/embulk-core/src/main/java/org/embulk/guice/InjectorProxy.java +145 -0
- data/embulk-core/src/main/java/org/embulk/guice/LifeCycleManager.java +187 -0
- data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethods.java +89 -0
- data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethodsMap.java +38 -0
- data/embulk-core/src/main/java/org/embulk/guice/LifeCycleModule.java +97 -0
- data/embulk-core/src/main/java/org/embulk/spi/TempFileSpace.java +41 -7
- data/embulk-docs/build.gradle +3 -2
- data/embulk-docs/src/built-in.rst +30 -1
- data/embulk-docs/src/index.rst +1 -1
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.6.22.rst +26 -0
- data/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +2 -2
- data/lib/embulk/command/embulk_run.rb +11 -5
- data/lib/embulk/data_source.rb +28 -8
- data/lib/embulk/error.rb +7 -1
- data/lib/embulk/gems.rb +29 -0
- data/lib/embulk/java/bootstrap.rb +4 -0
- data/lib/embulk/java/liquid_helper.rb +17 -0
- data/lib/embulk/version.rb +1 -1
- data/test/helper.rb +11 -2
- metadata +46 -33
@@ -0,0 +1,89 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2010 Proofpoint, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
/*
|
17
|
+
* Copyright 2015 Sadayuki Furuhashi
|
18
|
+
*/
|
19
|
+
package org.embulk.guice;
|
20
|
+
|
21
|
+
import com.google.common.collect.ArrayListMultimap;
|
22
|
+
import com.google.common.collect.Lists;
|
23
|
+
import com.google.common.collect.Multimap;
|
24
|
+
|
25
|
+
import javax.annotation.PostConstruct;
|
26
|
+
import javax.annotation.PreDestroy;
|
27
|
+
import java.lang.annotation.Annotation;
|
28
|
+
import java.lang.reflect.Method;
|
29
|
+
import java.util.Collection;
|
30
|
+
import java.util.HashSet;
|
31
|
+
import java.util.Set;
|
32
|
+
|
33
|
+
class LifeCycleMethods
|
34
|
+
{
|
35
|
+
private final Multimap<Class<? extends Annotation>, Method> methodMap = ArrayListMultimap.create();
|
36
|
+
|
37
|
+
LifeCycleMethods(Class<?> clazz)
|
38
|
+
{
|
39
|
+
addLifeCycleMethods(clazz, new HashSet<String>(), new HashSet<String>());
|
40
|
+
}
|
41
|
+
|
42
|
+
boolean hasFor(Class<? extends Annotation> annotation)
|
43
|
+
{
|
44
|
+
Collection<Method> methods = methodMap.get(annotation);
|
45
|
+
return (methods != null) && (methods.size() > 0);
|
46
|
+
}
|
47
|
+
|
48
|
+
Collection<Method> methodsFor(Class<? extends Annotation> annotation)
|
49
|
+
{
|
50
|
+
Collection<Method> methods = methodMap.get(annotation);
|
51
|
+
return (methods != null) ? methods : Lists.<Method>newArrayList();
|
52
|
+
}
|
53
|
+
|
54
|
+
private void addLifeCycleMethods(Class<?> clazz, Set<String> usedConstructNames, Set<String> usedDestroyNames)
|
55
|
+
{
|
56
|
+
if (clazz == null) {
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
|
60
|
+
for (Method method : clazz.getDeclaredMethods()) {
|
61
|
+
if (method.isSynthetic() || method.isBridge()) {
|
62
|
+
continue;
|
63
|
+
}
|
64
|
+
|
65
|
+
processMethod(method, PostConstruct.class, usedConstructNames);
|
66
|
+
processMethod(method, PreDestroy.class, usedDestroyNames);
|
67
|
+
}
|
68
|
+
|
69
|
+
addLifeCycleMethods(clazz.getSuperclass(), usedConstructNames, usedDestroyNames);
|
70
|
+
for (Class<?> face : clazz.getInterfaces()) {
|
71
|
+
addLifeCycleMethods(face, usedConstructNames, usedDestroyNames);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
private void processMethod(Method method, Class<? extends Annotation> annotationClass, Set<String> usedSet)
|
76
|
+
{
|
77
|
+
if (method.isAnnotationPresent(annotationClass)) {
|
78
|
+
if (!usedSet.contains(method.getName())) {
|
79
|
+
if (method.getParameterTypes().length != 0) {
|
80
|
+
throw new UnsupportedOperationException(String.format("@PostConstruct/@PreDestroy methods cannot have arguments: %s", method.getDeclaringClass().getName() + "." + method.getName() + "(...)"));
|
81
|
+
}
|
82
|
+
|
83
|
+
method.setAccessible(true);
|
84
|
+
usedSet.add(method.getName());
|
85
|
+
methodMap.put(annotationClass, method);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2010 Proofpoint, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
/*
|
17
|
+
* Copyright 2015 Sadayuki Furuhashi
|
18
|
+
*/
|
19
|
+
package org.embulk.guice;
|
20
|
+
|
21
|
+
import com.google.common.collect.Maps;
|
22
|
+
|
23
|
+
import java.util.Map;
|
24
|
+
|
25
|
+
class LifeCycleMethodsMap
|
26
|
+
{
|
27
|
+
private final Map<Class<?>, LifeCycleMethods> map = Maps.newHashMap();
|
28
|
+
|
29
|
+
synchronized LifeCycleMethods get(Class<?> clazz)
|
30
|
+
{
|
31
|
+
LifeCycleMethods methods = map.get(clazz);
|
32
|
+
if (methods == null) {
|
33
|
+
methods = new LifeCycleMethods(clazz);
|
34
|
+
map.put(clazz, methods);
|
35
|
+
}
|
36
|
+
return methods;
|
37
|
+
}
|
38
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2010 Proofpoint, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
/*
|
17
|
+
* Copyright 2015 Sadayuki Furuhashi
|
18
|
+
*/
|
19
|
+
package org.embulk.guice;
|
20
|
+
|
21
|
+
import com.google.common.collect.Lists;
|
22
|
+
import com.google.inject.Binder;
|
23
|
+
import com.google.inject.Module;
|
24
|
+
import com.google.inject.Provides;
|
25
|
+
import com.google.inject.Singleton;
|
26
|
+
import com.google.inject.TypeLiteral;
|
27
|
+
import com.google.inject.spi.InjectionListener;
|
28
|
+
import com.google.inject.spi.TypeEncounter;
|
29
|
+
import com.google.inject.spi.TypeListener;
|
30
|
+
|
31
|
+
import javax.annotation.PostConstruct;
|
32
|
+
import javax.annotation.PreDestroy;
|
33
|
+
import java.util.List;
|
34
|
+
import java.util.concurrent.atomic.AtomicReference;
|
35
|
+
|
36
|
+
import static com.google.inject.matcher.Matchers.any;
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Guice module for binding the LifeCycle manager
|
40
|
+
*/
|
41
|
+
public class LifeCycleModule implements Module
|
42
|
+
{
|
43
|
+
private final List<Object> injectedInstances = Lists.newArrayList();
|
44
|
+
private final LifeCycleMethodsMap lifeCycleMethodsMap = new LifeCycleMethodsMap();
|
45
|
+
private final AtomicReference<LifeCycleManager> lifeCycleManagerRef = new AtomicReference<LifeCycleManager>(null);
|
46
|
+
|
47
|
+
@Override
|
48
|
+
public void configure(Binder binder)
|
49
|
+
{
|
50
|
+
binder.disableCircularProxies();
|
51
|
+
|
52
|
+
binder.bindListener(any(), new TypeListener()
|
53
|
+
{
|
54
|
+
@Override
|
55
|
+
public <T> void hear(TypeLiteral<T> type, TypeEncounter<T> encounter)
|
56
|
+
{
|
57
|
+
encounter.register(new InjectionListener<T>()
|
58
|
+
{
|
59
|
+
@Override
|
60
|
+
public void afterInjection(T obj)
|
61
|
+
{
|
62
|
+
if (isLifeCycleClass(obj.getClass())) {
|
63
|
+
LifeCycleManager lifeCycleManager = lifeCycleManagerRef.get();
|
64
|
+
if (lifeCycleManager != null) {
|
65
|
+
try {
|
66
|
+
lifeCycleManager.addInstance(obj);
|
67
|
+
}
|
68
|
+
catch (Exception e) {
|
69
|
+
throw new Error(e);
|
70
|
+
}
|
71
|
+
}
|
72
|
+
else {
|
73
|
+
injectedInstances.add(obj);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
});
|
78
|
+
}
|
79
|
+
});
|
80
|
+
}
|
81
|
+
|
82
|
+
@Provides
|
83
|
+
@Singleton
|
84
|
+
public LifeCycleManager getServerManager()
|
85
|
+
throws Exception
|
86
|
+
{
|
87
|
+
LifeCycleManager lifeCycleManager = new LifeCycleManager(injectedInstances, lifeCycleMethodsMap);
|
88
|
+
lifeCycleManagerRef.set(lifeCycleManager);
|
89
|
+
return lifeCycleManager;
|
90
|
+
}
|
91
|
+
|
92
|
+
private boolean isLifeCycleClass(Class<?> clazz)
|
93
|
+
{
|
94
|
+
LifeCycleMethods methods = lifeCycleMethodsMap.get(clazz);
|
95
|
+
return methods.hasFor(PostConstruct.class) || methods.hasFor(PreDestroy.class);
|
96
|
+
}
|
97
|
+
}
|
@@ -3,6 +3,11 @@ package org.embulk.spi;
|
|
3
3
|
import java.util.List;
|
4
4
|
import java.util.ArrayList;
|
5
5
|
import java.util.Collections;
|
6
|
+
import java.nio.file.Files;
|
7
|
+
import java.nio.file.Path;
|
8
|
+
import java.nio.file.SimpleFileVisitor;
|
9
|
+
import java.nio.file.attribute.BasicFileAttributes;
|
10
|
+
import java.nio.file.FileVisitResult;
|
6
11
|
import java.io.File;
|
7
12
|
import java.io.IOException;
|
8
13
|
import com.google.common.base.Preconditions;
|
@@ -43,14 +48,43 @@ public class TempFileSpace
|
|
43
48
|
|
44
49
|
public void cleanup()
|
45
50
|
{
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
}
|
51
|
+
try {
|
52
|
+
deleteFilesIfExistsRecursively(dir);
|
53
|
+
}
|
54
|
+
catch (IOException ex) {
|
55
|
+
// ignore IOException
|
52
56
|
}
|
53
|
-
dir.delete();
|
54
57
|
dirCreated = false;
|
55
58
|
}
|
59
|
+
|
60
|
+
private void deleteFilesIfExistsRecursively(File dir)
|
61
|
+
throws IOException
|
62
|
+
{
|
63
|
+
Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>()
|
64
|
+
{
|
65
|
+
@Override
|
66
|
+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
|
67
|
+
{
|
68
|
+
try {
|
69
|
+
Files.deleteIfExists(file);
|
70
|
+
}
|
71
|
+
catch (IOException ex) {
|
72
|
+
// ignore IOException
|
73
|
+
}
|
74
|
+
return FileVisitResult.CONTINUE;
|
75
|
+
}
|
76
|
+
|
77
|
+
@Override
|
78
|
+
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
|
79
|
+
{
|
80
|
+
try {
|
81
|
+
Files.deleteIfExists(dir);
|
82
|
+
}
|
83
|
+
catch (IOException ex) {
|
84
|
+
// ignore IOException
|
85
|
+
}
|
86
|
+
return FileVisitResult.CONTINUE;
|
87
|
+
}
|
88
|
+
});
|
89
|
+
}
|
56
90
|
}
|
data/embulk-docs/build.gradle
CHANGED
@@ -23,8 +23,9 @@ task javadoc_html(type: Copy, dependsOn: [':embulk-core:javadoc']) {
|
|
23
23
|
|
24
24
|
task rdoc_html(type: JRubyExec) {
|
25
25
|
workingDir '..'
|
26
|
-
jrubyArgs '-ryard', '-eYARD::CLI::Yardoc.run(*ARGV)'
|
27
|
-
script 'lib'
|
26
|
+
jrubyArgs '-ryard', '-eYARD::CLI::Yardoc.run(*ARGV)'
|
27
|
+
script './lib/embulk/version.rb' // dummy
|
28
|
+
scriptArgs 'lib', '-o', 'embulk-docs/build/html/rdoc'
|
28
29
|
}
|
29
30
|
|
30
31
|
task site(type: Copy, dependsOn: ['sphinx_html', 'rdoc_html', 'javadoc_html']) {
|
@@ -59,6 +59,35 @@ A configuration file consists of following sections:
|
|
59
59
|
In many cases, what you need to write is **in:**, **out**: and **formatter** sections only because ``guess`` command guesses **parser** and **decoder** options for you. See also the `Quick Start <https://github.com/embulk/embulk#quick-start>`_.
|
60
60
|
|
61
61
|
|
62
|
+
Using variables
|
63
|
+
~~~~~~~~~~~~~~~~~~
|
64
|
+
|
65
|
+
You can embed environment variables in configuration file using `Liquid template engine <http://liquidmarkup.org/>`_ (This is experimental feature. Behavior might change or be removed in future releases).
|
66
|
+
|
67
|
+
To use template engine, configuration file name must end with ``.yml.liquid``.
|
68
|
+
|
69
|
+
Environment variables are set to ``env`` variable.
|
70
|
+
|
71
|
+
.. code-block:: yaml
|
72
|
+
|
73
|
+
in:
|
74
|
+
type: file
|
75
|
+
path_prefix: {{ env.path_prefix }}
|
76
|
+
decoders:
|
77
|
+
- {type: gzip}
|
78
|
+
parser:
|
79
|
+
...
|
80
|
+
out:
|
81
|
+
type: postgresql
|
82
|
+
host: {{ env.pg_host }}
|
83
|
+
port: {{ env.pg_port }}
|
84
|
+
user: {{ env.pg_user }}
|
85
|
+
password: "{{ env.pg_password }}"
|
86
|
+
database: embulk_load
|
87
|
+
mode: insert
|
88
|
+
table: {{ env.pg_table }}
|
89
|
+
|
90
|
+
|
62
91
|
Local file input plugin
|
63
92
|
------------------
|
64
93
|
|
@@ -248,7 +277,7 @@ Options
|
|
248
277
|
+====================+==========+===================================================+============================+
|
249
278
|
| path\_prefix | string | Path prefix of the output files | required |
|
250
279
|
+--------------------+----------+---------------------------------------------------+----------------------------+
|
251
|
-
| sequence\_format | string | Format of the sequence number of the output files | ``%03d.%02d.`` by default
|
280
|
+
| sequence\_format | string | Format of the sequence number of the output files | ``%03d.%02d.`` by default |
|
252
281
|
+--------------------+----------+---------------------------------------------------+----------------------------+
|
253
282
|
| file\_ext | string | Path suffix of the output files (e.g. ``"csv"``) | required |
|
254
283
|
+--------------------+----------+---------------------------------------------------+----------------------------+
|
data/embulk-docs/src/index.rst
CHANGED
data/embulk-docs/src/release.rst
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
Release 0.6.22
|
2
|
+
==================================
|
3
|
+
|
4
|
+
General Changes
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Added experimental support for Liquid template engine of configuration files. If configuration file name ends with ``.yml.liquid``, embulk runs embeds variables using Liquid template engine.
|
8
|
+
|
9
|
+
Ruby Plugin API
|
10
|
+
------------------
|
11
|
+
|
12
|
+
* Added ``Embulk.require_classpath`` method to initialize plugin test environment (@cosmo0920++)
|
13
|
+
* ``Embulk::ConfigError`` extends ``org.embulk.config.ConfigException``.
|
14
|
+
* ``Embulk::DataSource`` raises ``Embulk::ConfigError`` instead of StandardError.
|
15
|
+
|
16
|
+
Java Plugin API
|
17
|
+
------------------
|
18
|
+
|
19
|
+
* Added ``org.embulk.EmbulkEmbed`` to embed Embulk in an applications as a library.
|
20
|
+
* Added ``ConfigLoader.newConfigSource`` to create an empty ConfigSource.
|
21
|
+
* ``TempFileSpace.cleanup`` deletes files and directories recursively (@cosmo0920++)
|
22
|
+
|
23
|
+
|
24
|
+
Release Date
|
25
|
+
------------------
|
26
|
+
2015-08-11
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#Tue Aug 11 00:26:20 PDT 2015
|
2
2
|
distributionBase=GRADLE_USER_HOME
|
3
3
|
distributionPath=wrapper/dists
|
4
4
|
zipStoreBase=GRADLE_USER_HOME
|
5
5
|
zipStorePath=wrapper/dists
|
6
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.
|
6
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip
|
@@ -206,6 +206,8 @@ examples:
|
|
206
206
|
args = 0..0
|
207
207
|
|
208
208
|
when :gem
|
209
|
+
require 'embulk/gems'
|
210
|
+
Embulk.add_embedded_gem_path
|
209
211
|
require 'rubygems/gem_runner'
|
210
212
|
Gem::GemRunner.new.run argv
|
211
213
|
exit 0
|
@@ -357,11 +359,7 @@ examples:
|
|
357
359
|
java.lang.Class.forName('org.embulk.command.Runner')
|
358
360
|
rescue java.lang.ClassNotFoundException
|
359
361
|
# load classpath
|
360
|
-
|
361
|
-
jars = Dir.entries(classpath_dir).select {|f| f =~ /\.jar$/ }.sort
|
362
|
-
jars.each do |jar|
|
363
|
-
require File.join(classpath_dir, jar)
|
364
|
-
end
|
362
|
+
Embulk.require_classpath
|
365
363
|
end
|
366
364
|
|
367
365
|
setup_plugin_paths(plugin_paths)
|
@@ -390,6 +388,14 @@ examples:
|
|
390
388
|
end
|
391
389
|
end
|
392
390
|
|
391
|
+
def self.require_classpath
|
392
|
+
classpath_dir = Embulk.home("classpath")
|
393
|
+
jars = Dir.entries(classpath_dir).select{|f| f =~ /\.jar$/ }.sort
|
394
|
+
jars.each do |jar|
|
395
|
+
require File.join(classpath_dir, jar)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
393
399
|
def self.default_gem_home
|
394
400
|
if RUBY_PLATFORM =~ /java/i
|
395
401
|
user_home = java.lang.System.properties["user.home"]
|
data/lib/embulk/data_source.rb
CHANGED
@@ -142,31 +142,51 @@ module Embulk
|
|
142
142
|
value =
|
143
143
|
case type
|
144
144
|
when :integer
|
145
|
-
|
145
|
+
begin
|
146
|
+
Integer(v)
|
147
|
+
rescue => e
|
148
|
+
raise ConfigError, e
|
149
|
+
end
|
146
150
|
when :float
|
147
|
-
|
151
|
+
begin
|
152
|
+
Float(v)
|
153
|
+
rescue => e
|
154
|
+
raise ConfigError, e
|
155
|
+
end
|
148
156
|
when :string
|
149
|
-
|
157
|
+
begin
|
158
|
+
String(v).dup
|
159
|
+
rescue => e
|
160
|
+
raise ConfigError, e
|
161
|
+
end
|
150
162
|
when :bool
|
151
|
-
|
163
|
+
begin
|
164
|
+
!!v # TODO validation
|
165
|
+
rescue => e
|
166
|
+
raise ConfigError, e
|
167
|
+
end
|
152
168
|
when :hash
|
153
|
-
raise
|
169
|
+
raise ConfigError, "Invalid value for :hash" unless v.is_a?(Hash)
|
154
170
|
DataSource.new.merge!(v)
|
155
171
|
when :array
|
156
|
-
raise
|
172
|
+
raise ConfigError, "Invalid value for :array" unless v.is_a?(Array)
|
157
173
|
v.dup
|
158
174
|
else
|
159
175
|
unless type.respond_to?(:load)
|
160
176
|
raise ArgumentError, "Unknown type #{type.to_s.dump}"
|
161
177
|
end
|
162
|
-
|
178
|
+
begin
|
179
|
+
type.load(v)
|
180
|
+
rescue => e
|
181
|
+
raise ConfigError, e
|
182
|
+
end
|
163
183
|
end
|
164
184
|
|
165
185
|
elsif options.has_key?(:default)
|
166
186
|
value = options[:default]
|
167
187
|
|
168
188
|
else
|
169
|
-
raise "Required field #{key.to_s.dump} is not set"
|
189
|
+
raise ConfigError, "Required field #{key.to_s.dump} is not set"
|
170
190
|
end
|
171
191
|
|
172
192
|
return value
|