embulk 0.6.21 → 0.6.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/build.gradle +27 -15
  4. data/embulk-core/build.gradle +17 -1
  5. data/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java +216 -0
  6. data/embulk-core/src/main/java/org/embulk/EmbulkService.java +13 -7
  7. data/embulk-core/src/main/java/org/embulk/command/LiquidTemplate.java +8 -0
  8. data/embulk-core/src/main/java/org/embulk/command/Runner.java +63 -27
  9. data/embulk-core/src/main/java/org/embulk/config/ConfigLoader.java +5 -0
  10. data/embulk-core/src/main/java/org/embulk/config/DataSourceImpl.java +3 -3
  11. data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +1 -1
  12. data/embulk-core/src/main/java/org/embulk/exec/PooledBufferAllocator.java +3 -1
  13. data/embulk-core/src/main/java/org/embulk/guice/Bootstrap.java +150 -0
  14. data/embulk-core/src/main/java/org/embulk/guice/CloseableInjector.java +22 -0
  15. data/embulk-core/src/main/java/org/embulk/guice/CloseableInjectorProxy.java +47 -0
  16. data/embulk-core/src/main/java/org/embulk/guice/InjectorProxy.java +145 -0
  17. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleManager.java +187 -0
  18. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethods.java +89 -0
  19. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethodsMap.java +38 -0
  20. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleModule.java +97 -0
  21. data/embulk-core/src/main/java/org/embulk/spi/TempFileSpace.java +41 -7
  22. data/embulk-docs/build.gradle +3 -2
  23. data/embulk-docs/src/built-in.rst +30 -1
  24. data/embulk-docs/src/index.rst +1 -1
  25. data/embulk-docs/src/release.rst +1 -0
  26. data/embulk-docs/src/release/release-0.6.22.rst +26 -0
  27. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  28. data/gradle/wrapper/gradle-wrapper.properties +2 -2
  29. data/lib/embulk/command/embulk_run.rb +11 -5
  30. data/lib/embulk/data_source.rb +28 -8
  31. data/lib/embulk/error.rb +7 -1
  32. data/lib/embulk/gems.rb +29 -0
  33. data/lib/embulk/java/bootstrap.rb +4 -0
  34. data/lib/embulk/java/liquid_helper.rb +17 -0
  35. data/lib/embulk/version.rb +1 -1
  36. data/test/helper.rb +11 -2
  37. metadata +46 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90d6280d5bdcffb92922bfd929eae4bcc6d83b92
4
- data.tar.gz: 0e2c0d5e8a9f990cdfbb7006be196f9bfef19030
3
+ metadata.gz: 9517ba89a58e4c0980976822f7508f0b1040ea6c
4
+ data.tar.gz: dc378ef610b2e1cab1d4b66eb3ff46b64e0817bf
5
5
  SHA512:
6
- metadata.gz: e2ccbee9c830dd29e86734c1615354083fca35068476a30d0a06944926c3eb63b0386ab5db39d0ad7ed660a2c395da84e68d8433ee222274102dc01b30312de6
7
- data.tar.gz: 27174e4750c66516ead7b0ff90df6dc804e8d45694354cd03602654680b30dd0464fef0221aa18a9c28e6495ad6709e44e0c4469b12e55f3ca81d8b1bdb06fdc
6
+ metadata.gz: 07bd4d4bd1688835f9c830dab95206d7343c0c183427472842106f341d26feea84189f032499dbb1d5c955ae88a348fd806a09003b8fc0b46cd14e41fadf94de
7
+ data.tar.gz: 976b17fa42e6ba9dd0c02506097af5a0ac32b50155024a70cd9fa831f905ab5909caa9b0fec62ce96f86fd347271d8d39587e99d2a39805287280b42d4480695
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ vendor/
12
12
  .yardoc
13
13
  /embulk-*.jar
14
14
  /.gradle
15
+ /coverage
@@ -1,20 +1,25 @@
1
-
2
- plugins {
3
- id 'com.jfrog.bintray' version '1.1'
4
- id 'com.github.ben-manes.versions' version '0.7'
5
- id 'com.github.jruby-gradle.base' version '0.1.5'
6
- id 'com.github.johnrengelman.shadow' version '1.2.0'
1
+ buildscript {
2
+ repositories { jcenter() }
3
+ dependencies {
4
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.3.1'
5
+ classpath "com.github.jruby-gradle:jruby-gradle-jar-plugin:1.0.1"
6
+ classpath 'com.github.ben-manes:gradle-versions-plugin:0.11.3'
7
+ classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.2'
8
+ }
7
9
  }
10
+ apply plugin: "com.github.jruby-gradle.jar"
11
+ apply plugin: 'com.jfrog.bintray'
12
+ apply plugin: 'com.github.johnrengelman.shadow'
8
13
 
9
14
  def java_projects = [project(":embulk-core"), project(":embulk-standards"), project(":embulk-cli")]
10
15
  def release_projects = [project(":embulk-core"), project(":embulk-standards")]
11
16
 
12
17
  allprojects {
13
18
  group = 'org.embulk'
14
- version = '0.6.21'
19
+ version = '0.6.22'
15
20
 
16
21
  ext {
17
- jrubyVersion = '1.7.19'
22
+ jrubyVersion = '1.7.21'
18
23
  }
19
24
 
20
25
  apply plugin: 'java'
@@ -140,12 +145,17 @@ subprojects {
140
145
  }
141
146
  }
142
147
 
148
+ task wrapper(type: Wrapper) {
149
+ gradleVersion = '2.6'
150
+ }
151
+
143
152
  import com.github.jrubygradle.JRubyExec
144
153
  jruby {
145
154
  execVersion = project.jrubyVersion
146
155
  }
147
156
 
148
157
  dependencies {
158
+ jrubyExec 'rubygems:simplecov:0.10.+'
149
159
  jrubyExec 'rubygems:test-unit:3.0.+'
150
160
  }
151
161
 
@@ -226,8 +236,8 @@ project(':embulk-cli') {
226
236
  }
227
237
 
228
238
  task rubyTest(type: JRubyExec) {
229
- jrubyArgs '-Ilib', '-Itest', '-rtest/unit', '-eTest::Unit::AutoRunner.run(true, *ARGV)'
230
- script 'test'
239
+ jrubyArgs '-Ilib', '-Itest', '-rtest/unit', '--debug', '-eARGV.replace([]); Test::Unit::AutoRunner.run(true, "test")'
240
+ script './lib/embulk/version.rb' // dummy
231
241
  }
232
242
  rubyTest.dependsOn('classpath')
233
243
 
@@ -235,9 +245,10 @@ rubyTest.dependsOn('classpath')
235
245
  // gem task
236
246
  //
237
247
  task gem(type: JRubyExec) {
238
- jrubyArgs '-rrubygems/gem_runner', '-eGem::GemRunner.new.run(ARGV)', 'build'
239
- script 'embulk.gemspec'
240
- doLast { ant.move(file: "${project.name}-${project.version}.gem", todir: "pkg") }
248
+ jrubyArgs '-rrubygems/gem_runner', '-eGem::GemRunner.new.run(ARGV)'
249
+ script './lib/embulk/version.rb' // dummy
250
+ scriptArgs 'build', 'embulk.gemspec'
251
+ doLast { file("${project.name}-${project.version}.gem").renameTo("pkg/${project.name}-${project.version}.gem") }
241
252
  }
242
253
  gem.dependsOn('classpath')
243
254
 
@@ -245,8 +256,9 @@ gem.dependsOn('classpath')
245
256
  // rubyGemsUpload task
246
257
  //
247
258
  task rubyGemsUpload(type: JRubyExec, dependsOn: ["gem"]) {
248
- jrubyArgs '-rrubygems/gem_runner', '-eGem::GemRunner.new.run(ARGV)', 'push'
249
- script "pkg/embulk-${project.version}.gem"
259
+ jrubyArgs '-rrubygems/gem_runner', '-eGem::GemRunner.new.run(ARGV)'
260
+ script './lib/embulk/version.rb' // dummy
261
+ scriptArgs 'push', "pkg/embulk-${project.version}.gem"
250
262
  }
251
263
 
252
264
  //
@@ -1,6 +1,8 @@
1
+ apply plugin: "com.github.jruby-gradle.jar"
2
+
1
3
  // include ruby scripts to jar. don't use sourceSets.main.resources.srcDirs
2
4
  // because IntelliJ causes error if srcDirs includes files out of projectDir.
3
- processResources.from "${rootProject.projectDir}/lib"
5
+ processResources.from("${rootProject.projectDir}/lib", "${buildDir}/jruby")
4
6
 
5
7
  configurations {
6
8
  // com.google.inject:guice depends on asm and cglib but version of the libraries conflict
@@ -9,6 +11,9 @@ configurations {
9
11
  compile.exclude group: 'org.sonatype.sisu.inject', module: 'cglib'
10
12
  }
11
13
 
14
+ import com.github.jrubygradle.JRubyExec
15
+ import com.github.jrubygradle.JRubyPrepare
16
+
12
17
  // determine which dependencies have updates: $ gradle dependencyUpdates
13
18
  dependencies {
14
19
  compile 'com.google.guava:guava:18.0'
@@ -35,4 +40,15 @@ dependencies {
35
40
 
36
41
  // for embulk/guess/charset.rb
37
42
  compile 'com.ibm.icu:icu4j:54.1.1'
43
+
44
+ gems 'rubygems:liquid:3.0.6'
45
+ }
46
+
47
+ task unpackGems(type: JRubyPrepare) {
48
+ outputDir file("${buildDir}/jruby/embulk/gems")
49
+ dependencies configurations.gems
50
+ doLast {
51
+ fileTree(dir: "${buildDir}/jruby/embulk/gems/cache", include: "*.gem").each { f -> f.delete() }
52
+ }
38
53
  }
54
+ processResources.dependsOn("unpackGems")
@@ -0,0 +1,216 @@
1
+ package org.embulk;
2
+
3
+ import java.util.Arrays;
4
+ import java.util.List;
5
+ import com.google.common.base.Function;
6
+ import com.google.common.base.Throwables;
7
+ import com.google.common.collect.ImmutableList;
8
+ import com.google.common.collect.Iterables;
9
+ import com.google.common.annotations.Beta;
10
+ import com.google.inject.Injector;
11
+ import com.google.inject.Module;
12
+ import com.fasterxml.jackson.databind.ObjectMapper;
13
+ import org.embulk.config.ModelManager;
14
+ import org.embulk.config.ConfigSource;
15
+ import org.embulk.config.ConfigDiff;
16
+ import org.embulk.config.ConfigLoader;
17
+ import org.embulk.EmbulkService;
18
+ import org.embulk.exec.BulkLoader;
19
+ import org.embulk.exec.GuessExecutor;
20
+ import org.embulk.exec.PreviewExecutor;
21
+ import org.embulk.exec.PreviewResult;
22
+ import org.embulk.exec.ExecutionResult;
23
+ import org.embulk.exec.PartialExecutionException;
24
+ import org.embulk.exec.ResumeState;
25
+ import org.embulk.spi.ExecSession;
26
+ import org.embulk.guice.Bootstrap;
27
+ import org.embulk.guice.CloseableInjector;
28
+ import static com.google.common.base.Preconditions.checkState;
29
+ import static com.google.common.base.Preconditions.checkNotNull;
30
+
31
+ @Beta
32
+ public class EmbulkEmbed
33
+ implements AutoCloseable
34
+ {
35
+ public static ConfigLoader newSystemConfigLoader()
36
+ {
37
+ return new ConfigLoader(new ModelManager(null, new ObjectMapper()));
38
+ }
39
+
40
+ private final CloseableInjector injector;
41
+ private final BulkLoader bulkLoader;
42
+ private final GuessExecutor guessExecutor;
43
+ private final PreviewExecutor previewExecutor;
44
+
45
+ public EmbulkEmbed(ConfigSource systemConfig, Module... additionalModules)
46
+ {
47
+ this(systemConfig, Arrays.asList(additionalModules));
48
+ }
49
+
50
+ public EmbulkEmbed(ConfigSource systemConfig,
51
+ final Iterable<? extends Module> additionalModules)
52
+ {
53
+ this(systemConfig,
54
+ new Function<List<Module>, Iterable<Module>>()
55
+ {
56
+ public Iterable<Module> apply(List<Module> source)
57
+ {
58
+ return Iterables.concat(source, additionalModules);
59
+ }
60
+ });
61
+ }
62
+
63
+ public EmbulkEmbed(ConfigSource systemConfig,
64
+ Function<? super List<Module>, ? extends Iterable<? extends Module>> overrideModules)
65
+ {
66
+ this.injector = new Bootstrap()
67
+ .requireExplicitBindings(false)
68
+ .addModules(EmbulkService.standardModuleList(systemConfig))
69
+ .overrideModules(overrideModules)
70
+ .initializeCloseable();
71
+ injector.getInstance(org.slf4j.ILoggerFactory.class);
72
+ this.bulkLoader = new BulkLoader(injector, systemConfig);
73
+ this.guessExecutor = injector.getInstance(GuessExecutor.class);
74
+ this.previewExecutor = injector.getInstance(PreviewExecutor.class);
75
+ }
76
+
77
+ @Override
78
+ public void close()
79
+ {
80
+ try {
81
+ injector.close();
82
+ }
83
+ catch (Exception ex) {
84
+ throw Throwables.propagate(ex);
85
+ }
86
+ }
87
+
88
+ public Injector getInjector()
89
+ {
90
+ return injector;
91
+ }
92
+
93
+ public ModelManager getModelManager()
94
+ {
95
+ return injector.getInstance(ModelManager.class);
96
+ }
97
+
98
+ public ConfigLoader newConfigLoader()
99
+ {
100
+ return injector.getInstance(ConfigLoader.class);
101
+ }
102
+
103
+ public ExecSession.Builder sessionBuilder(ConfigSource execConfig)
104
+ {
105
+ return ExecSession.builder(injector).fromExecConfig(execConfig);
106
+ }
107
+
108
+ public ConfigDiff guess(ExecSession exec, ConfigSource config)
109
+ {
110
+ return guessExecutor.guess(exec, config);
111
+ }
112
+
113
+ public PreviewResult preview(ExecSession exec, ConfigSource config)
114
+ {
115
+ return previewExecutor.preview(exec, config);
116
+ }
117
+
118
+ public ExecutionResult run(ExecSession exec, ConfigSource config)
119
+ {
120
+ try {
121
+ return bulkLoader.run(exec, config);
122
+ } catch (PartialExecutionException partial) {
123
+ try {
124
+ bulkLoader.cleanup(config, partial.getResumeState());
125
+ } catch (Throwable ex) {
126
+ partial.addSuppressed(ex);
127
+ }
128
+ throw partial;
129
+ }
130
+ }
131
+
132
+ public ResumableResult runResumable(ExecSession exec, ConfigSource config)
133
+ {
134
+ ExecutionResult result;
135
+ try {
136
+ result = bulkLoader.run(exec, config);
137
+ } catch (PartialExecutionException partial) {
138
+ return new ResumableResult(partial);
139
+ }
140
+ return new ResumableResult(result);
141
+ }
142
+
143
+ public ResumeAction resumeAction(ConfigSource config, ResumeState resumeState)
144
+ {
145
+ return new ResumeAction(config, resumeState);
146
+ }
147
+
148
+ public static class ResumableResult
149
+ {
150
+ private final ExecutionResult successfulResult;
151
+ private final PartialExecutionException partialExecutionException;
152
+
153
+ public ResumableResult(PartialExecutionException partialExecutionException)
154
+ {
155
+ this.successfulResult = null;
156
+ this.partialExecutionException = checkNotNull(partialExecutionException);
157
+ }
158
+
159
+ public ResumableResult(ExecutionResult successfulResult)
160
+ {
161
+ this.successfulResult = checkNotNull(successfulResult);
162
+ this.partialExecutionException = null;
163
+ }
164
+
165
+ public boolean isSuccessful()
166
+ {
167
+ return successfulResult != null;
168
+ }
169
+
170
+ public ExecutionResult getSuccessfulResult()
171
+ {
172
+ checkState(successfulResult != null);
173
+ return successfulResult;
174
+ }
175
+
176
+ public Throwable getCause()
177
+ {
178
+ checkState(partialExecutionException != null);
179
+ return partialExecutionException.getCause();
180
+ }
181
+
182
+ public ResumeState getResumeState()
183
+ {
184
+ checkState(partialExecutionException != null);
185
+ return partialExecutionException.getResumeState();
186
+ }
187
+ }
188
+
189
+ public class ResumeAction
190
+ {
191
+ private final ConfigSource config;
192
+ private final ResumeState resumeState;
193
+
194
+ public ResumeAction(ConfigSource config, ResumeState resumeState)
195
+ {
196
+ this.config = config;
197
+ this.resumeState = resumeState;
198
+ }
199
+
200
+ public ResumableResult resume()
201
+ {
202
+ ExecutionResult result;
203
+ try {
204
+ result = bulkLoader.resume(config, resumeState);
205
+ } catch (PartialExecutionException partial) {
206
+ return new ResumableResult(partial);
207
+ }
208
+ return new ResumableResult(result);
209
+ }
210
+
211
+ public void cleanup()
212
+ {
213
+ bulkLoader.cleanup(config, resumeState);
214
+ }
215
+ }
216
+ }
@@ -1,5 +1,6 @@
1
1
  package org.embulk;
2
2
 
3
+ import java.util.List;
3
4
  import com.google.common.collect.ImmutableList;
4
5
  import com.google.inject.Guice;
5
6
  import com.google.inject.Injector;
@@ -35,18 +36,23 @@ public class EmbulkService
35
36
  return modules;
36
37
  }
37
38
 
39
+ static List<Module> standardModuleList(ConfigSource systemConfig)
40
+ {
41
+ return ImmutableList.of(
42
+ new SystemConfigModule(systemConfig),
43
+ new ExecModule(),
44
+ new ExtensionServiceLoaderModule(systemConfig),
45
+ new PluginClassLoaderModule(systemConfig),
46
+ new BuiltinPluginSourceModule(),
47
+ new JRubyScriptingModule(systemConfig));
48
+ }
49
+
38
50
  public Injector initialize()
39
51
  {
40
52
  checkState(!initialized, "Already initialized");
41
53
 
42
54
  ImmutableList.Builder<Module> builder = ImmutableList.builder();
43
- builder.add(new SystemConfigModule(systemConfig));
44
- builder.add(new ExecModule());
45
- builder.add(new ExtensionServiceLoaderModule(systemConfig));
46
- builder.add(new PluginClassLoaderModule(systemConfig));
47
- builder.add(new BuiltinPluginSourceModule());
48
- builder.add(new JRubyScriptingModule(systemConfig));
49
-
55
+ builder.addAll(standardModuleList(systemConfig));
50
56
  builder.addAll(getAdditionalModules(systemConfig));
51
57
 
52
58
  Iterable<? extends Module> modules = builder.build();
@@ -0,0 +1,8 @@
1
+ package org.embulk.command;
2
+
3
+ import java.util.Map;
4
+
5
+ public interface LiquidTemplate
6
+ {
7
+ public String render(String source, Map<String, String> params);
8
+ }
@@ -10,10 +10,15 @@ import java.io.FileOutputStream;
10
10
  import java.io.BufferedWriter;
11
11
  import java.io.OutputStreamWriter;
12
12
  import java.io.Writer;
13
+ import java.io.ByteArrayInputStream;
14
+ import java.nio.charset.StandardCharsets;
13
15
  import org.yaml.snakeyaml.Yaml;
14
16
  import com.fasterxml.jackson.databind.ObjectMapper;
15
17
  import com.google.common.base.Function;
18
+ import com.google.common.collect.ImmutableMap;
19
+ import com.google.common.io.Files;
16
20
  import com.google.inject.Injector;
21
+ import org.jruby.embed.ScriptingContainer;
17
22
  import org.embulk.config.ConfigSource;
18
23
  import org.embulk.config.DataSource;
19
24
  import org.embulk.config.ConfigLoader;
@@ -30,7 +35,7 @@ import org.embulk.exec.ResumeState;
30
35
  import org.embulk.exec.PartialExecutionException;
31
36
  import org.embulk.spi.time.Timestamp;
32
37
  import org.embulk.spi.ExecSession;
33
- import org.embulk.EmbulkService;
38
+ import org.embulk.EmbulkEmbed;
34
39
 
35
40
  public class Runner
36
41
  {
@@ -60,8 +65,9 @@ public class Runner
60
65
 
61
66
  private final Options options;
62
67
  private final ConfigSource systemConfig;
63
- private final EmbulkService service;
64
- private final Injector injector;
68
+
69
+ private EmbulkEmbed embed;
70
+ private Injector injector;
65
71
 
66
72
  public Runner(String optionJson)
67
73
  {
@@ -73,8 +79,6 @@ public class Runner
73
79
  mergeOptionsToSystemConfig(options, configLoader, systemConfig);
74
80
 
75
81
  this.systemConfig = systemConfig;
76
- this.service = new EmbulkService(systemConfig);
77
- this.injector = service.initialize();
78
82
  }
79
83
 
80
84
  @SuppressWarnings("unchecked")
@@ -105,27 +109,31 @@ public class Runner
105
109
 
106
110
  public void main(String command, String[] args)
107
111
  {
108
- switch (command) {
109
- case "run":
110
- run(args[0]);
111
- break;
112
- case "cleanup":
113
- cleanup(args[0]);
114
- break;
115
- case "guess":
116
- guess(args[0]);
117
- break;
118
- case "preview":
119
- preview(args[0]);
120
- break;
121
- default:
122
- throw new RuntimeException("Unsupported command: "+command);
112
+ try (EmbulkEmbed embed = new EmbulkEmbed(systemConfig)) {
113
+ this.injector = embed.getInjector();
114
+
115
+ switch (command) {
116
+ case "run":
117
+ run(args[0]);
118
+ break;
119
+ case "cleanup":
120
+ cleanup(args[0]);
121
+ break;
122
+ case "guess":
123
+ guess(args[0]);
124
+ break;
125
+ case "preview":
126
+ preview(args[0]);
127
+ break;
128
+ default:
129
+ throw new RuntimeException("Unsupported command: "+command);
130
+ }
123
131
  }
124
132
  }
125
133
 
126
134
  public void run(String configPath)
127
135
  {
128
- ConfigSource config = loadYamlConfig(configPath);
136
+ ConfigSource config = loadConfig(configPath);
129
137
  checkFileWritable(options.getNextConfigOutputPath());
130
138
  checkFileWritable(options.getResumeStatePath());
131
139
 
@@ -199,7 +207,7 @@ public class Runner
199
207
  if (resumePath == null) {
200
208
  throw new IllegalArgumentException("Resume path is required for cleanup");
201
209
  }
202
- ConfigSource config = loadYamlConfig(configPath);
210
+ ConfigSource config = loadConfig(configPath);
203
211
  ConfigSource resumeConfig = loadYamlConfig(resumePath);
204
212
  ResumeState resume = resumeConfig.loadConfig(ResumeState.class);
205
213
 
@@ -212,7 +220,7 @@ public class Runner
212
220
 
213
221
  public void guess(String partialConfigPath)
214
222
  {
215
- ConfigSource config = loadYamlConfig(partialConfigPath);
223
+ ConfigSource config = loadConfig(partialConfigPath);
216
224
  checkFileWritable(options.getNextConfigOutputPath());
217
225
 
218
226
  ConfigDiff configDiff;
@@ -268,7 +276,7 @@ public class Runner
268
276
  {
269
277
  PreviewResult result;
270
278
  {
271
- ConfigSource config = loadYamlConfig(partialConfigPath);
279
+ ConfigSource config = loadConfig(partialConfigPath);
272
280
  ExecSession exec = newExecSession(config);
273
281
  try {
274
282
  PreviewExecutor preview = injector.getInstance(PreviewExecutor.class);
@@ -304,12 +312,40 @@ public class Runner
304
312
  }
305
313
  }
306
314
 
307
- private ConfigSource loadYamlConfig(String yamlPath)
315
+ private ConfigSource loadConfig(String path)
316
+ {
317
+ if (path.endsWith(".yml") || path.endsWith(".yaml")) {
318
+ return loadYamlConfig(path);
319
+ }
320
+ else if (path.endsWith(".yml.liquid") || path.endsWith(".yaml.liquid")) {
321
+ return loadLiquidYamlConfig(path);
322
+ }
323
+ else {
324
+ throw new ConfigException("Unknown file extension. Supported file extentions are .yml and .yml.liquid: "+path);
325
+ }
326
+ }
327
+
328
+ private ConfigSource loadYamlConfig(String path)
308
329
  {
309
330
  try {
310
- return injector.getInstance(ConfigLoader.class).fromYamlFile(new File(yamlPath));
331
+ return injector.getInstance(ConfigLoader.class).fromYamlFile(new File(path));
332
+ }
333
+ catch (IOException ex) {
334
+ throw new ConfigException(ex);
335
+ }
336
+ }
311
337
 
312
- } catch (IOException ex) {
338
+ private ConfigSource loadLiquidYamlConfig(String path)
339
+ {
340
+ LiquidTemplate helper = (LiquidTemplate) injector.getInstance(ScriptingContainer.class).runScriptlet("Embulk::Java::LiquidTemplateHelper.new");
341
+ try {
342
+ String source = Files.toString(new File(path), StandardCharsets.UTF_8);
343
+ String data = helper.render(source, ImmutableMap.<String,String>of());
344
+ try (ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))) {
345
+ return injector.getInstance(ConfigLoader.class).fromYaml(in);
346
+ }
347
+ }
348
+ catch (IOException ex) {
313
349
  throw new ConfigException(ex);
314
350
  }
315
351
  }