embulk 0.8.28-java → 0.8.29-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/build.gradle +1 -1
- data/embulk-cli/src/main/java/org/embulk/cli/EmbulkGlobalJRubyScriptingContainer.java +1 -1
- data/embulk-cli/src/main/java/org/embulk/cli/EmbulkRun.java +71 -73
- data/embulk-core/src/main/java/org/embulk/EmbulkRunner.java +30 -28
- data/embulk-core/src/main/java/org/embulk/EmbulkSetup.java +48 -4
- data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormatter.java +25 -2
- data/embulk-core/src/main/java/org/embulk/spi/time/TimestampParser.java +40 -4
- data/embulk-core/src/main/java/org/embulk/spi/util/DynamicColumnSetterFactory.java +3 -3
- data/embulk-core/src/main/java/org/embulk/spi/util/DynamicPageBuilder.java +1 -0
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.8.29.rst +14 -0
- data/lib/embulk/runner.rb +4 -12
- data/lib/embulk/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 455af0eb268193a9c0a81f20a6823da090ec8714
|
4
|
+
data.tar.gz: 5881f11ed75bbd8a0d7798635298db475be835e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c580a2b6e69a90b60c4b3ba61a2eafccaba9edee05c9b2dcb47567a3dadcafc2bece12753bfb6d1ba2c229cd9ab01a661b0a847cb0b1aa11087507095f051ea4
|
7
|
+
data.tar.gz: 7aa021e2a4f55fce2894c5bf3b394c1756a2d02e068a4517e032df24506f869d66f5ecb8ca73e85f1999f98301ad387cb980f7bf542812a6ee7e59d207f1acbd
|
data/build.gradle
CHANGED
@@ -178,7 +178,7 @@ public class EmbulkGlobalJRubyScriptingContainer
|
|
178
178
|
|
179
179
|
final Path locationPath;
|
180
180
|
try {
|
181
|
-
locationPath = Paths.get(locationUrl.toURI()
|
181
|
+
locationPath = Paths.get(locationUrl.toURI());
|
182
182
|
}
|
183
183
|
catch (URISyntaxException ex) {
|
184
184
|
throw new EmbulkCommandLineException("Invalid location: " + locationUrl.toString(), ex);
|
@@ -24,6 +24,8 @@ import org.embulk.cli.parse.OptionDefinition;
|
|
24
24
|
import org.joda.time.DateTime;
|
25
25
|
import org.joda.time.format.DateTimeFormat;
|
26
26
|
import org.joda.time.format.DateTimeFormatter;
|
27
|
+
import org.jruby.embed.LocalContextScope;
|
28
|
+
import org.jruby.embed.LocalVariableBehavior;
|
27
29
|
import org.jruby.embed.ScriptingContainer;
|
28
30
|
|
29
31
|
public class EmbulkRun
|
@@ -398,14 +400,14 @@ public class EmbulkRun
|
|
398
400
|
}
|
399
401
|
return 0;
|
400
402
|
case BUNDLE:
|
401
|
-
if (!
|
402
|
-
if (
|
403
|
+
if (!subcommandArguments.isEmpty() && subcommandArguments.get(0).equals("new")) {
|
404
|
+
if (subcommandArguments.size() != 2) {
|
403
405
|
printGeneralUsage(System.err);
|
404
406
|
System.err.println("");
|
405
407
|
System.err.println("Use `<command> --help` to see description of the commands.");
|
406
408
|
return 1;
|
407
409
|
}
|
408
|
-
newBundle(
|
410
|
+
newBundle(subcommandArguments.get(1), null);
|
409
411
|
System.err.println("'embulk bundle new' is deprecated. This will be removed in future release. Please use 'embulk mkbundle' instead.");
|
410
412
|
}
|
411
413
|
else {
|
@@ -413,24 +415,16 @@ public class EmbulkRun
|
|
413
415
|
}
|
414
416
|
return 0;
|
415
417
|
case GEM:
|
416
|
-
|
417
|
-
this.jrubyContainer.put("__internal_argv_java__", subcommandArguments);
|
418
|
-
this.jrubyContainer.runScriptlet("__internal_argv__ = Array.new(__internal_argv_java__)");
|
419
|
-
this.jrubyContainer.runScriptlet("Gem::GemRunner.new.run __internal_argv__");
|
420
|
-
this.jrubyContainer.remove("__internal_argv_java__");
|
418
|
+
callJRubyGem(subcommandArguments);
|
421
419
|
return 0;
|
422
420
|
case MKBUNDLE:
|
423
421
|
newBundle(commandLine.getArguments().get(0), commandLine.getBundlePath());
|
424
422
|
break;
|
425
423
|
case EXEC:
|
426
|
-
|
427
|
-
this.jrubyContainer.runScriptlet("__internal_argv__ = Array.new(__internal_argv_java__)");
|
428
|
-
this.jrubyContainer.runScriptlet("exec(*__internal_argv__)");
|
429
|
-
this.jrubyContainer.remove("__internal_argv_java__");
|
424
|
+
callJRubyExec(subcommandArguments);
|
430
425
|
return 127;
|
431
426
|
case IRB:
|
432
|
-
|
433
|
-
this.jrubyContainer.runScriptlet("IRB.start");
|
427
|
+
callJRubyIRB();
|
434
428
|
return 0;
|
435
429
|
case RUN:
|
436
430
|
case CLEANUP:
|
@@ -446,14 +440,18 @@ public class EmbulkRun
|
|
446
440
|
|
447
441
|
// NOTE: When it was in Ruby ""require 'json'" was required.
|
448
442
|
|
449
|
-
|
450
|
-
setupClasspaths(commandLine.getClasspath());
|
443
|
+
// NOTE: $LOAD_PATH and $CLASSPATH are set in |EmbulkSetup|.
|
451
444
|
|
452
445
|
// call |EmbulkSetup.setup| after setup_classpaths to allow users to overwrite
|
453
446
|
// embulk classes
|
454
447
|
// NOTE: |EmbulkSetup.setup| returns |EmbulkEmbed| while it stores Ruby |Embulk::EmbulkRunner(EmbulkEmbed)|
|
455
448
|
// into Ruby |Embulk::Runner|.
|
456
|
-
final EmbulkRunner runner = EmbulkSetup.setup(
|
449
|
+
final EmbulkRunner runner = EmbulkSetup.setup(
|
450
|
+
commandLine.getSystemConfig(),
|
451
|
+
commandLine.getLoadPath(),
|
452
|
+
commandLine.getLoad(),
|
453
|
+
commandLine.getClasspath(),
|
454
|
+
this.jrubyContainer);
|
457
455
|
|
458
456
|
final Path configDiffPath =
|
459
457
|
(commandLine.getConfigDiff() == null ? null : Paths.get(commandLine.getConfigDiff()));
|
@@ -490,12 +488,7 @@ public class EmbulkRun
|
|
490
488
|
|
491
489
|
private int newBundle(final String pathString, final String bundlePath)
|
492
490
|
{
|
493
|
-
this.jrubyContainer.runScriptlet("require 'embulk'");
|
494
|
-
|
495
491
|
final Path path = Paths.get(pathString);
|
496
|
-
this.jrubyContainer.runScriptlet("require 'fileutils'");
|
497
|
-
this.jrubyContainer.runScriptlet("require 'rubygems/gem_runner'");
|
498
|
-
|
499
492
|
if (Files.exists(path)) {
|
500
493
|
System.err.println("'" + pathString + "' already exists.");
|
501
494
|
return 1;
|
@@ -511,16 +504,19 @@ public class EmbulkRun
|
|
511
504
|
}
|
512
505
|
boolean success = false;
|
513
506
|
try {
|
507
|
+
// TODO: Rewrite this part in Java.
|
508
|
+
final ScriptingContainer localJRubyContainer = createLocalJRubyScriptingContainer();
|
509
|
+
localJRubyContainer.runScriptlet("require 'embulk'");
|
510
|
+
localJRubyContainer.runScriptlet("require 'fileutils'");
|
511
|
+
localJRubyContainer.runScriptlet("require 'rubygems/gem_runner'");
|
512
|
+
|
514
513
|
// copy embulk/data/bundle/ contents
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
514
|
+
localJRubyContainer.runScriptlet("require 'embulk/data/package_data'");
|
515
|
+
localJRubyContainer.put("__internal_path__", pathString);
|
516
|
+
localJRubyContainer.runScriptlet("pkg = Embulk::PackageData.new('bundle', __internal_path__)");
|
517
|
+
localJRubyContainer.remove("__internal_path__");
|
518
|
+
localJRubyContainer.runScriptlet("%w[Gemfile .ruby-version .bundle/config embulk/input/example.rb embulk/output/example.rb embulk/filter/example.rb].each { |file| pkg.cp(file, file) }");
|
520
519
|
// run the first bundle-install
|
521
|
-
final ArrayList<String> bundlerArguments = new ArrayList<String>();
|
522
|
-
bundlerArguments.add("install");
|
523
|
-
bundlerArguments.add("--path");
|
524
520
|
runBundler(Arrays.asList("install", "--path", bundlePath != null ? bundlePath : "."), path);
|
525
521
|
success = true;
|
526
522
|
}
|
@@ -570,26 +566,26 @@ public class EmbulkRun
|
|
570
566
|
|
571
567
|
private void runBundler(final List<String> arguments, final Path path)
|
572
568
|
{
|
573
|
-
|
569
|
+
final ScriptingContainer localJRubyContainer = createLocalJRubyScriptingContainer();
|
570
|
+
localJRubyContainer.runScriptlet("require 'bundler'"); // bundler is included in embulk-core.jar
|
574
571
|
|
575
572
|
// this hack is necessary to make --help working
|
576
|
-
|
577
|
-
|
573
|
+
localJRubyContainer.runScriptlet("Bundler.define_singleton_method(:which_orig, Bundler.method(:which))");
|
574
|
+
localJRubyContainer.runScriptlet("Bundler.define_singleton_method(:which) { |executable| (executable == 'man' ? false : which_orig(executable)) }");
|
578
575
|
|
579
|
-
|
580
|
-
|
576
|
+
localJRubyContainer.runScriptlet("require 'bundler/friendly_errors'");
|
577
|
+
localJRubyContainer.runScriptlet("require 'bundler/cli'");
|
581
578
|
|
582
|
-
|
583
|
-
this.jrubyContainer.runScriptlet("__internal_argv__ = Array.new(__internal_argv_java__)");
|
579
|
+
localJRubyContainer.put("__internal_argv_java__", arguments);
|
584
580
|
if (path == null) {
|
585
|
-
|
581
|
+
localJRubyContainer.runScriptlet("Bundler.with_friendly_errors { Bundler::CLI.start(Array.new(__internal_argv_java__), debug: true) }");
|
586
582
|
}
|
587
583
|
else {
|
588
|
-
|
589
|
-
|
590
|
-
|
584
|
+
localJRubyContainer.put("__internal_working_dir__", path.toString());
|
585
|
+
localJRubyContainer.runScriptlet("Dir.chdir(__internal_working_dir__) { Bundler.with_friendly_errors { Bundler::CLI.start(__internal_argv__, debug: true) } }");
|
586
|
+
localJRubyContainer.remove("__internal_working_dir__");
|
591
587
|
}
|
592
|
-
|
588
|
+
localJRubyContainer.remove("__internal_argv_java__");
|
593
589
|
}
|
594
590
|
|
595
591
|
private void addPluginLoadOptionDefinitions(final EmbulkCommandLineParser.Builder parserBuilder)
|
@@ -700,37 +696,6 @@ public class EmbulkRun
|
|
700
696
|
}));
|
701
697
|
}
|
702
698
|
|
703
|
-
private void setupLoadPaths(final List<String> loadPaths, final List<String> pluginPaths)
|
704
|
-
{
|
705
|
-
// first $LOAD_PATH has highet priority. later load_paths should have highest priority.
|
706
|
-
for (final String loadPath : loadPaths) {
|
707
|
-
// ruby script directory (use unshift to make it highest priority)
|
708
|
-
this.jrubyContainer.put("__internal_load_path__", loadPath);
|
709
|
-
this.jrubyContainer.runScriptlet("$LOAD_PATH.unshift File.expand_path(__internal_load_path__)");
|
710
|
-
this.jrubyContainer.remove("__internal_load_path__");
|
711
|
-
}
|
712
|
-
|
713
|
-
// # Gem::StubSpecification is an internal API that seems chainging often.
|
714
|
-
// # Gem::Specification.add_spec is deprecated also. Therefore, here makes
|
715
|
-
// # -L <path> option alias of -I <path>/lib by assuming that *.gemspec file
|
716
|
-
// # always has require_paths = ["lib"].
|
717
|
-
for (final String pluginPath : pluginPaths) {
|
718
|
-
this.jrubyContainer.put("__internal_plugin_path__", pluginPath);
|
719
|
-
this.jrubyContainer.runScriptlet("$LOAD_PATH.unshift File.expand_path(File.join(__internal_plugin_path__, 'lib')");
|
720
|
-
this.jrubyContainer.remove("__internal_plugin_path__");
|
721
|
-
}
|
722
|
-
}
|
723
|
-
|
724
|
-
private void setupClasspaths(final List<String> classpaths)
|
725
|
-
{
|
726
|
-
for (final String classpath : classpaths) {
|
727
|
-
this.jrubyContainer.put("__internal_classpath__", classpath);
|
728
|
-
// $CLASSPATH object doesn't have concat method
|
729
|
-
this.jrubyContainer.runScriptlet("$CLASSPATH << __internal_classpath__");
|
730
|
-
this.jrubyContainer.remove("__internal_classpath__");
|
731
|
-
}
|
732
|
-
}
|
733
|
-
|
734
699
|
private void printGeneralUsage(final PrintStream out)
|
735
700
|
{
|
736
701
|
final String gemHomeEnv = System.getenv("GEM_HOME");
|
@@ -764,6 +729,39 @@ public class EmbulkRun
|
|
764
729
|
out.println(now + ": Embulk v" + this.embulkVersion);
|
765
730
|
}
|
766
731
|
|
732
|
+
// TODO: Check if it is required to process JRuby options.
|
733
|
+
private ScriptingContainer createLocalJRubyScriptingContainer()
|
734
|
+
{
|
735
|
+
// Not |LocalContextScope.SINGLETON| to narrow down considerations.
|
736
|
+
final ScriptingContainer localJRubyContainer =
|
737
|
+
new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior.PERSISTENT);
|
738
|
+
return localJRubyContainer;
|
739
|
+
}
|
740
|
+
|
741
|
+
private void callJRubyGem(final List<String> subcommandArguments)
|
742
|
+
{
|
743
|
+
final ScriptingContainer localJRubyContainer = createLocalJRubyScriptingContainer();
|
744
|
+
localJRubyContainer.runScriptlet("require 'rubygems/gem_runner'");
|
745
|
+
localJRubyContainer.put("__internal_argv_java__", subcommandArguments);
|
746
|
+
localJRubyContainer.runScriptlet("Gem::GemRunner.new.run Array.new(__internal_argv_java__)");
|
747
|
+
localJRubyContainer.remove("__internal_argv_java__");
|
748
|
+
}
|
749
|
+
|
750
|
+
private void callJRubyExec(final List<String> subcommandArguments)
|
751
|
+
{
|
752
|
+
final ScriptingContainer localJRubyContainer = createLocalJRubyScriptingContainer();
|
753
|
+
localJRubyContainer.put("__internal_argv_java__", subcommandArguments);
|
754
|
+
localJRubyContainer.runScriptlet("exec(*Array.new(__internal_argv_java__))");
|
755
|
+
localJRubyContainer.remove("__internal_argv_java__");
|
756
|
+
}
|
757
|
+
|
758
|
+
private void callJRubyIRB()
|
759
|
+
{
|
760
|
+
final ScriptingContainer localJRubyContainer = createLocalJRubyScriptingContainer();
|
761
|
+
localJRubyContainer.runScriptlet("require 'irb'");
|
762
|
+
localJRubyContainer.runScriptlet("IRB.start");
|
763
|
+
}
|
764
|
+
|
767
765
|
private final String embulkVersion;
|
768
766
|
private final ScriptingContainer jrubyContainer;
|
769
767
|
}
|
@@ -7,6 +7,7 @@ import java.nio.file.Files;
|
|
7
7
|
import java.nio.file.Path;
|
8
8
|
import java.nio.file.Paths;
|
9
9
|
import java.nio.file.StandardOpenOption;
|
10
|
+
import java.util.Collections;
|
10
11
|
import java.util.Map;
|
11
12
|
import java.util.regex.Pattern;
|
12
13
|
import org.embulk.command.PreviewPrinter;
|
@@ -21,7 +22,8 @@ import org.embulk.exec.ExecutionResult;
|
|
21
22
|
import org.embulk.exec.PreviewResult;
|
22
23
|
import org.embulk.exec.ResumeState;
|
23
24
|
import org.embulk.exec.TransactionStage;
|
24
|
-
import org.jruby.
|
25
|
+
import org.jruby.embed.LocalContextScope;
|
26
|
+
import org.jruby.embed.LocalVariableBehavior;
|
25
27
|
import org.jruby.embed.ScriptingContainer;
|
26
28
|
import org.slf4j.Logger;
|
27
29
|
import org.slf4j.LoggerFactory;
|
@@ -35,11 +37,10 @@ import org.slf4j.LoggerFactory;
|
|
35
37
|
public class EmbulkRunner
|
36
38
|
{
|
37
39
|
// |EmbulkSetup.setup| initializes:
|
38
|
-
// new EmbulkRunner(embed
|
39
|
-
public EmbulkRunner(final EmbulkEmbed embed
|
40
|
+
// new EmbulkRunner(embed)
|
41
|
+
public EmbulkRunner(final EmbulkEmbed embed)
|
40
42
|
{
|
41
43
|
this.embed = embed; // org.embulk.EmbulkEmbed
|
42
|
-
this.globalJRubyContainer = globalJRubyContainer;
|
43
44
|
}
|
44
45
|
|
45
46
|
/**
|
@@ -54,8 +55,7 @@ public class EmbulkRunner
|
|
54
55
|
// in Ruby Embulk::EmbulkRunner.
|
55
56
|
final ConfigSource configSource;
|
56
57
|
try {
|
57
|
-
configSource = readConfig(
|
58
|
-
configFilePath, new RubyHash(this.globalJRubyContainer.getProvider().getRuntime()), null);
|
58
|
+
configSource = readConfig(configFilePath, Collections.<String, Object>emptyMap(), null);
|
59
59
|
}
|
60
60
|
catch (IOException ex) {
|
61
61
|
throw new RuntimeException(ex);
|
@@ -108,8 +108,7 @@ public class EmbulkRunner
|
|
108
108
|
// in Ruby Embulk::EmbulkRunner.
|
109
109
|
final ConfigSource configSource;
|
110
110
|
try {
|
111
|
-
configSource = readConfig(
|
112
|
-
configFilePath, new RubyHash(this.globalJRubyContainer.getProvider().getRuntime()), null);
|
111
|
+
configSource = readConfig(configFilePath, Collections.<String, Object>emptyMap(), null);
|
113
112
|
}
|
114
113
|
catch (IOException ex) {
|
115
114
|
throw new RuntimeException(ex);
|
@@ -164,8 +163,7 @@ public class EmbulkRunner
|
|
164
163
|
// in Ruby Embulk::EmbulkRunner.
|
165
164
|
final ConfigSource configSource;
|
166
165
|
try {
|
167
|
-
configSource = readConfig(
|
168
|
-
configFilePath, new RubyHash(this.globalJRubyContainer.getProvider().getRuntime()), null);
|
166
|
+
configSource = readConfig(configFilePath, Collections.<String, Object>emptyMap(), null);
|
169
167
|
}
|
170
168
|
catch (IOException ex) {
|
171
169
|
throw new RuntimeException(ex);
|
@@ -289,9 +287,8 @@ public class EmbulkRunner
|
|
289
287
|
|
290
288
|
final ConfigSource configSource;
|
291
289
|
if (configDiffPath != null && Files.size(configDiffPath) > 0L) {
|
292
|
-
|
293
|
-
readConfig(configDiffPath,
|
294
|
-
configSource = originalConfigSource.merge(lastConfigDiff);
|
290
|
+
configSource = originalConfigSource.merge(
|
291
|
+
readConfig(configDiffPath, Collections.<String, Object>emptyMap(), null));
|
295
292
|
}
|
296
293
|
else {
|
297
294
|
configSource = originalConfigSource;
|
@@ -391,7 +388,7 @@ public class EmbulkRunner
|
|
391
388
|
|
392
389
|
private ConfigSource readConfig(
|
393
390
|
final Path configFilePath,
|
394
|
-
final
|
391
|
+
final Map<String, Object> templateParams,
|
395
392
|
final String templateIncludePath)
|
396
393
|
throws IOException
|
397
394
|
{
|
@@ -422,28 +419,34 @@ public class EmbulkRunner
|
|
422
419
|
|
423
420
|
private String runLiquid(
|
424
421
|
final String templateSource,
|
425
|
-
final
|
422
|
+
final Map<String, Object> templateParams,
|
426
423
|
final String templateIncludePath)
|
427
424
|
{
|
428
|
-
|
425
|
+
// TODO: Check if it is required to process JRuby options.
|
426
|
+
// Not |LocalContextScope.SINGLETON| to narrow down considerations.
|
427
|
+
final ScriptingContainer localJRubyContainer =
|
428
|
+
new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior.PERSISTENT);
|
429
429
|
|
430
|
-
|
431
|
-
|
432
|
-
|
430
|
+
localJRubyContainer.runScriptlet("require 'liquid'");
|
431
|
+
|
432
|
+
localJRubyContainer.put("__internal_liquid_template_source__", templateSource);
|
433
|
+
localJRubyContainer.runScriptlet("template = Liquid::Template.parse(__internal_liquid_template_source__, :error_mode => :strict)");
|
434
|
+
localJRubyContainer.remove("__internal_liquid_template_source__");
|
433
435
|
|
434
436
|
if (templateIncludePath != null) {
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
437
|
+
localJRubyContainer.put("__internal_liquid_template_include_path_java__", templateIncludePath);
|
438
|
+
localJRubyContainer.runScriptlet("__internal_liquid_template_include_path__ = File.expand_path(__internal_liquid_template_include_path_java__ || File.dirname(config)) unless __internal_liquid_template_include_path_java__ == false");
|
439
|
+
localJRubyContainer.runScriptlet("template.registers[:file_system] = Liquid::LocalFileSystem.new(__internal_liquid_template_include_path__, \"_%s.yml.liquid\")");
|
440
|
+
localJRubyContainer.remove("__internal_liquid_template_include_path__");
|
439
441
|
}
|
440
442
|
|
441
|
-
|
442
|
-
|
443
|
-
|
443
|
+
// TODO: Convert |templateParams| recursively to Ruby's Hash.
|
444
|
+
localJRubyContainer.put("__internal_liquid_template_params__", templateParams);
|
445
|
+
localJRubyContainer.runScriptlet("__internal_liquid_template_data__ = { 'env' => ENV.to_h }.merge(__internal_liquid_template_params__)");
|
446
|
+
localJRubyContainer.remove("__internal_liquid_template_params__");
|
444
447
|
|
445
448
|
final Object renderedObject =
|
446
|
-
|
449
|
+
localJRubyContainer.runScriptlet("template.render(__internal_liquid_template_data__)");
|
447
450
|
return renderedObject.toString();
|
448
451
|
}
|
449
452
|
|
@@ -522,5 +525,4 @@ public class EmbulkRunner
|
|
522
525
|
private final Pattern EXT_YAML_LIQUID = Pattern.compile(".*\\.ya?ml\\.liquid$");
|
523
526
|
|
524
527
|
private final EmbulkEmbed embed;
|
525
|
-
private final ScriptingContainer globalJRubyContainer;
|
526
528
|
}
|
@@ -2,7 +2,9 @@ package org.embulk;
|
|
2
2
|
|
3
3
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
4
4
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
5
|
+
import java.util.Collections;
|
5
6
|
import java.util.HashMap;
|
7
|
+
import java.util.List;
|
6
8
|
import java.util.Map;
|
7
9
|
import org.embulk.config.ConfigSource;
|
8
10
|
import org.jruby.embed.LocalContextScope;
|
@@ -24,11 +26,18 @@ public class EmbulkSetup
|
|
24
26
|
// The local variable should be persistent so that local variables are set through ScriptingContainer.put.
|
25
27
|
final ScriptingContainer globalJRubyContainer =
|
26
28
|
new ScriptingContainer(LocalContextScope.SINGLETON, LocalVariableBehavior.PERSISTENT);
|
27
|
-
return setup(systemConfigGiven,
|
29
|
+
return setup(systemConfigGiven,
|
30
|
+
Collections.<String>emptyList(),
|
31
|
+
Collections.<String>emptyList(),
|
32
|
+
Collections.<String>emptyList(),
|
33
|
+
globalJRubyContainer);
|
28
34
|
}
|
29
35
|
|
30
36
|
public static EmbulkRunner setup(
|
31
37
|
final Map<String, Object> systemConfigGiven,
|
38
|
+
final List<String> loadPaths,
|
39
|
+
final List<String> pluginPaths,
|
40
|
+
final List<String> classpaths,
|
32
41
|
final ScriptingContainer globalJRubyContainer)
|
33
42
|
{
|
34
43
|
// NOTE: When it was in Ruby "require 'json'" was required to format the system config into a JSON string.
|
@@ -57,14 +66,49 @@ public class EmbulkSetup
|
|
57
66
|
bootstrap.setSystemConfig(systemConfig);
|
58
67
|
final EmbulkEmbed embed = bootstrap.initialize(); // see embulk-core/src/main/java/org/embulk/jruby/JRubyScriptingModule.
|
59
68
|
|
69
|
+
setupLoadPaths(loadPaths, pluginPaths, globalJRubyContainer);
|
70
|
+
setupClasspaths(classpaths, globalJRubyContainer);
|
71
|
+
|
60
72
|
// see also embulk/java/bootstrap.rb loaded by JRubyScriptingModule
|
61
73
|
globalJRubyContainer.runScriptlet("module Embulk; end");
|
62
74
|
globalJRubyContainer.put("__internal_embulk_setup_embed__", embed);
|
63
|
-
globalJRubyContainer.put("__internal_embulk_setup_global_jruby_container__", globalJRubyContainer);
|
64
75
|
globalJRubyContainer.runScriptlet("Embulk.const_set :Runner, Embulk::EmbulkRunner.new(__internal_embulk_setup_embed__)");
|
65
|
-
globalJRubyContainer.remove("__internal_embulk_setup_global_jruby_container__");
|
66
76
|
globalJRubyContainer.remove("__internal_embulk_setup_embed__");
|
67
77
|
|
68
|
-
return new EmbulkRunner(embed
|
78
|
+
return new EmbulkRunner(embed);
|
79
|
+
}
|
80
|
+
|
81
|
+
private static void setupLoadPaths(
|
82
|
+
final List<String> loadPaths,
|
83
|
+
final List<String> pluginPaths,
|
84
|
+
final ScriptingContainer globalJRubyContainer)
|
85
|
+
{
|
86
|
+
// first $LOAD_PATH has highet priority. later load_paths should have highest priority.
|
87
|
+
for (final String loadPath : loadPaths) {
|
88
|
+
// ruby script directory (use unshift to make it highest priority)
|
89
|
+
globalJRubyContainer.put("__internal_load_path__", loadPath);
|
90
|
+
globalJRubyContainer.runScriptlet("$LOAD_PATH.unshift File.expand_path(__internal_load_path__)");
|
91
|
+
globalJRubyContainer.remove("__internal_load_path__");
|
92
|
+
}
|
93
|
+
|
94
|
+
// # Gem::StubSpecification is an internal API that seems chainging often.
|
95
|
+
// # Gem::Specification.add_spec is deprecated also. Therefore, here makes
|
96
|
+
// # -L <path> option alias of -I <path>/lib by assuming that *.gemspec file
|
97
|
+
// # always has require_paths = ["lib"].
|
98
|
+
for (final String pluginPath : pluginPaths) {
|
99
|
+
globalJRubyContainer.put("__internal_plugin_path__", pluginPath);
|
100
|
+
globalJRubyContainer.runScriptlet("$LOAD_PATH.unshift File.expand_path(File.join(__internal_plugin_path__, 'lib')");
|
101
|
+
globalJRubyContainer.remove("__internal_plugin_path__");
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
private static void setupClasspaths(final List<String> classpaths, final ScriptingContainer globalJRubyContainer)
|
106
|
+
{
|
107
|
+
for (final String classpath : classpaths) {
|
108
|
+
globalJRubyContainer.put("__internal_classpath__", classpath);
|
109
|
+
// $CLASSPATH object doesn't have concat method
|
110
|
+
globalJRubyContainer.runScriptlet("$CLASSPATH << __internal_classpath__");
|
111
|
+
globalJRubyContainer.remove("__internal_classpath__");
|
112
|
+
}
|
69
113
|
}
|
70
114
|
}
|
@@ -22,6 +22,7 @@ public class TimestampFormatter
|
|
22
22
|
public DateTimeZone getTimeZone();
|
23
23
|
|
24
24
|
@ConfigInject
|
25
|
+
@Deprecated
|
25
26
|
public ScriptingContainer getJRuby();
|
26
27
|
}
|
27
28
|
|
@@ -36,6 +37,7 @@ public class TimestampFormatter
|
|
36
37
|
public String getDefaultTimestampFormat();
|
37
38
|
|
38
39
|
@ConfigInject
|
40
|
+
@Deprecated
|
39
41
|
public ScriptingContainer getJRuby();
|
40
42
|
}
|
41
43
|
|
@@ -56,12 +58,20 @@ public class TimestampFormatter
|
|
56
58
|
@Deprecated
|
57
59
|
public TimestampFormatter(String format, FormatterTask task)
|
58
60
|
{
|
59
|
-
this(
|
61
|
+
this(format, task.getTimeZone());
|
62
|
+
// NOTE: Its deprecation is not actually from ScriptingContainer, though.
|
63
|
+
// TODO: Notify users about deprecated calls through the notification reporter.
|
64
|
+
System.err.println("[WARN] A plugin uses a deprecated constructor of org.embulk.spi.time.TimestampFormatter.");
|
65
|
+
System.err.println("[WARN] Please tell the plugin developer to stop using the constructor, or report this to:");
|
66
|
+
System.err.println("[WARN] https://github.com/embulk/embulk/issues/745");
|
67
|
+
for (final StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
|
68
|
+
System.err.println("[WARN] " + stackTrace.toString());
|
69
|
+
}
|
60
70
|
}
|
61
71
|
|
62
72
|
public TimestampFormatter(Task task, Optional<? extends TimestampColumnOption> columnOption)
|
63
73
|
{
|
64
|
-
this(
|
74
|
+
this(
|
65
75
|
columnOption.isPresent() ?
|
66
76
|
columnOption.get().getFormat().or(task.getDefaultTimestampFormat())
|
67
77
|
: task.getDefaultTimestampFormat(),
|
@@ -70,7 +80,20 @@ public class TimestampFormatter
|
|
70
80
|
: task.getDefaultTimeZone());
|
71
81
|
}
|
72
82
|
|
83
|
+
@Deprecated
|
73
84
|
public TimestampFormatter(ScriptingContainer jruby, String format, DateTimeZone timeZone)
|
85
|
+
{
|
86
|
+
this(format, timeZone);
|
87
|
+
// TODO: Notify users about deprecated calls through the notification reporter.
|
88
|
+
System.err.println("[WARN] A plugin uses a deprecated constructor of org.embulk.spi.time.TimestampFormatter.");
|
89
|
+
System.err.println("[WARN] Please tell the plugin developer to stop using the constructor, or report this to:");
|
90
|
+
System.err.println("[WARN] https://github.com/embulk/embulk/issues/745");
|
91
|
+
for (final StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
|
92
|
+
System.err.println("[WARN] " + stackTrace.toString());
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
public TimestampFormatter(final String format, final DateTimeZone timeZone)
|
74
97
|
{
|
75
98
|
this.timeZone = timeZone;
|
76
99
|
this.dateFormat = new RubyDateFormat(format, Locale.ENGLISH, true);
|
@@ -32,6 +32,7 @@ public class TimestampParser
|
|
32
32
|
public DateTimeZone getDefaultTimeZone();
|
33
33
|
|
34
34
|
@ConfigInject
|
35
|
+
@Deprecated
|
35
36
|
public ScriptingContainer getJRuby();
|
36
37
|
}
|
37
38
|
|
@@ -50,6 +51,7 @@ public class TimestampParser
|
|
50
51
|
public String getDefaultDate();
|
51
52
|
|
52
53
|
@ConfigInject
|
54
|
+
@Deprecated
|
53
55
|
public ScriptingContainer getJRuby();
|
54
56
|
}
|
55
57
|
|
@@ -77,30 +79,64 @@ public class TimestampParser
|
|
77
79
|
@Deprecated
|
78
80
|
public TimestampParser(String format, ParserTask task)
|
79
81
|
{
|
80
|
-
this(
|
82
|
+
this(format, task.getDefaultTimeZone());
|
83
|
+
// NOTE: Its deprecation is not actually from ScriptingContainer, though.
|
84
|
+
// TODO: Notify users about deprecated calls through the notification reporter.
|
85
|
+
System.err.println("[WARN] A plugin uses a deprecated constructor of org.embulk.spi.time.TimestampFormatter.");
|
86
|
+
System.err.println("[WARN] Please tell the plugin developer to stop using the constructor, or report this to:");
|
87
|
+
System.err.println("[WARN] https://github.com/embulk/embulk/issues/745");
|
88
|
+
for (final StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
|
89
|
+
System.err.println("[WARN] " + stackTrace.toString());
|
90
|
+
}
|
81
91
|
}
|
82
92
|
|
83
93
|
@VisibleForTesting
|
84
94
|
static TimestampParser createTimestampParserForTesting(Task task)
|
85
95
|
|
86
96
|
{
|
87
|
-
return new TimestampParser(task.
|
97
|
+
return new TimestampParser(task.getDefaultTimestampFormat(), task.getDefaultTimeZone(), task.getDefaultDate());
|
88
98
|
}
|
89
99
|
|
90
100
|
public TimestampParser(Task task, TimestampColumnOption columnOption)
|
91
101
|
{
|
92
|
-
this(
|
102
|
+
this(
|
93
103
|
columnOption.getFormat().or(task.getDefaultTimestampFormat()),
|
94
104
|
columnOption.getTimeZone().or(task.getDefaultTimeZone()),
|
95
105
|
columnOption.getDate().or(task.getDefaultDate()));
|
96
106
|
}
|
97
107
|
|
108
|
+
@Deprecated
|
98
109
|
public TimestampParser(ScriptingContainer jruby, String format, DateTimeZone defaultTimeZone)
|
99
110
|
{
|
100
|
-
this(
|
111
|
+
this(format, defaultTimeZone);
|
112
|
+
// TODO: Notify users about deprecated calls through the notification reporter.
|
113
|
+
System.err.println("[WARN] A plugin uses a deprecated constructor of org.embulk.spi.time.TimestampFormatter.");
|
114
|
+
System.err.println("[WARN] Please tell the plugin developer to stop using the constructor, or report this to:");
|
115
|
+
System.err.println("[WARN] https://github.com/embulk/embulk/issues/745");
|
116
|
+
for (final StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
|
117
|
+
System.err.println("[WARN] " + stackTrace.toString());
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
public TimestampParser(String format, DateTimeZone defaultTimeZone)
|
122
|
+
{
|
123
|
+
this(format, defaultTimeZone, "1970-01-01");
|
101
124
|
}
|
102
125
|
|
126
|
+
@Deprecated
|
103
127
|
public TimestampParser(ScriptingContainer jruby, String format, DateTimeZone defaultTimeZone, String defaultDate)
|
128
|
+
{
|
129
|
+
this(format, defaultTimeZone, defaultDate);
|
130
|
+
// TODO: Notify users about deprecated calls through the notification reporter.
|
131
|
+
System.err.println("[WARN] A plugin uses a deprecated constructor of org.embulk.spi.time.TimestampFormatter.");
|
132
|
+
System.err.println("[WARN] Please tell the plugin developer to stop using the constructor, or report this to:");
|
133
|
+
System.err.println("[WARN] https://github.com/embulk/embulk/issues/745");
|
134
|
+
for (final StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
|
135
|
+
System.err.println("[WARN] " + stackTrace.toString());
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
public TimestampParser(final String format, final DateTimeZone defaultTimeZone, final String defaultDate)
|
104
140
|
{
|
105
141
|
// TODO get default current time from ExecTask.getExecTimestamp
|
106
142
|
this.format = format;
|
@@ -52,16 +52,16 @@ public class DynamicColumnSetterFactory
|
|
52
52
|
} else if (type instanceof DoubleType) {
|
53
53
|
return new DoubleColumnSetter(pageBuilder, column, defaultValue);
|
54
54
|
} else if (type instanceof StringType) {
|
55
|
-
TimestampFormatter formatter = new TimestampFormatter(
|
55
|
+
TimestampFormatter formatter = new TimestampFormatter(
|
56
56
|
getTimestampFormat(column).getFormat(), getTimeZone(column));
|
57
57
|
return new StringColumnSetter(pageBuilder, column, defaultValue, formatter);
|
58
58
|
} else if (type instanceof TimestampType) {
|
59
59
|
// TODO use flexible time format like Ruby's Time.parse
|
60
|
-
TimestampParser parser = new TimestampParser(
|
60
|
+
TimestampParser parser = new TimestampParser(
|
61
61
|
getTimestampFormat(column).getFormat(), getTimeZone(column));
|
62
62
|
return new TimestampColumnSetter(pageBuilder, column, defaultValue, parser);
|
63
63
|
} else if (type instanceof JsonType) {
|
64
|
-
TimestampFormatter formatter = new TimestampFormatter(
|
64
|
+
TimestampFormatter formatter = new TimestampFormatter(
|
65
65
|
getTimestampFormat(column).getFormat(), getTimeZone(column));
|
66
66
|
return new JsonColumnSetter(pageBuilder, column, defaultValue, formatter);
|
67
67
|
}
|
data/embulk-docs/src/release.rst
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
Release 0.8.29
|
2
|
+
==================================
|
3
|
+
|
4
|
+
General Changes
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Deprecate Timestamp-related methods using JRuby ScriptingContainer. [#744]
|
8
|
+
* Reduce usage of the global (Singleton) JRuby instance [#747]
|
9
|
+
* Fix how to get the CodeSource location on Windows. [#751]
|
10
|
+
* Fix the broken "bundle" subcommand rewritten in Java. [#752]
|
11
|
+
|
12
|
+
Release Date
|
13
|
+
------------------
|
14
|
+
2017-08-02
|
data/lib/embulk/runner.rb
CHANGED
@@ -4,22 +4,14 @@ module Embulk
|
|
4
4
|
# Runner = EmbulkRunner.new
|
5
5
|
|
6
6
|
class EmbulkRunner
|
7
|
-
def initialize(embed
|
7
|
+
def initialize(embed)
|
8
8
|
@embed = embed # org.embulk.EmbulkEmbed
|
9
|
-
if jruby_container
|
10
|
-
@jruby_container = jruby_container
|
11
|
-
else
|
12
|
-
# The ScriptingContainer instance below is the same JRuby instance with the one running this runner.rb itself
|
13
|
-
# as it's LocalContextScope.SINGLETON.
|
14
|
-
@jruby_container = Java::org.jruby.embed.ScriptingContainer.new(
|
15
|
-
Java::org.jruby.embed.LocalContextScope::SINGLETON, Java::org.jruby.embed.LocalVariableBehavior::PERSISTENT)
|
16
|
-
end
|
17
9
|
end
|
18
10
|
|
19
11
|
def guess(config, options={})
|
20
12
|
output_path =
|
21
13
|
(options[:next_config_output_path] ? Java::java.lang.String.new(options[:next_config_output_path]) : nil)
|
22
|
-
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed
|
14
|
+
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed)
|
23
15
|
|
24
16
|
case config
|
25
17
|
when String
|
@@ -33,7 +25,7 @@ module Embulk
|
|
33
25
|
|
34
26
|
def preview(config, options={})
|
35
27
|
format = (options[:format] ? Java::java.lang.String.new(options[:format]) : nil)
|
36
|
-
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed
|
28
|
+
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed)
|
37
29
|
|
38
30
|
case config
|
39
31
|
when String
|
@@ -52,7 +44,7 @@ module Embulk
|
|
52
44
|
(options[:next_config_output_path] ? Java::java.lang.String.new(options[:next_config_output_path]) : nil)
|
53
45
|
resume_state_path =
|
54
46
|
(options[:resume_state_path] ? Java::java.lang.String.new(options[:resume_state_path]) : nil)
|
55
|
-
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed
|
47
|
+
embulk_runner_java = Java::org.embulk.EmbulkRunner.new(@embed)
|
56
48
|
|
57
49
|
case config
|
58
50
|
when String
|
data/lib/embulk/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Embulk
|
4
4
|
@@warned = false
|
5
5
|
|
6
|
-
VERSION_INTERNAL = '0.8.
|
6
|
+
VERSION_INTERNAL = '0.8.29'
|
7
7
|
|
8
8
|
DEPRECATED_MESSAGE = 'Embulk::VERSION in (J)Ruby is deprecated. Use org.embulk.EmbulkVersion::VERSION instead. If this message is from a plugin, please tell this to the author of the plugin!'
|
9
9
|
def self.const_missing(name)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.29
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -155,10 +155,10 @@ files:
|
|
155
155
|
- classpath/commons-compress-1.10.jar
|
156
156
|
- classpath/commons-lang-2.4.jar
|
157
157
|
- classpath/commons-lang3-3.4.jar
|
158
|
-
- classpath/embulk-cli-0.8.
|
159
|
-
- classpath/embulk-core-0.8.
|
160
|
-
- classpath/embulk-jruby-strptime-0.8.
|
161
|
-
- classpath/embulk-standards-0.8.
|
158
|
+
- classpath/embulk-cli-0.8.29.jar
|
159
|
+
- classpath/embulk-core-0.8.29.jar
|
160
|
+
- classpath/embulk-jruby-strptime-0.8.29.jar
|
161
|
+
- classpath/embulk-standards-0.8.29.jar
|
162
162
|
- classpath/guava-18.0.jar
|
163
163
|
- classpath/guice-4.0.jar
|
164
164
|
- classpath/guice-bootstrap-0.1.1.jar
|
@@ -558,6 +558,7 @@ files:
|
|
558
558
|
- embulk-docs/src/release/release-0.8.26.rst
|
559
559
|
- embulk-docs/src/release/release-0.8.27.rst
|
560
560
|
- embulk-docs/src/release/release-0.8.28.rst
|
561
|
+
- embulk-docs/src/release/release-0.8.29.rst
|
561
562
|
- embulk-docs/src/release/release-0.8.3.rst
|
562
563
|
- embulk-docs/src/release/release-0.8.4.rst
|
563
564
|
- embulk-docs/src/release/release-0.8.5.rst
|