nxt_pipeline 0.2.4 → 0.2.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
  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