clomp 0.0.3 → 0.0.4

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: 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: