pdi 1.0.0.pre.alpha → 1.0.0.pre.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -8
- data/lib/pdi/executor/result.rb +12 -10
- data/lib/pdi/executor/status.rb +28 -0
- data/lib/pdi/executor.rb +13 -11
- data/lib/pdi/spoon/kitchen_error.rb +1 -1
- data/lib/pdi/spoon/options/arg.rb +1 -1
- data/lib/pdi/spoon/options/level.rb +1 -1
- data/lib/pdi/spoon/options/param.rb +1 -1
- data/lib/pdi/spoon/options.rb +1 -1
- data/lib/pdi/spoon/pan_error.rb +1 -1
- data/lib/pdi/spoon/parser.rb +2 -2
- data/lib/pdi/spoon/result.rb +1 -1
- data/lib/pdi/spoon.rb +19 -19
- data/lib/pdi/version.rb +2 -2
- data/lib/pdi.rb +1 -0
- data/pdi.gemspec +3 -3
- data/spec/mocks/spoon/{return_0.sh → return_code.sh} +1 -1
- data/spec/pdi/spoon/error_spec.rb +19 -5
- data/spec/pdi/spoon/options/arg_spec.rb +1 -1
- data/spec/pdi/spoon/options/param_spec.rb +1 -1
- data/spec/pdi/spoon/options_spec.rb +1 -1
- data/spec/pdi/spoon_spec.rb +37 -24
- metadata +8 -18
- data/spec/mocks/spoon/return_1.sh +0 -14
- data/spec/mocks/spoon/return_2.sh +0 -14
- data/spec/mocks/spoon/return_3.sh +0 -14
- data/spec/mocks/spoon/return_7.sh +0 -14
- data/spec/mocks/spoon/return_8.sh +0 -14
- data/spec/mocks/spoon/return_9.sh +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e653f6aed9fd26cce60e4f84cfdf662e0be847f40828142dd28fcc6118150cc7
|
4
|
+
data.tar.gz: 6ab7d8da5c628dc867d0607bcb3a3db6a5b4c030f07d91adc3f47516a2b3350f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e2688a153fea7a256e80a9e682b6488e71923d2752e32f37c23a39c7899f33faf2ffd99c91b5770e4e4279dd0af0ea9f3bdd6d52057b9780d6f798f7a44fedc
|
7
|
+
data.tar.gz: 66f618cc1203d313091cd849403501c127907a719f2b6503792cffe606f02062d0f2f31e179a45395e4460c47245de5461c1b78496208ad5ddf68437f7889558
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Pdi
|
2
2
|
|
3
3
|
---
|
4
4
|
|
@@ -36,14 +36,14 @@ Pull Requests are welcome for:
|
|
36
36
|
|
37
37
|
## Examples
|
38
38
|
|
39
|
-
All examples assume
|
39
|
+
All examples assume Pdi has been installed to your home directory: `~/data-integration`.
|
40
40
|
|
41
41
|
### Creating a Spoon Instance
|
42
42
|
|
43
|
-
`
|
43
|
+
`Pdi::Spoon` is the common interface you will use when interacting with Pdi. It will use Pan and Kitchen for executing Spoon commands.
|
44
44
|
|
45
45
|
```ruby
|
46
|
-
spoon =
|
46
|
+
spoon = Pdi::Spoon.new(dir: `~/data-integration`)
|
47
47
|
```
|
48
48
|
|
49
49
|
Note: You can also override the names of the scripts using the `kitchen` and `pan` constructor keyword arguments. The defaults are `kitchen.sh` and `pan.sh`, respectively.
|
@@ -52,7 +52,7 @@ Note: You can also override the names of the scripts using the `kitchen` and `pa
|
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
options = {
|
55
|
-
level:
|
55
|
+
level: Pdi::Spoon::Level::DETAILED,
|
56
56
|
name: 'update_address',
|
57
57
|
repository: 'transformations/demographics',
|
58
58
|
params: {
|
@@ -66,12 +66,12 @@ result = spoon.run(options)
|
|
66
66
|
|
67
67
|
`Spoon#run` will return:
|
68
68
|
|
69
|
-
* `
|
70
|
-
* If a non-zero exit code was returned then a `
|
69
|
+
* `Pdi::Spoon::Result` upon a successful run.
|
70
|
+
* If a non-zero exit code was returned then a `Pdi::Spoon::PanError` or `Pdi::Spoon::KitchenError` will be raised.
|
71
71
|
|
72
72
|
You can access the raw command line results by tapping into the execution attribute of the result or error object.
|
73
73
|
|
74
|
-
Note: Not all options are currently supported. See
|
74
|
+
Note: Not all options are currently supported. See Pdi's official references for [Pan](https://help.pentaho.com/Documentation/6.1/0L0/0Y0/070/000) and [Kitchen](https://help.pentaho.com/Documentation/6.1/0L0/0Y0/070/010) to see all options.
|
75
75
|
|
76
76
|
## Contributing
|
77
77
|
|
data/lib/pdi/executor/result.rb
CHANGED
@@ -7,20 +7,22 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
|
10
|
+
require_relative 'status'
|
11
|
+
|
12
|
+
module Pdi
|
11
13
|
class Executor
|
12
14
|
# General return object for an execution call result.
|
13
15
|
class Result
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
extend Forwardable
|
17
|
+
acts_as_hashable
|
18
|
+
|
19
|
+
attr_reader :args, :status
|
20
|
+
|
21
|
+
def_delegators :status, :code, :out, :err, :pid
|
18
22
|
|
19
|
-
def initialize(
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@out_and_err = out_and_err
|
23
|
-
@pid = pid
|
23
|
+
def initialize(args:, status: {})
|
24
|
+
@args = args
|
25
|
+
@status = Status.make(status)
|
24
26
|
|
25
27
|
freeze
|
26
28
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Pdi
|
11
|
+
class Executor
|
12
|
+
# General return object for describing the operating system return data.
|
13
|
+
class Status
|
14
|
+
acts_as_hashable
|
15
|
+
|
16
|
+
attr_reader :code, :out, :err, :pid
|
17
|
+
|
18
|
+
def initialize(code:, out: '', err: '', pid:)
|
19
|
+
@code = code
|
20
|
+
@out = out
|
21
|
+
@err = err
|
22
|
+
@pid = pid
|
23
|
+
|
24
|
+
freeze
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/pdi/executor.rb
CHANGED
@@ -9,22 +9,24 @@
|
|
9
9
|
|
10
10
|
require_relative 'executor/result'
|
11
11
|
|
12
|
-
module
|
12
|
+
module Pdi
|
13
13
|
# This class is the library's "metal" layer, the one which actually makes the system call and
|
14
14
|
# interacts with the operating system (through Ruby's standard library.)
|
15
15
|
class Executor
|
16
|
-
|
16
|
+
def run(args)
|
17
|
+
args = Array(args).map(&:to_s)
|
17
18
|
|
18
|
-
|
19
|
-
cmd = args.flatten.join(SPACE)
|
19
|
+
out, err, status = Open3.capture3(*args)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
Result.new(
|
22
|
+
args: args,
|
23
|
+
status: {
|
24
|
+
code: status.exitstatus,
|
25
|
+
out: out,
|
26
|
+
err: err,
|
27
|
+
pid: status.pid
|
28
|
+
}
|
29
|
+
)
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
data/lib/pdi/spoon/options.rb
CHANGED
@@ -12,7 +12,7 @@ require_relative 'options/level'
|
|
12
12
|
require_relative 'options/param'
|
13
13
|
require_relative 'pan_error'
|
14
14
|
|
15
|
-
module
|
15
|
+
module Pdi
|
16
16
|
class Spoon
|
17
17
|
# This class serves as the input for executing a transformation or job through Pan or Kitchen.
|
18
18
|
class Options
|
data/lib/pdi/spoon/pan_error.rb
CHANGED
data/lib/pdi/spoon/parser.rb
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
module
|
10
|
+
module Pdi
|
11
11
|
class Spoon
|
12
|
-
# This class knows how to parse
|
12
|
+
# This class knows how to parse feedback from Pentaho and make sense of it.
|
13
13
|
class Parser
|
14
14
|
NEW_LINE = "\n"
|
15
15
|
|
data/lib/pdi/spoon/result.rb
CHANGED
data/lib/pdi/spoon.rb
CHANGED
@@ -11,15 +11,16 @@ require_relative 'spoon/options'
|
|
11
11
|
require_relative 'spoon/parser'
|
12
12
|
require_relative 'spoon/result'
|
13
13
|
|
14
|
-
module
|
15
|
-
# This class is the main wrapper for
|
14
|
+
module Pdi
|
15
|
+
# This class is the main wrapper for Pdi's pan and kitchen scripts.
|
16
16
|
class Spoon
|
17
17
|
DEFAULT_KITCHEN = 'kitchen.sh'
|
18
18
|
DEFAULT_PAN = 'pan.sh'
|
19
19
|
|
20
|
-
attr_reader :dir, :kitchen, :pan
|
20
|
+
attr_reader :args, :dir, :kitchen, :pan
|
21
21
|
|
22
22
|
def initialize(
|
23
|
+
args: [],
|
23
24
|
dir:,
|
24
25
|
kitchen: DEFAULT_KITCHEN,
|
25
26
|
pan: DEFAULT_PAN
|
@@ -28,6 +29,7 @@ module PDI
|
|
28
29
|
assert_required(:kitchen, kitchen)
|
29
30
|
assert_required(:pan, pan)
|
30
31
|
|
32
|
+
@args = Array(args)
|
31
33
|
@dir = dir.to_s
|
32
34
|
@kitchen = kitchen.to_s
|
33
35
|
@pan = pan.to_s
|
@@ -37,30 +39,28 @@ module PDI
|
|
37
39
|
freeze
|
38
40
|
end
|
39
41
|
|
42
|
+
# Returns a Spoon::Result instance when PDI returns error code 0 or else raises
|
43
|
+
# a KitchenError since Kitchen was used to run the version command.
|
40
44
|
def version
|
41
|
-
|
42
|
-
kitchen_path,
|
43
|
-
Options::Arg.new(Options::Arg::Key::VERSION)
|
44
|
-
]
|
45
|
+
final_args = [kitchen_path] + args + [Options::Arg.new(Options::Arg::Key::VERSION)]
|
45
46
|
|
46
|
-
result = executor.run(
|
47
|
-
version_line = parser.version(result.
|
47
|
+
result = executor.run(final_args)
|
48
|
+
version_line = parser.version(result.out)
|
49
|
+
|
50
|
+
raise(KitchenError, result) if result.code != 0
|
48
51
|
|
49
52
|
Result.new(result, version_line)
|
50
53
|
end
|
51
54
|
|
55
|
+
# Returns an Executor::Result instance when PDI returns error code 0 or else raises
|
56
|
+
# a PanError (transformation) or KitchenError (job).
|
52
57
|
def run(options)
|
53
|
-
options
|
54
|
-
|
55
|
-
args = [
|
56
|
-
pan_path
|
57
|
-
] + options.to_args
|
58
|
-
|
59
|
-
result = executor.run(args)
|
60
|
-
|
61
|
-
raise(options.error_constant, result) if result.code != 0
|
58
|
+
options = Options.make(options)
|
59
|
+
final_args = [pan_path] + args + options.to_args
|
62
60
|
|
63
|
-
|
61
|
+
executor.run(final_args).tap do |result|
|
62
|
+
raise(options.error_constant, result) if result.code != 0
|
63
|
+
end
|
64
64
|
end
|
65
65
|
|
66
66
|
private
|
data/lib/pdi/version.rb
CHANGED
data/lib/pdi.rb
CHANGED
data/pdi.gemspec
CHANGED
@@ -4,11 +4,11 @@ require './lib/pdi/version'
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'pdi'
|
7
|
-
s.version =
|
8
|
-
s.summary = '
|
7
|
+
s.version = Pdi::VERSION
|
8
|
+
s.summary = 'Ruby wrapper for invoking Pentaho Data Integration'
|
9
9
|
|
10
10
|
s.description = <<-DESCRIPTION
|
11
|
-
|
11
|
+
Pentaho Data Integration allows for the creation of ETL transformation and jobs. This library allows those ETL tasks to be executed from Ruby.
|
12
12
|
DESCRIPTION
|
13
13
|
|
14
14
|
s.authors = ['Matthew Ruggio']
|
@@ -9,19 +9,33 @@
|
|
9
9
|
|
10
10
|
require 'spec_helper'
|
11
11
|
|
12
|
-
describe
|
12
|
+
describe Pdi::Spoon::PanError do
|
13
13
|
describe 'initialization' do
|
14
14
|
[1, 2, 3, 7, 8, 9].each do |code|
|
15
15
|
specify "code #{code} should have message" do
|
16
|
-
|
17
|
-
|
16
|
+
result = Pdi::Executor::Result.new(
|
17
|
+
args: [],
|
18
|
+
status: {
|
19
|
+
code: code,
|
20
|
+
pid: 123
|
21
|
+
}
|
22
|
+
)
|
23
|
+
|
24
|
+
expect(described_class.new(result).message).not_to eq('Unknown')
|
18
25
|
end
|
19
26
|
end
|
20
27
|
|
21
28
|
[-1, 0, 4, 5, 6, 10, 11].each do |code|
|
22
29
|
specify "code #{code} should not have message" do
|
23
|
-
|
24
|
-
|
30
|
+
result = Pdi::Executor::Result.new(
|
31
|
+
args: [],
|
32
|
+
status: {
|
33
|
+
code: code,
|
34
|
+
pid: 123
|
35
|
+
}
|
36
|
+
)
|
37
|
+
|
38
|
+
expect(described_class.new(result).message).to eq('Unknown')
|
25
39
|
end
|
26
40
|
end
|
27
41
|
end
|
data/spec/pdi/spoon_spec.rb
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
|
10
10
|
require 'spec_helper'
|
11
11
|
|
12
|
-
describe
|
12
|
+
describe Pdi::Spoon do
|
13
|
+
let(:script) { 'return_code.sh' }
|
13
14
|
let(:mocks_dir) { %w[spec mocks spoon] }
|
14
15
|
let(:dir) { File.join(*mocks_dir) }
|
15
16
|
|
@@ -25,9 +26,8 @@ describe PDI::Spoon do
|
|
25
26
|
|
26
27
|
context 'when code is 0' do
|
27
28
|
it 'returns correct stdout, stderr and code' do
|
28
|
-
script = 'return_0.sh'
|
29
|
-
|
30
29
|
subject = described_class.new(
|
30
|
+
args: 0,
|
31
31
|
dir: dir,
|
32
32
|
kitchen: script,
|
33
33
|
pan: script
|
@@ -35,18 +35,17 @@ describe PDI::Spoon do
|
|
35
35
|
|
36
36
|
result = subject.run(options)
|
37
37
|
|
38
|
-
expect(result.
|
39
|
-
expect(result.
|
40
|
-
expect(result.
|
38
|
+
expect(result.out).to eq("output to stdout\n")
|
39
|
+
expect(result.err).to eq("output to sterr\n")
|
40
|
+
expect(result.code).to eq(0)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
[1, 2, 3, 7, 8, 9].each do |code|
|
45
45
|
context "when code is #{code}" do
|
46
46
|
specify 'returns correct stdout, stderr and code' do
|
47
|
-
script = "return_#{code}.sh"
|
48
|
-
|
49
47
|
subject = described_class.new(
|
48
|
+
args: code,
|
50
49
|
dir: dir,
|
51
50
|
kitchen: script,
|
52
51
|
pan: script
|
@@ -73,9 +72,8 @@ describe PDI::Spoon do
|
|
73
72
|
|
74
73
|
context 'when code is 0' do
|
75
74
|
it 'returns correct stdout, stderr and code' do
|
76
|
-
script = 'return_0.sh'
|
77
|
-
|
78
75
|
subject = described_class.new(
|
76
|
+
args: 0,
|
79
77
|
dir: dir,
|
80
78
|
kitchen: script,
|
81
79
|
pan: script
|
@@ -83,18 +81,17 @@ describe PDI::Spoon do
|
|
83
81
|
|
84
82
|
result = subject.run(options)
|
85
83
|
|
86
|
-
expect(result.
|
87
|
-
expect(result.
|
88
|
-
expect(result.
|
84
|
+
expect(result.out).to eq("output to stdout\n")
|
85
|
+
expect(result.err).to eq("output to sterr\n")
|
86
|
+
expect(result.code).to eq(0)
|
89
87
|
end
|
90
88
|
end
|
91
89
|
|
92
90
|
[1, 2, 7, 8, 9].each do |code|
|
93
91
|
context "when code is #{code}" do
|
94
92
|
specify 'returns correct stdout, stderr and code' do
|
95
|
-
script = "return_#{code}.sh"
|
96
|
-
|
97
93
|
subject = described_class.new(
|
94
|
+
args: code,
|
98
95
|
dir: dir,
|
99
96
|
kitchen: script,
|
100
97
|
pan: script
|
@@ -109,24 +106,40 @@ describe PDI::Spoon do
|
|
109
106
|
end
|
110
107
|
|
111
108
|
describe '#version' do
|
112
|
-
let(:script) { 'version.sh' }
|
113
|
-
|
114
109
|
subject do
|
115
110
|
described_class.new(
|
111
|
+
args: args,
|
116
112
|
dir: dir,
|
117
113
|
kitchen: script,
|
118
114
|
pan: script
|
119
115
|
)
|
120
116
|
end
|
121
117
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
118
|
+
context 'when code is 0' do
|
119
|
+
let(:script) { 'version.sh' }
|
120
|
+
let(:args) { 0 }
|
121
|
+
|
122
|
+
it 'returns parsed version line' do
|
123
|
+
result = subject.version
|
124
|
+
|
125
|
+
expected = [
|
126
|
+
'2020/01/30 13:31:04 - Pan - Kettle version 6.1.0.1-196,',
|
127
|
+
'build 1, build date : 2016-04-07 12.08.49'
|
128
|
+
].join(' ')
|
129
|
+
|
130
|
+
expect(result.value).to eq(expected)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'when code is not 0' do
|
135
|
+
let(:script) { 'return_code.sh' }
|
136
|
+
let(:args) { 1 }
|
137
|
+
|
138
|
+
it 'raises KitchenError' do
|
139
|
+
expected = described_class::KitchenError
|
128
140
|
|
129
|
-
|
141
|
+
expect { subject.version }.to raise_error(expected)
|
142
|
+
end
|
130
143
|
end
|
131
144
|
end
|
132
145
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pdi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.alpha
|
4
|
+
version: 1.0.0.pre.alpha.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_hashable
|
@@ -122,7 +122,8 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.6.0
|
125
|
-
description: "
|
125
|
+
description: " Pentaho Data Integration allows for the creation of ETL transformation
|
126
|
+
and jobs. This library allows those ETL tasks to be executed from Ruby.\n"
|
126
127
|
email:
|
127
128
|
- mruggio@bluemarblepayroll.com
|
128
129
|
executables:
|
@@ -146,6 +147,7 @@ files:
|
|
146
147
|
- lib/pdi.rb
|
147
148
|
- lib/pdi/executor.rb
|
148
149
|
- lib/pdi/executor/result.rb
|
150
|
+
- lib/pdi/executor/status.rb
|
149
151
|
- lib/pdi/spoon.rb
|
150
152
|
- lib/pdi/spoon/kitchen_error.rb
|
151
153
|
- lib/pdi/spoon/options.rb
|
@@ -157,13 +159,7 @@ files:
|
|
157
159
|
- lib/pdi/spoon/result.rb
|
158
160
|
- lib/pdi/version.rb
|
159
161
|
- pdi.gemspec
|
160
|
-
- spec/mocks/spoon/
|
161
|
-
- spec/mocks/spoon/return_1.sh
|
162
|
-
- spec/mocks/spoon/return_2.sh
|
163
|
-
- spec/mocks/spoon/return_3.sh
|
164
|
-
- spec/mocks/spoon/return_7.sh
|
165
|
-
- spec/mocks/spoon/return_8.sh
|
166
|
-
- spec/mocks/spoon/return_9.sh
|
162
|
+
- spec/mocks/spoon/return_code.sh
|
167
163
|
- spec/mocks/spoon/version.sh
|
168
164
|
- spec/pdi/spoon/error_spec.rb
|
169
165
|
- spec/pdi/spoon/options/arg_spec.rb
|
@@ -193,15 +189,9 @@ requirements: []
|
|
193
189
|
rubygems_version: 3.0.3
|
194
190
|
signing_key:
|
195
191
|
specification_version: 4
|
196
|
-
summary:
|
192
|
+
summary: Ruby wrapper for invoking Pentaho Data Integration
|
197
193
|
test_files:
|
198
|
-
- spec/mocks/spoon/
|
199
|
-
- spec/mocks/spoon/return_1.sh
|
200
|
-
- spec/mocks/spoon/return_2.sh
|
201
|
-
- spec/mocks/spoon/return_3.sh
|
202
|
-
- spec/mocks/spoon/return_7.sh
|
203
|
-
- spec/mocks/spoon/return_8.sh
|
204
|
-
- spec/mocks/spoon/return_9.sh
|
194
|
+
- spec/mocks/spoon/return_code.sh
|
205
195
|
- spec/mocks/spoon/version.sh
|
206
196
|
- spec/pdi/spoon/error_spec.rb
|
207
197
|
- spec/pdi/spoon/options/arg_spec.rb
|