ntl-orchestra 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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