ntl-orchestra 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e96984bfe46ae0b8f9769e7d2a63fcfc2d3efc04
4
- data.tar.gz: 35665deb648f6be6360f566d4d504b7e609e28d0
3
+ metadata.gz: 3c1897824735843933375a596888e93eb404fe49
4
+ data.tar.gz: d29cfbda3e69e845132c79b2cc7784c410851b39
5
5
  SHA512:
6
- metadata.gz: 9af68198925832621e1a08a4fb34c2da7881a44aab59f350485c2a4e6845ecdbd2631e089315e392bf5047453ae67a20eaf07bdf5ce3535bf148c4445cfaf646
7
- data.tar.gz: 99e4ed20368788e954eab33f8bd79ddc7c329cf0fec6ef13fc7fec550fe06b78df1b9362c7f7d5093d21a2b0422bd6c139d49b72a435b871798ca5a000db5f6a
6
+ metadata.gz: f870d33006961640028804fb1103a04815a81d631dc11ea1ac71801fb22da9ca1a87e56cce78de5e9d3488dc73c532d3737164dace444ba3eecb72e8f6b75a2f
7
+ data.tar.gz: 6dbcb3009f801d14e81447d00a86793c61253284f7f8ac863a06e6d113de53811da672867382ab3e59b41040ca6c19cbe08fd2307b44f60eac01dda4060381af
data/README.md CHANGED
@@ -491,13 +491,13 @@ recording.output # <-- the usual output is attached to the recording itself
491
491
  And a recording can be replayed:
492
492
 
493
493
  ```ruby
494
- Orchestra.replay_recording InvitationService, recording
494
+ recording.replay InvitationService
495
495
  ```
496
496
 
497
497
  You can override the inputs passed in when replaying:
498
498
 
499
499
  ```ruby
500
- Orchestra.replay_recording InvitationService, recording, :account_name => "dhh"
500
+ recording.replay InvitationService, :account_name => "dhh"
501
501
  ```
502
502
 
503
503
  If you want to serialize/persist the recording, just use `JSON.dump`:
@@ -511,8 +511,8 @@ You can replay the recording using `JSON.load`:
511
511
 
512
512
  ```ruby
513
513
  json = File.read "tmp/recording.json"
514
- recording = JSON.load json
515
- Orchestra.replay_recording InvitationService, recording
514
+ recording = Orchestra::Recording(JSON.load json, symbolize_names: true)
515
+ recording.replay InvitationService
516
516
  ```
517
517
 
518
518
  ## Installation
data/lib/orchestra.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "forwardable"
2
2
  require "invokr"
3
3
  require "observer"
4
- require "securerandom"
5
4
 
6
5
  module Orchestra
7
6
  extend self
@@ -14,16 +13,5 @@ module Orchestra
14
13
  Conductor.new.execute operation, inputs
15
14
  end
16
15
 
17
- def replay_recording operation, store, input = {}
18
- store = Util.recursively_symbolize store
19
- input = input.merge store[:input]
20
- svc_recordings = store[:service_recordings]
21
- Recording.replay operation, input, svc_recordings
22
- end
23
-
24
- load File.expand_path('../orchestra/errors.rb', __FILE__)
25
- end
26
-
27
- Dir[File.expand_path '../orchestra/**/*.rb', __FILE__].each do |rb_file|
28
- load rb_file
16
+ Dir[File.expand_path '../orchestra/**/*.rb', __FILE__].each &method(:load)
29
17
  end
@@ -7,6 +7,9 @@ module Orchestra
7
7
  @thread_pool = ThreadPool.new
8
8
  @observers = Set.new
9
9
  self.thread_count = Configuration.thread_count
10
+ if block_given?
11
+ raise ArgumentError, "Supplied block to Conductor.new; did you mean to invoke Orchestra::Operation.new do … end?"
12
+ end
10
13
  end
11
14
 
12
15
  def execute operation, input = {}
@@ -17,7 +20,7 @@ module Orchestra
17
20
  end
18
21
 
19
22
  def record *args
20
- recording = Recording.new
23
+ recording = Recording.fresh
21
24
  add_observer recording
22
25
  execute *args do |execution|
23
26
  execution.add_observer recording
@@ -91,10 +94,10 @@ module Orchestra
91
94
  alias_method :__getobj__, :service
92
95
  alias_method :__setobj__, :service=
93
96
 
94
- def initialize service, recording
95
- super service
96
- @recording = recording
97
- end
97
+ def initialize service, recording
98
+ super service
99
+ @recording = recording
100
+ end
98
101
 
99
102
  def kind_of? klass
100
103
  super or service.kind_of? klass
@@ -20,7 +20,6 @@ module Orchestra
20
20
 
21
21
  def add_step name_or_object, args = {}, &block
22
22
  name, step = case name_or_object
23
- when nil then build_anonymous_step block
24
23
  when Operation then build_embedded_operation_step name_or_object
25
24
  when ::String, ::Symbol then build_inline_step name_or_object, block
26
25
  else build_object_step name_or_object, args
@@ -37,15 +36,6 @@ module Orchestra
37
36
  step.freeze
38
37
  end
39
38
 
40
- def build_anonymous_step block
41
- step = Step::InlineStep.build &block
42
- unless step.provisions.size == 1
43
- raise ArgumentError, "Could not infer name for step from a provision"
44
- end
45
- name = step.provisions.fetch 0
46
- [name, step]
47
- end
48
-
49
39
  def build_embedded_operation_step operation
50
40
  name = object_name operation
51
41
  [name || operation.result, operation]
@@ -92,7 +82,7 @@ module Orchestra
92
82
  end
93
83
 
94
84
  def result *args, &block
95
- args << nil if args.empty?
85
+ args << :result if args.empty?
96
86
  step = @builder.add_step *args, &block
97
87
  name ||= step.provisions.fetch 0
98
88
  self.result = name
@@ -13,12 +13,18 @@ module Orchestra
13
13
  end
14
14
 
15
15
  class MissingProvisionError < Error
16
+ attr_writer :name
17
+
16
18
  def initialize missing_provisions
17
19
  @missing_provisions = missing_provisions
18
20
  end
19
21
 
22
+ def name
23
+ @name ||= "<anonymous>"
24
+ end
25
+
20
26
  def to_s
21
- "failed to supply output: #{list_out @missing_provisions}"
27
+ "Node `#{name}' failed to supply output: #{list_out @missing_provisions}"
22
28
  end
23
29
  end
24
30
 
@@ -4,12 +4,12 @@ module Orchestra
4
4
 
5
5
  def build operation, conductor, input = {}
6
6
  run_list = RunList.build operation.steps, operation.result, input.keys
7
- node = Node.new run_list, operation.name, input
7
+ node = Recording::Node.new run_list, operation.name, input
8
8
  Operation.new conductor, run_list, input, node
9
9
  end
10
10
 
11
11
  def execute_step step, input
12
- node = Node.new step, 'anonymous', input
12
+ node = Recording::Node.new step, 'anonymous', input
13
13
  operation_execution = Operation.new Conductor.new, {}, input, node
14
14
  Step.execute step, node.name, operation_execution
15
15
  end
@@ -50,6 +50,9 @@ module Orchestra
50
50
  def process name, step
51
51
  output = Step.execute step, name, self
52
52
  state.merge! output
53
+ rescue MissingProvisionError => error
54
+ error.name = name.inspect
55
+ raise error
53
56
  end
54
57
 
55
58
  def ensure_inputs_are_present!
@@ -95,7 +98,7 @@ module Orchestra
95
98
  end
96
99
 
97
100
  def execute
98
- @node = Node.new step, name, input
101
+ @node = Recording::Node.new step, name, input
99
102
  operation_execution.publish :step_entered, node, node.input
100
103
  output = step.process invoke
101
104
  operation_execution.publish :step_exited, node, output
@@ -1,9 +1,15 @@
1
1
  module Orchestra
2
2
  class Recording
3
- attr :input, :output, :services
3
+ def self.fresh
4
+ services = Hash.new do |hsh, service_name| hsh[service_name] = [] end
5
+ new services
6
+ end
7
+
8
+ attr_accessor :input, :output
9
+ attr :services
4
10
 
5
- def initialize
6
- @services = Hash.new do |hsh, service_name| hsh[service_name] = [] end
11
+ def initialize services
12
+ @services = services
7
13
  end
8
14
 
9
15
  def update event_name, *args
@@ -19,10 +25,14 @@ module Orchestra
19
25
  end
20
26
  end
21
27
 
28
+ def [] attr
29
+ to_h[attr]
30
+ end
31
+
22
32
  def to_h
23
33
  {
24
- :input => input,
25
- :output => output,
34
+ :input => input,
35
+ :output => output,
26
36
  :service_recordings => services,
27
37
  }
28
38
  end
@@ -31,13 +41,20 @@ module Orchestra
31
41
  generator.generate to_h
32
42
  end
33
43
 
34
- def self.replay operation, input, service_recordings
44
+ def replay operation, override_input = {}
35
45
  replayed_services = {}
36
- service_recordings.each do |svc, service_recording|
46
+ services.each do |svc, service_recording|
37
47
  replayed_services[svc] = Playback.build service_recording
38
48
  end
39
49
  conductor = Conductor.new replayed_services
40
- conductor.execute operation, input
50
+ conductor.execute operation, input.merge(override_input)
41
51
  end
42
52
  end
53
+
54
+ def Recording serialized_recording
55
+ recording = Recording.new serialized_recording[:service_recordings]
56
+ recording.input = serialized_recording[:input]
57
+ recording.output = serialized_recording[:output]
58
+ recording.freeze
59
+ end
43
60
  end
@@ -0,0 +1,54 @@
1
+ module Orchestra
2
+ class Recording
3
+ # Reader object to expose operations and steps to the outside world
4
+ class Node
5
+ attr :input, :name
6
+
7
+ extend Forwardable
8
+
9
+ def_delegators :@node, :provisions, :dependencies, :optional_dependencies,
10
+ :required_dependencies
11
+
12
+ def initialize step_or_operation, name, input
13
+ @name = name
14
+ @node = step_or_operation
15
+ @input = format_input input
16
+ freeze
17
+ end
18
+
19
+ def to_h
20
+ {
21
+ dependencies: dependencies,
22
+ input: input,
23
+ name: name,
24
+ optional_dependencies: optional_dependencies,
25
+ provisions: provisions,
26
+ required_dependencies: required_dependencies,
27
+ }
28
+ end
29
+
30
+ def inspect
31
+ params = to_h.each_with_object [] do |(key, val), list|
32
+ list << "#{key}=#{val.inspect}"
33
+ end
34
+ "#<Orchestra::Node #{params.join ', '}>"
35
+ end
36
+
37
+ def operation?
38
+ @node.is_a? Operation
39
+ end
40
+
41
+ def step?
42
+ not operation?
43
+ end
44
+
45
+ private
46
+
47
+ def format_input input
48
+ @node.dependencies.each_with_object Hash.new do |dep, hsh|
49
+ hsh[dep] = input[dep] if input.has_key? dep
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -61,7 +61,7 @@ module Orchestra
61
61
  def initialize result, input_names = []
62
62
  @input_names = input_names
63
63
  @steps_hash = {}
64
- @required = [result]
64
+ @required = Set.new [result]
65
65
  @result = result
66
66
  freeze
67
67
  end
@@ -109,8 +109,10 @@ module Orchestra
109
109
 
110
110
  def require step
111
111
  supplied_by_input = input_names.method :include?
112
- deps = step.required_dependencies.reject &supplied_by_input
113
- @required.concat deps
112
+ required_deps = step.required_dependencies.reject &supplied_by_input
113
+ @required.merge required_deps
114
+ required = @required.method :include?
115
+ @required.merge step.optional_dependencies.reject &required
114
116
  true
115
117
  end
116
118
 
@@ -23,18 +23,6 @@ module Orchestra
23
23
  [hsh, ary]
24
24
  end
25
25
 
26
- def recursively_symbolize obj
27
- case obj
28
- when Array
29
- obj.map &method(:recursively_symbolize)
30
- when Hash then
31
- obj.each_with_object Hash.new do |(k, v), out_hsh|
32
- out_hsh[k.to_sym] = recursively_symbolize v
33
- end
34
- else obj
35
- end
36
- end
37
-
38
26
  def to_lazy_thunk obj
39
27
  if obj.respond_to? :to_proc and not obj.is_a? Symbol
40
28
  obj
@@ -1,3 +1,3 @@
1
1
  module Orchestra
2
- VERSION = "0.9.4" unless defined? VERSION
2
+ VERSION = "0.9.5" unless defined? VERSION
3
3
  end
data/orchestra.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^test/})
19
19
  spec.require_paths = %w(lib)
20
20
 
21
- spec.add_dependency "invokr"
21
+ spec.add_dependency "invokr", "~> 0.9.7"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.6"
24
24
  spec.add_development_dependency "pry"
@@ -21,12 +21,28 @@ module Examples
21
21
  end
22
22
  end
23
23
 
24
- finally :print do
25
- depends_on :io
24
+ finally do
25
+ depends_on :stdout
26
26
  iterates_over :fizzbuzz
27
27
  execute do |str|
28
- io.puts str
28
+ stdout.puts str
29
29
  end
30
30
  end
31
31
  end
32
+
33
+ InteractiveFizzBuzz = Orchestra::Operation.new do
34
+ step :prompt_user do
35
+ depends_on :stdin, :stdout
36
+ provides :up_to
37
+ execute do
38
+ stdout.puts "How high would you like to go?"
39
+ stdout.print " => "
40
+ stdout.flush
41
+ value = stdin.gets
42
+ value.to_i
43
+ end
44
+ end
45
+
46
+ finally Examples::FizzBuzz
47
+ end
32
48
  end
@@ -8,7 +8,7 @@ module Examples
8
8
  provides :followers
9
9
  execute do
10
10
  json = http.get "flutter.io", "/users/#{account_name}/followers"
11
- JSON.parse json
11
+ JSON.parse json
12
12
  end
13
13
  end
14
14
 
@@ -46,7 +46,7 @@ class RecordingTelemetryTest < Minitest::Test
46
46
  ],
47
47
  },
48
48
  },
49
- :print => {
49
+ :__finally__ => {
50
50
  :input => {
51
51
  :fizzbuzz => [
52
52
  "1",
@@ -66,15 +66,15 @@ class RecordingTelemetryTest < Minitest::Test
66
66
  "FizzBuzz",
67
67
  ],
68
68
  },
69
- :output => { :print => [] },
69
+ :output => { :__finally__ => [] },
70
70
  }
71
71
  },
72
72
  :output => [],
73
73
  }
74
74
  end
75
75
 
76
- def execute_with_telemetry telemetry, io
77
- conductor = Orchestra::Conductor.new :io => io
76
+ def execute_with_telemetry telemetry, stdout
77
+ conductor = Orchestra::Conductor.new :stdout => stdout
78
78
 
79
79
  conductor.add_observer TelemetryRecorder.new telemetry
80
80
 
@@ -1,3 +1,5 @@
1
+ require "yaml"
2
+
1
3
  class ReplayableOperationTest < Minitest::Test
2
4
  include Examples::InvitationService::TestSetup
3
5
 
@@ -6,16 +8,20 @@ class ReplayableOperationTest < Minitest::Test
6
8
  recording = execute_for_real
7
9
 
8
10
  # Write the recording out to a file. In this case, a StringIO is used for
9
- # simplicity, and we serialize into JSON
11
+ # simplicity, and we serialize into JSON. The to_h is important as
12
+ # hashes can be coerced back into Recording objects.
10
13
  file = StringIO.new
11
14
  file.write JSON.dump recording
12
15
  file.rewind
13
16
 
17
+ # Re-load the recording from JSON using Orchestra::Recording()
18
+ parsed_json = JSON.parse file.read, symbolize_names: true
19
+ recording = Orchestra::Recording(parsed_json)
20
+
14
21
  # Replay the operation, directing SMTP to an alternative service object
15
22
  smtp_service = build_example_smtp
16
- Orchestra.replay_recording(
23
+ recording.replay(
17
24
  Examples::InvitationService,
18
- JSON.load(file.read),
19
25
  :smtp => smtp_service,
20
26
  )
21
27
 
@@ -33,12 +33,10 @@ class DSLTest < Minitest::Test
33
33
  end
34
34
  assert_equal :foo, operation.result
35
35
 
36
- error = assert_raises ArgumentError do
37
- operation = Orchestra::Operation.new do
38
- result do execute do 'foo' end end
39
- end
36
+ operation = Orchestra::Operation.new do
37
+ result do execute do 'foo' end end
40
38
  end
41
- assert_equal "Could not infer name for step from a provision", error.message
39
+ assert_equal :result, operation.result
42
40
 
43
41
  operation = Orchestra::Operation.new do
44
42
  result do
@@ -119,4 +117,14 @@ class DSLTest < Minitest::Test
119
117
 
120
118
  assert_equal "Must supply at least one step", error.message
121
119
  end
120
+
121
+ def test_cannot_accidentally_try_to_define_a_conductor_with_dsl
122
+ error = assert_raises ArgumentError do
123
+ Orchestra::Conductor.new do
124
+ self.result = :foo
125
+ end
126
+ end
127
+
128
+ assert_equal "Supplied block to Conductor.new; did you mean to invoke Orchestra::Operation.new do … end?", error.message
129
+ end
122
130
  end
@@ -1,9 +1,13 @@
1
1
  class NodeTest < Minitest::Test
2
2
  def test_inspect
3
- node = Orchestra::Node.new Examples::FizzBuzz, "Examples::FizzBuzz", {}
3
+ node = Orchestra::Recording::Node.new(
4
+ Examples::FizzBuzz,
5
+ "Examples::FizzBuzz",
6
+ {},
7
+ )
4
8
 
5
9
  assert_equal(
6
- "#<Orchestra::Node dependencies=[:array, :fizzbuzz, :io, :up_to], input={}, name=\"Examples::FizzBuzz\", optional_dependencies=[], provisions=[:array, :fizzbuzz, :print], required_dependencies=[:io, :up_to]>",
10
+ "#<Orchestra::Node dependencies=[:array, :fizzbuzz, :stdout, :up_to], input={}, name=\"Examples::FizzBuzz\", optional_dependencies=[], provisions=[:__finally__, :array, :fizzbuzz], required_dependencies=[:stdout, :up_to]>",
7
11
  node.inspect,
8
12
  )
9
13
  end
@@ -19,6 +19,24 @@ module OperationTest
19
19
  assert_equal %(Missing input :sentence), error.message
20
20
  end
21
21
 
22
+ def test_adds_name_to_missing_provision_error
23
+ operation = Orchestra::Operation.new do
24
+ result :foo do
25
+ provides :bar, :baz
26
+ execute do nil end
27
+ end
28
+ end
29
+
30
+ error = assert_raises Orchestra::MissingProvisionError do
31
+ operation.execute
32
+ end
33
+
34
+ assert_equal(
35
+ "Node `:foo' failed to supply output: :bar and :baz",
36
+ error.message,
37
+ )
38
+ end
39
+
22
40
  def test_mutating_inputs
23
41
  operation = build_mutator
24
42
 
@@ -16,6 +16,29 @@ class RunListTest < Minitest::Test
16
16
  assert_equal %w(foo⇒bar bar⇒baz baz⇒qux qux⇒res), run_list.step_names
17
17
  end
18
18
 
19
+ def test_does_not_discard_steps_that_would_override_defaults
20
+ steps = {
21
+ 'foo' => OpenStruct.new(
22
+ :optional_dependencies => [],
23
+ :required_dependencies => [:bar],
24
+ :provisions => [:baz],
25
+ ),
26
+ 'qux' => OpenStruct.new(
27
+ :optional_dependencies => [:baz],
28
+ :required_dependencies => [],
29
+ :provisions => [:res],
30
+ ),
31
+ }
32
+ builder = assemble_builder steps
33
+ builder.input_names.concat [:bar]
34
+
35
+ builder.sort!
36
+ builder.prune!
37
+ run_list = builder.build
38
+
39
+ assert_equal %w(foo qux), run_list.step_names
40
+ end
41
+
19
42
  def test_supplying_dependencies
20
43
  builder.input_names << :baz
21
44
 
@@ -78,7 +78,7 @@ class StepTest < Minitest::Test
78
78
  error = assert_raises Orchestra::MissingProvisionError do step.execute end
79
79
 
80
80
  assert_equal(
81
- "failed to supply output: :foo, :bar and :baz",
81
+ "Node `<anonymous>' failed to supply output: :foo, :bar and :baz",
82
82
  error.message,
83
83
  )
84
84
  end
@@ -92,7 +92,7 @@ class StepTest < Minitest::Test
92
92
  error = assert_raises Orchestra::MissingProvisionError do step.execute end
93
93
 
94
94
  assert_equal(
95
- "failed to supply output: :foo",
95
+ "Node `<anonymous>' failed to supply output: :foo",
96
96
  error.message,
97
97
  )
98
98
  end
@@ -3,18 +3,4 @@ class UtilTest < Minitest::Test
3
3
  assert_equal "foo/bar", Orchestra::Util.to_snake_case("Foo::Bar")
4
4
  assert_equal "foo_bar", Orchestra::Util.to_snake_case("FOOBar")
5
5
  end
6
-
7
- def test_recursive_symbolizing
8
- expected_hsh = {
9
- foo: [{
10
- bar: { baz: 'qux' },
11
- },{
12
- ping: ['pong'],
13
- }],
14
- }
15
-
16
- actual_hsh = Orchestra::Util.recursively_symbolize JSON.load JSON.dump expected_hsh
17
-
18
- assert_equal expected_hsh, actual_hsh
19
- end
20
6
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ntl-orchestra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ntl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2015-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: invokr
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.9.7
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.9.7
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -90,9 +90,9 @@ files:
90
90
  - lib/orchestra/dsl/steps.rb
91
91
  - lib/orchestra/errors.rb
92
92
  - lib/orchestra/execution.rb
93
- - lib/orchestra/node.rb
94
93
  - lib/orchestra/operation.rb
95
94
  - lib/orchestra/recording.rb
95
+ - lib/orchestra/recording/node.rb
96
96
  - lib/orchestra/recording/playback.rb
97
97
  - lib/orchestra/run_list.rb
98
98
  - lib/orchestra/step.rb
@@ -1,52 +0,0 @@
1
- module Orchestra
2
- # Reader object to expose operations and steps to the outside world
3
- class Node
4
- attr :input, :name
5
-
6
- extend Forwardable
7
-
8
- def_delegators :@node, :provisions, :dependencies, :optional_dependencies,
9
- :required_dependencies
10
-
11
- def initialize step_or_operation, name, input
12
- @name = name
13
- @node = step_or_operation
14
- @input = format_input input
15
- freeze
16
- end
17
-
18
- def to_h
19
- {
20
- dependencies: dependencies,
21
- input: input,
22
- name: name,
23
- optional_dependencies: optional_dependencies,
24
- provisions: provisions,
25
- required_dependencies: required_dependencies,
26
- }
27
- end
28
-
29
- def inspect
30
- params = to_h.each_with_object [] do |(key, val), list|
31
- list << "#{key}=#{val.inspect}"
32
- end
33
- "#<Orchestra::Node #{params.join ', '}>"
34
- end
35
-
36
- def operation?
37
- @node.is_a? Operation
38
- end
39
-
40
- def step?
41
- not operation?
42
- end
43
-
44
- private
45
-
46
- def format_input input
47
- @node.dependencies.each_with_object Hash.new do |dep, hsh|
48
- hsh[dep] = input[dep] if input.has_key? dep
49
- end
50
- end
51
- end
52
- end