nxt_pipeline 0.2.4 → 0.2.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
  SHA256:
3
- metadata.gz: 6b545c68dc71684330edc75197b306a9f87abfb90240efe4708d426299902782
4
- data.tar.gz: d47d498587927798476462538f3c42ea7a151080fe6cdbdccd56e0e12baa9d05
3
+ metadata.gz: 7aa1fdbbfb4c1d0eb99c72270cf13893f34fda78162abb749091600b1857f8bb
4
+ data.tar.gz: adce759515d5d7ee687eaf96221083127e089946945095d8ddf931348f4d4826
5
5
  SHA512:
6
- metadata.gz: ddfe39ac16d28a562a28f42e41205828f8ffe8c448b8135e798aecfd71a2083870e4faffc7e5fc0f1e19625d63eaf0f2930e1b2fbc21a6cb68987647446ae5de
7
- data.tar.gz: 76ef2fc1b046dac15ed2c5f913048ea304b9ceddcfcd7f6777b9a623026d87e49322ecae0219ce35813b86aabf30867debb667ec69157adebd1adfd0620e6b53
6
+ metadata.gz: f3a040fe24d3e4329d7241eba0d21c49f0696027bf8e39550a7cf473c3a80e7b86f1313a00fe4c78feac2a6621f8a6b55d7f6e05eadd0a674b5782bb70e8d3f2
7
+ data.tar.gz: a9e3ad99022ef92321e680e664207f296bd69f9ffe2f12edb8193f129e102fe4bc0b52363af769b4408ed36dcec8a29329bfedf0da06f28ae2c5929e54850a02
data/README.md CHANGED
@@ -76,7 +76,9 @@ pipeline.step to_s: 'This is the same as above' do |step, arg|
76
76
  end
77
77
  ```
78
78
 
79
- You can also define inline steps, meaning the block will be executed
79
+ You can also define inline steps, meaning the block will be executed. When you do not provide a :to_s option, type
80
+ will be used as :to_s option per default. When no type was given for an inline block the type of the inline block
81
+ will be set to :inline.
80
82
 
81
83
  ### Execution
82
84
 
@@ -106,6 +108,13 @@ NxtPipeline::Pipeline.execute('initial argument') do |p|
106
108
  end
107
109
  ```
108
110
 
111
+ You can query the steps of your pipeline simply by calling `pipeline.steps`. A NxtPipeline::Step will provide you with
112
+ an interface it's type, options, status (:success, :skipped, :failed), result, error and the index in the pipeline.
113
+
114
+ ```
115
+ pipeline.steps.first
116
+ ```
117
+
109
118
  ### Error callbacks
110
119
 
111
120
  Apart from defining constructors and steps you can also define error callbacks.
@@ -0,0 +1,13 @@
1
+ module NxtPipeline
2
+ class Logger
3
+ def initialize
4
+ @log = {}
5
+ end
6
+
7
+ attr_accessor :log
8
+
9
+ def call(step)
10
+ log[step.to_s] = step.status
11
+ end
12
+ end
13
+ end
@@ -7,15 +7,18 @@ module NxtPipeline
7
7
  def initialize(&block)
8
8
  @steps = []
9
9
  @error_callbacks = []
10
- @log = {}
10
+ @logger = Logger.new
11
11
  @current_step = nil
12
12
  @current_arg = nil
13
- @default_constructor = nil
13
+ @default_constructor_name = nil
14
14
  @registry = {}
15
+
15
16
  configure(&block) if block_given?
16
17
  end
17
18
 
18
- attr_reader :log
19
+ alias_method :configure, :tap
20
+
21
+ attr_accessor :logger, :steps
19
22
 
20
23
  # register steps with name and block
21
24
  def constructor(name, **opts, &constructor)
@@ -25,39 +28,60 @@ module NxtPipeline
25
28
  registry[name] = constructor
26
29
 
27
30
  return unless opts.fetch(:default, false)
28
- default_constructor ? (raise ArgumentError, 'Default step already defined') : self.default_constructor = constructor
31
+ set_default_constructor(name)
32
+ end
33
+
34
+ def set_default_constructor(name)
35
+ raise_duplicate_default_constructor if default_constructor_name.present?
36
+ self.default_constructor_name = name
37
+ end
38
+
39
+ def raise_duplicate_default_constructor
40
+ raise ArgumentError, 'Default step already defined'
29
41
  end
30
42
 
31
43
  def step(type = nil, **opts, &block)
44
+ type = type&.to_sym
45
+
32
46
  constructor = if block_given?
33
- # make first argument the to_s of step if given
34
- opts.merge!(to_s: type) if type && !opts.key?(:to_s)
47
+ # make type the :to_s of inline steps
48
+ # fall back to :inline if no type is given
49
+ type ||= :inline
50
+ opts.reverse_merge!(to_s: type)
35
51
  block
36
52
  else
37
53
  if type
54
+ raise_reserved_type_inline_error if type == :inline
38
55
  registry.fetch(type) { raise KeyError, "No step :#{type} registered" }
39
56
  else
57
+ # When no type was given we try to fallback to the type of the default constructor
58
+ type = default_constructor_name
59
+ # If none was given - raise
40
60
  default_constructor || (raise StandardError, 'No default step registered')
41
61
  end
42
62
  end
43
63
 
44
- steps << Step.new(constructor, **opts)
64
+ steps << Step.new(type, constructor, steps.count, **opts)
45
65
  end
46
66
 
47
67
  def execute(arg, &block)
48
- reset_log
49
- before_execute_callback.call(self, arg) if before_execute_callback.respond_to?(:call)
68
+ reset
69
+
50
70
  configure(&block) if block_given?
71
+ before_execute_callback.call(self, arg) if before_execute_callback.respond_to?(:call)
72
+
51
73
  result = steps.inject(arg) do |argument, step|
52
74
  execute_step(step, argument)
53
75
  end
76
+
54
77
  after_execute_callback.call(self, result) if after_execute_callback.respond_to?(:call)
55
78
  result
56
79
  rescue StandardError => error
57
- log[current_step] = { status: :failed, reason: "#{error.class}: #{error.message}" }
80
+ log_step(current_step)
58
81
  callback = find_error_callback(error)
59
82
 
60
83
  raise unless callback
84
+
61
85
  callback.call(current_step, current_arg, error)
62
86
  end
63
87
 
@@ -75,38 +99,46 @@ module NxtPipeline
75
99
  self.after_execute_callback = callback
76
100
  end
77
101
 
78
- def configure(&block)
79
- block.call(self)
80
- self
81
- end
82
-
83
102
  private
84
103
 
85
104
  attr_reader :error_callbacks, :registry
86
- attr_accessor :steps, :current_step, :current_arg, :default_constructor, :before_execute_callback, :after_execute_callback
87
- attr_writer :log
105
+ attr_accessor :current_step,
106
+ :current_arg,
107
+ :default_constructor_name,
108
+ :before_execute_callback,
109
+ :after_execute_callback
110
+
111
+ def default_constructor
112
+ return unless default_constructor_name
113
+
114
+ @default_constructor ||= registry[default_constructor_name.to_sym]
115
+ end
88
116
 
89
117
  def execute_step(step, arg)
90
- self.current_step = step.to_s
118
+ self.current_step = step
91
119
  self.current_arg = arg
92
120
  result = step.execute(arg)
93
-
94
- if result # step was successful
95
- log[current_step] = { status: :success }
96
- result
97
- else # step was not successful if nil or false
98
- log[current_step] = { status: :skipped }
99
- arg
100
- end
121
+ log_step(step)
122
+ result || arg
101
123
  end
102
124
 
103
125
  def find_error_callback(error)
104
126
  error_callbacks.find { |callback| callback.applies_to_error?(error) }
105
127
  end
106
128
 
107
- def reset_log
108
- self.log = {}
129
+ def log_step(step)
130
+ return unless logger.respond_to?(:call)
131
+
132
+ logger.call(step)
133
+ end
134
+
135
+ def reset
109
136
  self.current_arg = nil
137
+ self.current_step = nil
138
+ end
139
+
140
+ def raise_reserved_type_inline_error
141
+ raise ArgumentError, 'Type :inline is reserved for inline steps!'
110
142
  end
111
143
  end
112
144
  end
@@ -1,25 +1,41 @@
1
1
  module NxtPipeline
2
2
  class Step
3
- def initialize(constructor, **opts)
3
+ def initialize(type, constructor, index, **opts)
4
4
  define_attr_readers(opts)
5
+
6
+ @type = type
7
+ @index = index
8
+ @result = nil
5
9
  @opts = opts
10
+ @status = nil
6
11
  @constructor = constructor
12
+ @error = nil
7
13
  end
8
14
 
9
- attr_accessor :constructor
15
+ attr_reader :type, :result, :status, :error, :opts, :index
10
16
 
11
17
  def execute(arg)
12
- constructor.call(self, arg)
13
- # instance_exec(arg, &constructor)
18
+ self.result = constructor.call(self, arg)
19
+ set_status
20
+ result
21
+ rescue StandardError => e
22
+ self.status = :failed
23
+ self.error = e
24
+ raise
14
25
  end
15
26
 
16
27
  def to_s
17
- "#{self.class} opts => #{opts}"
28
+ "#{opts.merge(type: type)}"
29
+ end
30
+
31
+ def type?(potential_type)
32
+ type.to_sym == potential_type.to_sym
18
33
  end
19
34
 
20
35
  private
21
36
 
22
- attr_reader :opts
37
+ attr_writer :result, :status, :error
38
+ attr_reader :constructor
23
39
 
24
40
  def define_attr_readers(opts)
25
41
  opts.each do |key, value|
@@ -28,5 +44,9 @@ module NxtPipeline
28
44
  end
29
45
  end
30
46
  end
47
+
48
+ def set_status
49
+ self.status = result.present? ? :success : :skipped
50
+ end
31
51
  end
32
52
  end
@@ -1,3 +1,3 @@
1
1
  module NxtPipeline
2
- VERSION = "0.2.4".freeze
2
+ VERSION = "0.2.5".freeze
3
3
  end
data/lib/nxt_pipeline.rb CHANGED
@@ -1,4 +1,6 @@
1
+ require 'active_support/all'
1
2
  require 'nxt_pipeline/version'
3
+ require 'nxt_pipeline/logger'
2
4
  require 'nxt_pipeline/pipeline'
3
5
  require 'nxt_pipeline/step'
4
6
  require 'nxt_pipeline/error_callback'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nils Sommer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-06-14 00:00:00.000000000 Z
13
+ date: 2019-06-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -121,6 +121,7 @@ files:
121
121
  - bin/setup
122
122
  - lib/nxt_pipeline.rb
123
123
  - lib/nxt_pipeline/error_callback.rb
124
+ - lib/nxt_pipeline/logger.rb
124
125
  - lib/nxt_pipeline/pipeline.rb
125
126
  - lib/nxt_pipeline/step.rb
126
127
  - lib/nxt_pipeline/version.rb