embulk 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/bin/embulk +2 -2
- data/build.gradle +11 -2
- data/embulk-cli/src/main/java/org/embulk/cli/Main.java +0 -2
- data/embulk-core/build.gradle +1 -1
- data/embulk-core/src/main/java/org/embulk/command/Runner.java +10 -0
- data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +3 -2
- data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +1 -1
- data/embulk-core/src/main/java/org/embulk/jruby/JRubyScriptingModule.java +18 -6
- data/embulk-core/src/main/java/org/embulk/plugin/PluginManager.java +14 -11
- data/embulk-core/src/main/java/org/embulk/spi/Column.java +5 -5
- data/embulk-core/src/main/java/org/embulk/spi/ColumnConfig.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/Exec.java +6 -0
- data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +1 -1
- data/embulk-core/src/main/java/org/embulk/spi/Schema.java +2 -2
- data/embulk-core/src/main/java/org/embulk/spi/SchemaConfig.java +2 -2
- data/embulk-core/src/main/java/org/embulk/spi/unit/ByteSize.java +148 -0
- data/embulk-core/src/test/java/org/embulk/spi/unit/TestByteSize.java +79 -0
- data/embulk-docs/build.gradle +5 -1
- data/embulk-docs/src/customization.rst +184 -0
- data/embulk-docs/src/index.rst +10 -1
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.6.3.rst +23 -0
- data/lib/embulk/command/embulk_run.rb +41 -3
- data/lib/embulk/data/new/gitignore.erb +1 -0
- data/lib/embulk/data/new/java/build.gradle.erb +20 -4
- data/lib/embulk/java/bootstrap.rb +2 -2
- data/lib/embulk/plugin.rb +1 -1
- data/lib/embulk/version.rb +1 -1
- data/test/helper.rb +7 -0
- metadata +8 -6
- data/embulk-docs/plugins/index.html.erb +0 -73
- data/embulk-docs/plugins/plugins.css +0 -148
@@ -0,0 +1,79 @@
|
|
1
|
+
package org.embulk.spi.unit;
|
2
|
+
|
3
|
+
import static org.junit.Assert.assertEquals;
|
4
|
+
import static org.junit.Assert.fail;
|
5
|
+
import org.junit.Test;
|
6
|
+
|
7
|
+
public class TestByteSize
|
8
|
+
{
|
9
|
+
@Test
|
10
|
+
public void testUnitPatterns()
|
11
|
+
{
|
12
|
+
assertByteSize(42L, "42");
|
13
|
+
assertByteSize(42L, "42B");
|
14
|
+
assertByteSize(42L*(1L << 10), "42KB");
|
15
|
+
assertByteSize(42L*(1L << 20), "42MB");
|
16
|
+
assertByteSize(42L*(1L << 30), "42GB");
|
17
|
+
assertByteSize(42L*(1L << 40), "42TB");
|
18
|
+
assertByteSize(42L*(1L << 50), "42PB");
|
19
|
+
assertByteSize(42L, "42 B");
|
20
|
+
assertByteSize(42L*(1L << 10), "42 KB");
|
21
|
+
}
|
22
|
+
|
23
|
+
@Test
|
24
|
+
public void testUnknownUnits()
|
25
|
+
{
|
26
|
+
assertInvalidByteSize("42XB");
|
27
|
+
assertInvalidByteSize("42 XB");
|
28
|
+
}
|
29
|
+
|
30
|
+
@Test
|
31
|
+
public void testInvalidPatterns()
|
32
|
+
{
|
33
|
+
assertInvalidByteSize(" 42");
|
34
|
+
assertInvalidByteSize("42 B");
|
35
|
+
assertInvalidByteSize("42 B ");
|
36
|
+
assertInvalidByteSize("42B ");
|
37
|
+
assertInvalidByteSize("42 KB");
|
38
|
+
assertInvalidByteSize("42 KB ");
|
39
|
+
assertInvalidByteSize("42KB ");
|
40
|
+
}
|
41
|
+
|
42
|
+
@Test
|
43
|
+
public void testInvalidValues()
|
44
|
+
{
|
45
|
+
assertInvalidByteSize("9223372036854775KB");
|
46
|
+
}
|
47
|
+
|
48
|
+
@Test
|
49
|
+
public void testToString()
|
50
|
+
{
|
51
|
+
assertByteSizeString("42B", "42 B");
|
52
|
+
assertByteSizeString("42KB", "42 KB");
|
53
|
+
assertByteSizeString("42MB", "42 MB");
|
54
|
+
assertByteSizeString("42GB", "42 GB");
|
55
|
+
assertByteSizeString("42TB", "42 TB");
|
56
|
+
assertByteSizeString("42PB", "42 PB");
|
57
|
+
assertByteSizeString("42.20KB", "42.2 KB");
|
58
|
+
assertByteSizeString("42.33KB", "42.33KB");
|
59
|
+
}
|
60
|
+
|
61
|
+
private static void assertByteSize(long bytes, String string)
|
62
|
+
{
|
63
|
+
assertEquals(bytes, ByteSize.parseByteSize(string).getBytes());
|
64
|
+
}
|
65
|
+
|
66
|
+
private static void assertByteSizeString(String expected, String string)
|
67
|
+
{
|
68
|
+
assertEquals(expected, ByteSize.parseByteSize(string).toString());
|
69
|
+
}
|
70
|
+
|
71
|
+
private static void assertInvalidByteSize(String string)
|
72
|
+
{
|
73
|
+
try {
|
74
|
+
ByteSize.parseByteSize(string);
|
75
|
+
fail();
|
76
|
+
} catch (IllegalArgumentException ex) {
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
data/embulk-docs/build.gradle
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
apply plugin: 'com.github.jruby-gradle.base'
|
2
2
|
|
3
|
+
import com.github.jrubygradle.JRubyExec
|
4
|
+
jruby {
|
5
|
+
execVersion = project.jrubyVersion
|
6
|
+
}
|
7
|
+
|
3
8
|
dependencies {
|
4
9
|
jrubyExec 'rubygems:yard:0.8.7.6'
|
5
10
|
}
|
@@ -16,7 +21,6 @@ task javadoc_html(type: Copy, dependsOn: [':embulk-core:javadoc']) {
|
|
16
21
|
into 'build/html/javadoc'
|
17
22
|
}
|
18
23
|
|
19
|
-
import com.github.jrubygradle.JRubyExec
|
20
24
|
task rdoc_html(type: JRubyExec) {
|
21
25
|
workingDir '..'
|
22
26
|
jrubyArgs '-ryard', '-eYARD::CLI::Yardoc.run(*ARGV)', '--', '-o', 'embulk-docs/build/html/rdoc'
|
@@ -0,0 +1,184 @@
|
|
1
|
+
Customization
|
2
|
+
==================================
|
3
|
+
|
4
|
+
.. contents::
|
5
|
+
:local:
|
6
|
+
:depth: 2
|
7
|
+
|
8
|
+
|
9
|
+
Creating plugins
|
10
|
+
------------------
|
11
|
+
|
12
|
+
Creating a new plugin is 4 steps:
|
13
|
+
|
14
|
+
1. Create a new project using a template generator
|
15
|
+
2. Build the project (Java only)
|
16
|
+
3. Confirm it works
|
17
|
+
4. Modify the code as you need
|
18
|
+
|
19
|
+
This article describes how to create a plugin step by step.
|
20
|
+
|
21
|
+
Step 1: Creating a new project
|
22
|
+
~~~~~~~~~~~~~~~~~~
|
23
|
+
|
24
|
+
Embulk comes with a number of templates that generates a new project so that you can start development instantly. Because the generated project contains completely working code without additional code, you can focus on the necessary coding.
|
25
|
+
|
26
|
+
Usage of the generator is where ``<type>`` is one of the plugin templates:
|
27
|
+
|
28
|
+
::
|
29
|
+
|
30
|
+
$ embulk new <type> <name>
|
31
|
+
|
32
|
+
Here is the list of available templates. Please find the best option:
|
33
|
+
|
34
|
+
==================== =============================== =================
|
35
|
+
Type description example
|
36
|
+
==================== =============================== =================
|
37
|
+
**java-input** Java record input plugin ``mysql``
|
38
|
+
**java-output** Java record output plugin ``mysql``
|
39
|
+
**java-filter** Java record filter plugin ``add-hostname``
|
40
|
+
**java-file-input** Java file input plugin ``ftp``
|
41
|
+
**java-file-output** Java file output plugin ``ftp``
|
42
|
+
**java-parser** Java file parser plugin ``csv``
|
43
|
+
**java-formatter** Java file formatter plugin ``csv``
|
44
|
+
**java-decoder** Java file decoder plugin ``gzip``
|
45
|
+
**java-encoder** Java file encoder plugin ``gzip``
|
46
|
+
**ruby-input** Ruby record input plugin ``mysql``
|
47
|
+
**ruby-output** Ruby record output plugin ``mysql``
|
48
|
+
**ruby-filter** Ruby record filter plugin ``add-hostname``
|
49
|
+
**ruby-parser** Ruby file parser plugin ``csv``
|
50
|
+
**ruby-formatter** Ruby file formatter plugin ``csv```
|
51
|
+
==================== =============================== =================
|
52
|
+
|
53
|
+
For example, if you want to parse a new file format using Java, type this command:
|
54
|
+
|
55
|
+
::
|
56
|
+
|
57
|
+
$ embulk new java-parser myformat
|
58
|
+
|
59
|
+
This will create a Java-based parser plugin called ``myformat`` in ``embulk-parser-myformat`` directory.
|
60
|
+
|
61
|
+
Step 2: Building the project
|
62
|
+
~~~~~~~~~~~~~~~~~~
|
63
|
+
|
64
|
+
If the plugin is Java-based, you need to build the project. To build, type this command:
|
65
|
+
|
66
|
+
::
|
67
|
+
|
68
|
+
$ cd embulk-parser-myformat
|
69
|
+
$ ./gradlew package
|
70
|
+
|
71
|
+
Now, the plugin is ready to use.
|
72
|
+
|
73
|
+
Step 3: Confirm it works
|
74
|
+
~~~~~~~~~~~~~~~~~~
|
75
|
+
|
76
|
+
The next step is to actually use the plugin.
|
77
|
+
|
78
|
+
Let's supporse you have a configuration file named ``your-config.yml``. You can use the plugin using embulk with ``-L`` argument:
|
79
|
+
|
80
|
+
::
|
81
|
+
|
82
|
+
$ embulk run -L ./embulk-parser-myformat/ your-config.yml
|
83
|
+
|
84
|
+
Step 4: Modifying the code
|
85
|
+
~~~~~~~~~~~~~~~~~~
|
86
|
+
|
87
|
+
The final step is to modify code as you want!
|
88
|
+
|
89
|
+
The code is located at
|
90
|
+
|
91
|
+
* Java-based plugins
|
92
|
+
|
93
|
+
* src/org/embulk/*
|
94
|
+
|
95
|
+
* Ruby-based plugins
|
96
|
+
|
97
|
+
* lib/embulk/*
|
98
|
+
|
99
|
+
There are a lot of good code examples on Github. Search repositories by `embulk-<type> keyword <https://github.com/search?q=embulk-output>`_.
|
100
|
+
|
101
|
+
Releasing plugins
|
102
|
+
------------------
|
103
|
+
|
104
|
+
You can release publicly so that all people can use your awesome plugins.
|
105
|
+
|
106
|
+
Checking plugin description
|
107
|
+
~~~~~~~~~~~~~~~~~~
|
108
|
+
|
109
|
+
To prepare the plugin ready to release, you need to include some additional information. The plugin information is written in this file:
|
110
|
+
|
111
|
+
* Java-based plugins
|
112
|
+
|
113
|
+
* ``build.gradle`` file
|
114
|
+
|
115
|
+
* Ruby-based plugins
|
116
|
+
|
117
|
+
* ``embulk-<type>-<name>.gemspec`` file (``<type>`` is plugin type and ``<name>`` is plugin name)
|
118
|
+
|
119
|
+
You will find following section in the file.
|
120
|
+
|
121
|
+
.. code-block:: ruby
|
122
|
+
|
123
|
+
Gem::Specification.new do |spec|
|
124
|
+
# ...
|
125
|
+
|
126
|
+
spec.authors = ["Your Name"]
|
127
|
+
spec.summary = %[Myformat parser plugin for Embulk]
|
128
|
+
spec.description = %[Parses Myformat files read by other file input plugins.]
|
129
|
+
spec.email = ["you@example.org"]
|
130
|
+
spec.licenses = ["MIT"]
|
131
|
+
spec.homepage = "https://github.com/frsyuki/embulk-parser-myformat"
|
132
|
+
|
133
|
+
# ...
|
134
|
+
end
|
135
|
+
|
136
|
+
The items in above example are important. Please make sure that they are good.
|
137
|
+
|
138
|
+
Creating account on RubyGems.org
|
139
|
+
~~~~~~~~~~~~~~~~~~
|
140
|
+
|
141
|
+
Embulk uses `RubyGems.org <https://rubygems.org/>`_ as a package distribution service. Please create an account there to release plugins at `Sign Up <https://rubygems.org/sign_up>`_ page.
|
142
|
+
|
143
|
+
Don't forget the password! It will be necessary at the next step.
|
144
|
+
|
145
|
+
Releasing the plugin to RubyGems.org
|
146
|
+
~~~~~~~~~~~~~~~~~~
|
147
|
+
|
148
|
+
Now, you're ready to release the plugin. To release, type following command:
|
149
|
+
|
150
|
+
* Java-based plugins
|
151
|
+
|
152
|
+
* ``$ ./gradlew gemPush``
|
153
|
+
|
154
|
+
* Ruby-based plugins
|
155
|
+
|
156
|
+
* ``$ rake release``
|
157
|
+
|
158
|
+
If everything is good, you can find your plugin at https://rubygems.org/. Congratulations!
|
159
|
+
|
160
|
+
Installing your plugin
|
161
|
+
~~~~~~~~~~~~~~~~~~
|
162
|
+
|
163
|
+
Usage of plugin installer is:
|
164
|
+
|
165
|
+
::
|
166
|
+
|
167
|
+
$ embulk gem install embulk-<type>-<name>
|
168
|
+
|
169
|
+
``<type>`` is plugin type and ``<name>`` is plugin name.
|
170
|
+
|
171
|
+
If your plugin is ``embulk-parser-myformat``, then type this command:
|
172
|
+
|
173
|
+
::
|
174
|
+
|
175
|
+
$ embulk gem install embulk-parser-myformat
|
176
|
+
|
177
|
+
This command installs the plugin to ``~/.embulk`` directory.
|
178
|
+
|
179
|
+
To check the list of installed plugins and their versions, use this command:
|
180
|
+
|
181
|
+
::
|
182
|
+
|
183
|
+
$ embulk gem list
|
184
|
+
|
data/embulk-docs/src/index.rst
CHANGED
@@ -63,7 +63,11 @@ Documents
|
|
63
63
|
:maxdepth: 2
|
64
64
|
|
65
65
|
built-in
|
66
|
-
|
66
|
+
|
67
|
+
.. toctree::
|
68
|
+
:maxdepth: 3
|
69
|
+
|
70
|
+
customization
|
67
71
|
|
68
72
|
* `JavaDoc <javadoc/index.html>`_
|
69
73
|
|
@@ -71,3 +75,8 @@ Documents
|
|
71
75
|
|
72
76
|
* `Github <https://github.com/embulk/embulk>`_
|
73
77
|
|
78
|
+
.. toctree::
|
79
|
+
:maxdepth: 2
|
80
|
+
|
81
|
+
release
|
82
|
+
|
data/embulk-docs/src/release.rst
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
Release 0.6.3
|
2
|
+
==================================
|
3
|
+
|
4
|
+
Plugin API
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Added ``org.embulk.spi.unit.ByteSize`` utility class. Plugins can use this class to allow units such as 'KB' or 'MB' in the configuration file.
|
8
|
+
|
9
|
+
Command-line
|
10
|
+
------------------
|
11
|
+
|
12
|
+
* Added '-L, --load PATH' argument to load a plugin form a local directory.
|
13
|
+
|
14
|
+
General Changes
|
15
|
+
------------------
|
16
|
+
|
17
|
+
* Updated template generator for Java so that generated build.gradle file has ``package`` task to create gemspec file.
|
18
|
+
* PreviewExecutor and GuessExecutor unwrap ExecutionException. Error stacktrace becomes simple.
|
19
|
+
* EmbulkService creates JRuby runtime and its execution environment for each Injector instances.
|
20
|
+
|
21
|
+
Release Date
|
22
|
+
------------------
|
23
|
+
2015-04-21
|
@@ -36,10 +36,16 @@ module Embulk
|
|
36
36
|
|
37
37
|
puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%3N %z")}: Embulk v#{Embulk::VERSION}"
|
38
38
|
|
39
|
+
plugin_paths = []
|
39
40
|
load_paths = []
|
40
41
|
classpaths = []
|
41
42
|
classpath_separator = java.io.File.pathSeparator
|
42
|
-
|
43
|
+
|
44
|
+
options = {
|
45
|
+
# use the global ruby runtime (the jruby Runtime running this embulk_run.rb script) for all
|
46
|
+
# ScriptingContainer injected by the org.embulk.command.Runner.
|
47
|
+
useGlobalRubyRuntime: true,
|
48
|
+
}
|
43
49
|
|
44
50
|
op.on('-b', '--bundle BUNDLE_DIR', 'Path to a Gemfile directory') do |path|
|
45
51
|
# only for help message. implemented at lib/embulk/command/embulk.rb
|
@@ -61,6 +67,9 @@ module Embulk
|
|
61
67
|
op.on('-l', '--log-level LEVEL', 'Log level (fatal, error, warn, info, debug or trace)') do |level|
|
62
68
|
options[:logLevel] = level
|
63
69
|
end
|
70
|
+
op.on('-L', '--load PATH', 'Add a local plugin path') do |plugin_path|
|
71
|
+
plugin_paths << plugin_path
|
72
|
+
end
|
64
73
|
op.on('-I', '--load-path PATH', 'Add ruby script directory path ($LOAD_PATH)') do |load_path|
|
65
74
|
load_paths << load_path
|
66
75
|
end
|
@@ -80,6 +89,9 @@ module Embulk
|
|
80
89
|
op.on('-l', '--log-level LEVEL', 'Log level (fatal, error, warn, info, debug or trace)') do |level|
|
81
90
|
options[:logLevel] = level
|
82
91
|
end
|
92
|
+
op.on('-L', '--load PATH', 'Add a local plugin path') do |plugin_path|
|
93
|
+
plugin_paths << plugin_path
|
94
|
+
end
|
83
95
|
op.on('-I', '--load-path PATH', 'Add ruby script directory path ($LOAD_PATH)') do |load_path|
|
84
96
|
load_paths << load_path
|
85
97
|
end
|
@@ -96,6 +108,9 @@ module Embulk
|
|
96
108
|
op.on('-l', '--log-level LEVEL', 'Log level (fatal, error, warn, info, debug or trace)') do |level|
|
97
109
|
options[:logLevel] = level
|
98
110
|
end
|
111
|
+
op.on('-L', '--load PATH', 'Add a local plugin path') do |plugin_path|
|
112
|
+
plugin_paths << plugin_path
|
113
|
+
end
|
99
114
|
op.on('-I', '--load-path PATH', 'Add ruby script directory path ($LOAD_PATH)') do |load_path|
|
100
115
|
load_paths << load_path
|
101
116
|
end
|
@@ -115,6 +130,9 @@ module Embulk
|
|
115
130
|
op.on('-o', '--output PATH', 'Path to a file to write the guessed configuration') do |path|
|
116
131
|
options[:nextConfigOutputPath] = path
|
117
132
|
end
|
133
|
+
op.on('-L', '--load PATH', 'Add a local plugin path') do |plugin_path|
|
134
|
+
plugin_paths << plugin_path
|
135
|
+
end
|
118
136
|
op.on('-I', '--load-path PATH', 'Add ruby script directory path ($LOAD_PATH)') do |load_path|
|
119
137
|
load_paths << load_path
|
120
138
|
end
|
@@ -186,6 +204,7 @@ examples:
|
|
186
204
|
|
187
205
|
require 'fileutils'
|
188
206
|
require 'rubygems/gem_runner'
|
207
|
+
setup_plugin_paths(plugin_paths)
|
189
208
|
setup_load_paths(load_paths)
|
190
209
|
setup_classpaths(classpaths)
|
191
210
|
|
@@ -292,6 +311,7 @@ examples:
|
|
292
311
|
end
|
293
312
|
end
|
294
313
|
|
314
|
+
setup_plugin_paths(plugin_paths)
|
295
315
|
setup_load_paths(load_paths)
|
296
316
|
setup_classpaths(classpaths)
|
297
317
|
|
@@ -331,6 +351,24 @@ examples:
|
|
331
351
|
Gem.clear_paths # force rubygems to reload GEM_HOME
|
332
352
|
end
|
333
353
|
|
354
|
+
def self.setup_plugin_paths(plugin_paths)
|
355
|
+
plugin_paths.each do |path|
|
356
|
+
unless File.directory?(path)
|
357
|
+
raise "Path '#{path}' is not a directory"
|
358
|
+
end
|
359
|
+
specs = Dir[File.join(File.expand_path(path), "*.gemspec")]
|
360
|
+
if specs.empty?
|
361
|
+
raise "Path '#{path}' does not include *.gemspec file. Hint: Did you run './gradlew package' command?"
|
362
|
+
end
|
363
|
+
specs.each do |spec|
|
364
|
+
gem_path = File.dirname(spec)
|
365
|
+
stub = Gem::StubSpecification.new(spec)
|
366
|
+
stub.define_singleton_method(:full_gem_path) { gem_path }
|
367
|
+
Gem::Specification.add_spec(stub)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
334
372
|
def self.setup_load_paths(load_paths)
|
335
373
|
# first $LOAD_PATH has highet priority. later load_paths should have highest priority.
|
336
374
|
load_paths.each do |load_path|
|
@@ -340,9 +378,9 @@ examples:
|
|
340
378
|
end
|
341
379
|
|
342
380
|
def self.setup_classpaths(classpaths)
|
343
|
-
classpaths.each
|
381
|
+
classpaths.each do |classpath|
|
344
382
|
$CLASSPATH << classpath # $CLASSPATH object doesn't have concat method
|
345
|
-
|
383
|
+
end
|
346
384
|
end
|
347
385
|
|
348
386
|
def self.usage(message)
|