clomp 0.0.3 → 0.0.4

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: 0e100e9861f2a2b799e088d4d4ac31d5e17fd376
4
- data.tar.gz: 156d3e65b3b7664ef2f2d1273d0d93967058fff8
3
+ metadata.gz: 3274c97946362d96e713004853c32790b28282bc
4
+ data.tar.gz: d1647e5d1bee604c2875ec40a6dbe974091935be
5
5
  SHA512:
6
- metadata.gz: 13c87f30b50cf897d32b06ebe9dbd6281227d6c58bde6169711f9e3627d3f005b3efe9ce0507440f050d2cdaa52a36bf77eebcc010a5108a67fe2ac4138507b0
7
- data.tar.gz: 7ef600eaa8d98c726da464d79dfef75391c8134051f6bb6f14b593db1cbadd2e6977c8f4551223bb9e9486d6ee9096bb4f3081ea0972e7076d938cc41b25a6c2
6
+ metadata.gz: b20d6816638ca8b9530df827610d3277538623b7f7ca95d09458d42341de994854e65e2033c9b3982eda326066ceedae9f9b6469aab8a71fed697e6c03497099
7
+ data.tar.gz: 2f7304738d7bc18c62ed79617119e7fd68af14b3e8b2cc42be7743c747747661d47158e0a9916877b296a48167d1ec8b5143c41b9494d7c0fddacab741609e90
data/.byebug_history CHANGED
@@ -1,3 +1,11 @@
1
+ exit
1
2
  c
2
- break
3
- _track.failure?
3
+ _callable_object = Callable[result, track, options, _self]
4
+ track.name
5
+ track
6
+ track.track_name
7
+ _callable_object
8
+ c
9
+ n
10
+ track.track_from
11
+ _callable_object
data/.gitignore CHANGED
@@ -10,3 +10,5 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+ .clomp-0.0.3.gem
14
+ /*.gem
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Clomp [![CircleCI](https://circleci.com/gh/rubyrider/Clomp.svg?style=svg)](https://circleci.com/gh/rubyrider/Clomp)
1
+ # Clomp [![CircleCI](https://circleci.com/gh/rubyrider/clomp.svg?style=svg)](https://circleci.com/gh/rubyrider/clomp)
2
2
 
3
3
  **Clomp gem provides a smooth, lightweight, productive and reusable way to build an operation using Railway oriented programing paradigm.**
4
4
  Clomp will give you an easy interface to complete your service operation. You can use it with any framework
@@ -27,11 +27,27 @@ specific step.
27
27
 
28
28
  Consider the following class:
29
29
  ```ruby
30
+ class AnotherOperation < Clomp::Operation
31
+ track :track_from_another_operation
32
+
33
+ def track_from_another_operation(options)
34
+ options[:hello_from_another_operation] = true
35
+ end
36
+ end
37
+
30
38
  class SingingOperation < Clomp::Operation
31
- # this block only executes on successful steps!
39
+ # Configure your operation for common tracks,
40
+ # configuration can be overridden from individual tracks
41
+ setup do |config|
42
+ config.pass_fast = true
43
+ config.fail_fast = true
44
+ config.optional = true
45
+ end
46
+
47
+ # this block only executes on failure step!
32
48
  # pass options to receive the operation states!
33
49
  add_track :get_lyrics do |options|
34
- # we call this a success state based block!
50
+ # we call this a failure state based block!
35
51
  options[:do_some_thing] = 10
36
52
  end
37
53
 
@@ -39,6 +55,10 @@ class SingingOperation < Clomp::Operation
39
55
 
40
56
  add_track :start_signing
41
57
 
58
+ # We can now share specific step from
59
+ # outsider operation
60
+ share :track_from_another_operation, from: AnotherOperation # Or 'AnotherOperation'
61
+
42
62
  finally :receive_price #final step, wont execute after this step!
43
63
 
44
64
  def get_instruments_ready(options, mutable_data: , **)
@@ -60,7 +80,7 @@ end
60
80
  ```
61
81
 
62
82
  ```ruby
63
- @result = SingingOperation.({singer_name: 'Base Baba'})
83
+ @result = SingingOperation[singer_name: 'Base Baba']
64
84
  @result.success? # => true
65
85
  @result.failure? # => false
66
86
  ```
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "the_railway"
4
+ require "clomp"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -0,0 +1,14 @@
1
+ module Clomp
2
+ class Callable
3
+ class << self
4
+ def [](track, options, _self)
5
+ if track.track_from
6
+ #FIXME: stop executing! we will call it from our context
7
+ track.track_from.new(track_builders: [track], options: options, exec: false)
8
+ else
9
+ _self
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Clomp
2
+ class Configuration
3
+ attr_accessor :fail_fast, :pass_fast, :optional
4
+
5
+ # Constructor for Configuration file
6
+ def initialize
7
+ @pass_fast = false
8
+ @fail_fast = false
9
+ @optional = false
10
+ end
11
+ end
12
+ end
data/lib/clomp/errors.rb CHANGED
@@ -3,5 +3,6 @@ module Clomp
3
3
  NoTrackProvided = Class.new(ArgumentError)
4
4
  TrackNotDefined = Class.new(NotImplementedError)
5
5
  UnknownTrackType = Class.new(ArgumentError)
6
+ UnknownOperation = Class.new(NotImplementedError)
6
7
  end
7
8
  end
@@ -0,0 +1,23 @@
1
+ require 'pp'
2
+
3
+ module Clomp
4
+ class Executor
5
+ class << self
6
+ def [](result = {}, options, _self: )
7
+ result['tracks'].each do |track|
8
+ next unless track.track?
9
+
10
+ _callable_object = Callable[track, options, _self]
11
+
12
+ raise Errors::TrackNotDefined, "Please define the track in your operation/service: #{track.name} in #{_callable_object.class}" unless _callable_object.respond_to?(track.name)
13
+
14
+ _track = track.exec!(_callable_object, options)
15
+
16
+ break if _track.failure?
17
+ end
18
+
19
+ _self
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,79 +1,116 @@
1
1
  module Clomp
2
2
  class Operation
3
- attr_accessor :input, :options
3
+ attr_reader :result, :configs
4
4
 
5
- def call(track_builders: [], mutable_data: {}, immutable_data: {})
6
- @track_builders = track_builders
7
- @mutable_data = mutable_data
8
- @immutable_data = immutable_data
9
- @options ||= {}
10
- @options[:mutable_data] = mutable_data
11
- @options[:immutable_data] = immutable_data
5
+ # Constructor for operation object
6
+ #
7
+ # @param track_builders [Array] the list of tracks we define
8
+ # @param options [Hash] of options to be provided by .[] call/method
9
+ # @return [self]
10
+ def initialize(track_builders: [], options: {}, exec: true)
11
+ @options = options
12
+ # Setup result object!
13
+ @result = Result.new(
14
+ operation: self,
15
+ tracks: track_builders || [],
16
+ options: options || {}
17
+ )
12
18
 
13
- exec_steps!
19
+ @configs = self.class.setup_configuration
20
+
21
+ exec_steps! if exec
14
22
  end
15
23
 
16
24
  # Execute all the steps! Execute all the tracks!
17
25
  def exec_steps!
18
- @track_builders.each do |track|
19
- raise Errors::TrackNotDefined, "Please define track: #{track.name}" unless self.respond_to?(track.name)
20
-
21
- _track = track.exec!(self, @options)
22
-
23
- break if _track.failure?
24
- end
25
-
26
- @result = Result.new(@options, @track_builders, self)
26
+ Executor[result, @options, _self: self]
27
27
  end
28
28
 
29
29
  def executed_steps
30
- @track_builders.collect { |track| track.name if track.success? }.compact
30
+ @result['tracks'].collect {|track| track.name if track.success?}.compact
31
31
  end
32
32
 
33
33
  # Name of the steps defined in the operation class
34
34
  def steps
35
- @track_builders.collect { |track| track.name }
35
+ @result['tracks'].collect {|track| track.name}
36
36
  end
37
37
 
38
38
  class << self
39
39
 
40
40
  # To store and read all the tracks!
41
- attr_accessor :track_builders
41
+ attr_accessor :track_builders, :configs
42
+
43
+ # Operation wise configuration to control state
44
+ # All operation may not require fail fast
45
+ # All operation may not require pass fast
46
+ # Operation wise optional value could be different
47
+ #
48
+ # @yield [config] to mutate new configuration
49
+ #
50
+ # @return [Configuration] @config
51
+ def setup
52
+ @configs ||= Configuration.new
53
+
54
+ yield(@configs) if block_given?
55
+
56
+ @configs
57
+ end
58
+
59
+ alias_method :setup_configuration, :setup
60
+
61
+ # Share track from other operation
62
+ def share(track_name, from:, track_options: {}, &block)
63
+ @track_builders ||= []
64
+
65
+ _callable_class = from && from.kind_of?(String) ? Object.const_get(from) : from
66
+
67
+ raise UnknownOperation, 'Please provide a valid operation to share the steps for' unless _callable_class
68
+
69
+ @track_builders << build_track(track_name, track_options, :track, track_for: _callable_class , &block)
70
+ end
42
71
 
43
72
  # get track name and options!
44
73
  def track(track_name, track_options: {}, &block)
45
74
  @track_builders ||= []
46
75
 
47
- @track_builders << build_track(track_name, track_options, :track, &block)
76
+ @track_builders << build_track(track_name, track_options, :track, track_for: nil, &block)
48
77
  end
49
-
78
+
50
79
  # get the track name for the failure case!
51
80
  def failure(track_name, track_options: {}, &block)
52
81
  @track_builders ||= []
53
82
 
54
- @track_builders << build_track(track_name, track_options, :failed_track, &block)
83
+ @track_builders << build_track(track_name, track_options, :failed_track, track_for: nil, &block)
55
84
  end
56
-
85
+
57
86
  # get the track name for the final step! Only one step will be executed!
58
87
  def finally(track_name, track_options: {}, &block)
59
88
  @track_builders ||= []
60
-
61
- @track_builders << build_track(track_name, track_options, :finally, &block)
89
+
90
+ @track_builders << build_track(track_name, track_options, :finally, track_for: nil, &block)
91
+ end
92
+
93
+ def [](mutable_data = {}, immutable_data = {})
94
+ self.(mutable_data, immutable_data)
62
95
  end
63
96
 
64
97
  def call(mutable_data = {}, immutable_data = {})
65
- self.new.call(
98
+ new(
66
99
  track_builders: @track_builders,
67
- mutable_data: mutable_data,
68
- immutable_data: immutable_data
69
- )
100
+ options: {
101
+ mutable_data: mutable_data,
102
+ immutable_data: immutable_data
103
+ },
104
+ ).result
70
105
  end
71
106
 
72
107
  private
73
108
 
74
- def build_track(track_name, track_options = {}, track_type , &block)
75
- Track.new(name: track_name, track_options: track_options, track_type: track_type, &block)
109
+ def build_track(track_name, track_options = {}, track_type, track_for: nil, &block)
110
+ @configs ||= Configuration.new
111
+
112
+ TrackBuilder[track_name: track_name, track_options: track_options, track_type: track_type, track_for: track_for, &block]
76
113
  end
77
114
  end
78
115
  end
79
- end
116
+ end
data/lib/clomp/result.rb CHANGED
@@ -1,18 +1,58 @@
1
1
  module Clomp
2
2
  class Result
3
- include CommonStates
4
- extend Forwardable
3
+ attr_reader :options, :operation, :state
5
4
 
6
- attr_reader :options, :state, :operation
5
+ def initialize(options: {}, tracks: [], operation: nil)
6
+ @report = {}
7
+
8
+ @operation = set_prop :operation, operation || Operation.new
9
+ @tracks = set_prop :tracks, tracks || []
10
+ @options ||= {}
11
+ @immutable_data = set_prop :options, options
12
+ @state = ->(tracks) { tracks.select {|track| track.failure?}.count.zero? }
13
+ end
14
+
15
+ def success?
16
+ @state.(self[:tracks]) === true
17
+ end
18
+
19
+ def failure?
20
+ @state.(self[:tracks]) === false
21
+ end
22
+
23
+ def method_missing(method, *args)
24
+ if @operation.respond_to?(method)
25
+ @operation.send(method, *args)
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def [](key)
32
+ sym_key = to_sym_key(key)
33
+
34
+ self.instance_variable_get(sym_key)
35
+ end
36
+
37
+ def []=(key, value)
38
+ sym_key = to_sym_key(key)
39
+ self.instance_variable_set(sym_key, value)
40
+ end
41
+
42
+ def set_prop(key, value)
43
+ sym_key = to_sym_key(key)
44
+
45
+ self.instance_variable_set(sym_key, value)
46
+ end
7
47
 
8
- def_delegators :@operation, :steps, :executed_steps
48
+ private
9
49
 
10
- def initialize(options, tracks = [], operation)
11
- @options = options
12
- @tracks = tracks
13
- @error = nil
14
- @state = @tracks.select {|track| track.failure?}.count.zero? ? SUCCESS : FAILURE
15
- @operation = operation
50
+ def to_sym_key(key)
51
+ if key.is_a? Symbol
52
+ ('@' + key.to_s).to_sym
53
+ else
54
+ ('@' + key.to_s.delete('@')).to_sym
55
+ end
16
56
  end
17
57
  end
18
58
  end
data/lib/clomp/track.rb CHANGED
@@ -2,14 +2,15 @@ module Clomp
2
2
  class Track
3
3
  include Clomp::CommonStates
4
4
 
5
- attr_reader :name, :block, :track_options, :state, :error
5
+ attr_reader :name, :block, :track_options, :state, :error, :track_from
6
6
 
7
7
  VALID_TRACK_TYPES = %I(track failed_track finally catch)
8
8
 
9
- def initialize(name: (raise Errors::NoTrackProvided), track_options: {}, track_type: VALID_TRACK_TYPES.first, &block)
9
+ def initialize(name: (raise Errors::NoTrackProvided), track_options: {}, track_type: VALID_TRACK_TYPES.first, track_from: nil, &block)
10
10
  raise UnknownTrackType, 'Please provide a valid track type' unless VALID_TRACK_TYPES.include?(track_type)
11
11
 
12
12
  @name = name
13
+ @track_from = track_from
13
14
  @block = block
14
15
  @track_options = track_options
15
16
  @type = track_type
@@ -17,6 +18,20 @@ module Clomp
17
18
  @error = nil
18
19
  end
19
20
 
21
+ def type
22
+ @type
23
+ end
24
+
25
+ VALID_TRACK_TYPES.each do |track_type|
26
+ define_method "#{track_type}?" do
27
+ @type == track_type
28
+ end
29
+ end
30
+
31
+ def track?
32
+ @type == :track
33
+ end
34
+
20
35
  # Track#exec! executes the steps defined in the operation class
21
36
  def exec!(object, options)
22
37
  mark_as_failure! # going to execute! set to failure initially
@@ -27,7 +42,7 @@ module Clomp
27
42
  mark_as_success! if object.public_send(name.to_sym, options) != false
28
43
  end
29
44
 
30
- @block.(options) if success? && @block
45
+ @block.(options) if failure? && @block
31
46
 
32
47
  self
33
48
 
@@ -0,0 +1,9 @@
1
+ module Clomp
2
+ class TrackBuilder < Array
3
+ class << self
4
+ def [](track_name:, track_options: {}, track_for: nil, track_type:, &block)
5
+ Track.new(name: track_name, track_options: track_options, track_type: track_type, track_from: track_for, &block)
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/clomp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Clomp
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/clomp.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  require 'clomp/version'
2
2
  require 'clomp/common_states'
3
+ require 'clomp/track_builder'
3
4
  require 'clomp/operation'
4
5
  require 'clomp/track'
5
6
  require 'clomp/context'
6
7
  require 'clomp/errors'
7
8
  require 'clomp/result'
9
+ require 'clomp/configuration'
10
+ require 'clomp/callable'
11
+ require 'clomp/executor'
8
12
 
9
13
  module Clomp
10
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clomp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Irfan Ahmed
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-04 00:00:00.000000000 Z
11
+ date: 2018-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -89,12 +89,16 @@ files:
89
89
  - bin/setup
90
90
  - clomp.gemspec
91
91
  - lib/clomp.rb
92
+ - lib/clomp/callable.rb
92
93
  - lib/clomp/common_states.rb
94
+ - lib/clomp/configuration.rb
93
95
  - lib/clomp/context.rb
94
96
  - lib/clomp/errors.rb
97
+ - lib/clomp/executor.rb
95
98
  - lib/clomp/operation.rb
96
99
  - lib/clomp/result.rb
97
100
  - lib/clomp/track.rb
101
+ - lib/clomp/track_builder.rb
98
102
  - lib/clomp/version.rb
99
103
  homepage: https://github.com/rubyrider/clomp
100
104
  licenses: