bogo 0.2.14 → 0.2.15

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: 730a00461fb1d2b71a79a959bec8085111781a1ac542443566f875f9c9560e45
4
- data.tar.gz: 7225927bd86221c434caf7f9808f87c17c7b71a1e7839ec172157521876bf551
3
+ metadata.gz: 3c54ebb5a6708a864ecac0a28f00ac6195ec7ea8cbf4b45af0938e819dcbb352
4
+ data.tar.gz: d433b7b015699094dfb387e301627259bb1bd5fedce8b737a3975f23a1893903
5
5
  SHA512:
6
- metadata.gz: c3351892aae400d4035470522093bd231f6611d8e955338ac29af84d7ff594b498b863ee63fce80272b42cb3aa3bb4e13e32f3c95f67fe6c66c73ea8ac8cdfed
7
- data.tar.gz: a9cac6cfbb9df030f965ca3e6d180343ba8445a1bbffd7ea029b02a45dc05f4846d81211e5ba3c8cbc2a99b83c4683715e3e62179c1e879c9a866502692ca49d
6
+ metadata.gz: 976fc3309852ef467a1407a74e70c32b4ebb42d168e28feb32f0a1171239ca26e5dfb8c004ac60daf93cd9aeff4f68ce616728be33cfbe2d485850a5e4888a77
7
+ data.tar.gz: 7bd54f01ae3b64183caf8582e93c2d34e28ddb2e3fbaeeb4eb49b04ef45c2cd3eb0807974749a34fa7dbbbb28d1eecacf71988e9675e51740eecc97ca7282d88
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v0.2.15
2
+ * [Logger] Fix frozen string modification (#6)
3
+ * [Stack] Add stack
4
+
1
5
  # v0.2.14
2
6
  * [Logger] Add logging helpers
3
7
 
data/CONTRIBUTING.md CHANGED
@@ -1,22 +1,18 @@
1
1
  # Contributing
2
2
 
3
- ## Branches
3
+ ## Fixes
4
4
 
5
- ### `master` branch
5
+ Have a fix to some bug you want to submit? Well you're
6
+ awesome. Please just include a description of the bug
7
+ (or link to originating issue) and test coverage on the
8
+ modifications.
6
9
 
7
- The master branch is the current stable released version.
10
+ ## New Features
8
11
 
9
- ### `develop` branch
10
-
11
- The develop branch is the current edge of development.
12
-
13
- ## Pull requests
14
-
15
- * https://github.com/spox/bogo/pulls
16
-
17
- Please base all pull requests of the `develop` branch. Merges to
18
- `master` only occur through the `develop` branch. Pull requests
19
- based on `master` will likely be cherry picked.
12
+ Have a new feature you want to add? Well you're awesome
13
+ too! It may be a good idea to submit an issue first to
14
+ describe the desired feature and get any feedback. Please
15
+ be sure to include tests.
20
16
 
21
17
  ## Issues
22
18
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2018 Chris Roberts
1
+ Copyright 2022 Chris Roberts
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
@@ -10,4 +10,4 @@
10
10
  distributed under the License is distributed on an "AS IS" BASIS,
11
11
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  See the License for the specific language governing permissions and
13
- limitations under the License.
13
+ limitations under the License.
data/bogo.gemspec CHANGED
@@ -12,9 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.license = "Apache 2.0"
13
13
  s.add_runtime_dependency "hashie"
14
14
  s.add_runtime_dependency "multi_json"
15
- s.add_runtime_dependency "concurrent-ruby", "~> 1.1.3"
16
15
  s.add_development_dependency "pry"
17
16
  s.add_development_dependency "minitest"
18
- s.add_development_dependency "rake", "~> 10"
17
+ s.add_development_dependency "rake"
19
18
  s.files = Dir["lib/**/*"] + %w(bogo.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
20
19
  end
@@ -1,5 +1,3 @@
1
- require 'bogo'
2
-
3
1
  module Bogo
4
2
  # Animal stylings on strings
5
3
  module AnimalStrings
@@ -24,7 +22,5 @@ module Bogo
24
22
  def snake(string)
25
23
  string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').gsub('-', '_').downcase
26
24
  end
27
-
28
25
  end
29
-
30
26
  end
@@ -1,10 +1,6 @@
1
- require 'bogo'
2
-
3
1
  module Bogo
4
-
5
2
  # Constant helper
6
3
  module Constants
7
-
8
4
  # Convert string to constant
9
5
  #
10
6
  # @param string [String] full constant name
@@ -40,7 +36,5 @@ module Bogo
40
36
  constantize(klass.join('::'))
41
37
  end
42
38
  end
43
-
44
39
  end
45
-
46
40
  end
@@ -1,15 +1,12 @@
1
- require 'bogo'
2
1
  require 'tempfile'
3
2
 
4
3
  module Bogo
5
4
  # Tempfile that will destroy itself when closed
6
5
  class EphemeralFile < Tempfile
7
-
8
6
  # Override to remove file after close
9
7
  def close
10
8
  super
11
9
  delete
12
10
  end
13
-
14
11
  end
15
12
  end
@@ -7,7 +7,6 @@ require 'http/request'
7
7
  # library to allow easy sharing. It is the responsibility of the user
8
8
  # to ensure the http gem is available!
9
9
  class HTTP::Request
10
-
11
10
  # Override to implicitly apply proxy as required
12
11
  #
13
12
  # NOTE: If dealing with https request, force port so CONNECT request
@@ -54,5 +53,4 @@ class HTTP::Request
54
53
  end
55
54
  "CONNECT #{@uri.host}:#{dest_port} HTTP/#{version}"
56
55
  end
57
-
58
56
  end
data/lib/bogo/lazy.rb CHANGED
@@ -1,21 +1,35 @@
1
- require 'bogo'
2
1
  require 'multi_json'
2
+ require 'monitor'
3
3
  require 'digest/sha2'
4
4
 
5
5
  module Bogo
6
6
  # Adds functionality to facilitate laziness
7
7
  module Lazy
8
-
9
8
  # Instance methods for laziness
10
9
  module InstanceMethods
11
10
 
11
+ def self.included(klass)
12
+ klass.include(MonitorMixin)
13
+ klass.instance_variable_set(:@calling_on_missing, false)
14
+ klass.class_eval do
15
+ alias_method :unlazy_initialize, :initialize
16
+ def initialize(*args, **opts, &block)
17
+ @data = nil
18
+ @dirty = Smash.new
19
+ unlazy_initialize(*args, **opts, &block)
20
+ end
21
+ end
22
+ end
23
+
12
24
  # @return [Smash] argument hash
13
25
  def data
14
- unless(@data)
15
- @data = Smash.new
16
- self.class.attributes.each do |key, value|
17
- if(value.has_key?('default'))
18
- @data[key] = value['default']
26
+ synchronize do
27
+ unless(@data)
28
+ @data = Smash.new
29
+ self.class.attributes.each do |key, value|
30
+ if(value.has_key?('default'))
31
+ @data[key] = value['default']
32
+ end
19
33
  end
20
34
  end
21
35
  end
@@ -24,15 +38,17 @@ module Bogo
24
38
 
25
39
  # @return [Smash] updated data
26
40
  def dirty
27
- unless(@dirty)
28
- @dirty = Smash.new
41
+ synchronize do
42
+ unless(@dirty)
43
+ @dirty = Smash.new
44
+ end
29
45
  end
30
46
  @dirty
31
47
  end
32
48
 
33
49
  # @return [Smash] current data state
34
50
  def attributes
35
- data.merge(dirty)
51
+ synchronize { data.merge(dirty) }
36
52
  end
37
53
 
38
54
  # Create new instance
@@ -40,20 +56,22 @@ module Bogo
40
56
  # @param args [Hash]
41
57
  # @return [self]
42
58
  def load_data(args={})
43
- args = args.to_smash
44
- @data = Smash.new
45
- self.class.attributes.each do |name, options|
46
- val = args[name]
47
- if(options[:required] && !args.has_key?(name) && !options.has_key?(:default))
48
- raise ArgumentError.new("Missing required option: `#{name}`")
49
- end
50
- if(val.nil? && !args.has_key?(name) && options[:default])
51
- if(options[:default])
52
- val = options[:default].respond_to?(:call) ? options[:default].call : options[:default]
59
+ synchronize do
60
+ args = args.to_smash
61
+ @data = Smash.new
62
+ self.class.attributes.each do |name, options|
63
+ val = args[name]
64
+ if(options[:required] && !args.has_key?(name) && !options.has_key?(:default))
65
+ raise ArgumentError.new("Missing required option: `#{name}`")
66
+ end
67
+ if(val.nil? && !args.has_key?(name) && options[:default])
68
+ if(options[:default])
69
+ val = options[:default].respond_to?(:call) ? options[:default].call : options[:default]
70
+ end
71
+ end
72
+ if(args.has_key?(name) || val)
73
+ self.send("#{name}=", val)
53
74
  end
54
- end
55
- if(args.has_key?(name) || val)
56
- self.send("#{name}=", val)
57
75
  end
58
76
  end
59
77
  self
@@ -65,9 +83,11 @@ module Bogo
65
83
  #
66
84
  # @return [self]
67
85
  def valid_state
68
- data.merge!(dirty)
69
- dirty.clear
70
- @_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data.inspect).to_s)
86
+ synchronize do
87
+ data.merge!(dirty)
88
+ dirty.clear
89
+ @_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data.inspect).to_s)
90
+ end
71
91
  self
72
92
  end
73
93
 
@@ -76,14 +96,16 @@ module Bogo
76
96
  # @param attr [String, Symbol] name of attribute
77
97
  # @return [TrueClass, FalseClass] model or attribute is dirty
78
98
  def dirty?(attr=nil)
79
- if(attr)
80
- dirty.has_key?(attr)
81
- else
82
- if(@_checksum)
83
- !dirty.empty? ||
84
- @_checksum != Digest::SHA256.hexdigest(MultiJson.dump(data.inspect).to_s)
99
+ synchronize do
100
+ if(attr)
101
+ dirty.has_key?(attr)
85
102
  else
86
- true
103
+ if(@_checksum)
104
+ !dirty.empty? ||
105
+ @_checksum != Digest::SHA256.hexdigest(MultiJson.dump(data.inspect).to_s)
106
+ else
107
+ true
108
+ end
87
109
  end
88
110
  end
89
111
  end
@@ -100,19 +122,20 @@ module Bogo
100
122
 
101
123
  # @return [Hash]
102
124
  def to_h
103
- Hash[
104
- attributes.map{|k,v|
105
- [k, v.is_a?(Array) ?
106
- v.map{|x| x.respond_to?(:to_h) ? x.to_h : x} :
107
- v.respond_to?(:to_h) ? v.to_h : v]
108
- }
109
- ]
125
+ synchronize do
126
+ Hash[
127
+ attributes.map{|k,v|
128
+ [k, v.is_a?(Array) ?
129
+ v.map{|x| x.respond_to?(:to_h) ? x.to_h : x} :
130
+ v.respond_to?(:to_h) ? v.to_h : v]
131
+ }
132
+ ]
133
+ end
110
134
  end
111
135
  end
112
136
 
113
137
  # Class methods for laziness
114
138
  module ClassMethods
115
-
116
139
  # Disable dirty state
117
140
  def always_clean!
118
141
  self.class_eval do
@@ -264,11 +287,9 @@ module Bogo
264
287
  @attributes = attrs.to_smash
265
288
  true
266
289
  end
267
-
268
290
  end
269
291
 
270
292
  class << self
271
-
272
293
  # Injects laziness into class
273
294
  #
274
295
  # @param klass [Class]
@@ -278,16 +299,12 @@ module Bogo
278
299
  extend ClassMethods
279
300
 
280
301
  class << self
281
-
282
302
  def inherited(klass)
283
303
  klass.set_attributes(self.attributes.to_smash)
284
304
  end
285
-
286
305
  end
287
306
  end
288
307
  end
289
-
290
308
  end
291
-
292
309
  end
293
310
  end
data/lib/bogo/logger.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "concurrent"
2
1
  require "logger"
3
2
 
4
3
  module Bogo
@@ -46,9 +45,9 @@ module Bogo
46
45
  logger_args = [$stderr]
47
46
  end
48
47
  @base_args = logger_args
49
- logger = ::Logger.new(*@base_args)
50
- logger.level = :fatal
51
- @wrapped_logger = Concurrent::MVar.new(logger)
48
+ @logger = ::Logger.new(*@base_args)
49
+ @logger.level = :fatal
50
+ @lock = Mutex.new
52
51
  end
53
52
 
54
53
  # Create a new logger with the sub-name provided
@@ -56,7 +55,7 @@ module Bogo
56
55
  # @param name [String] sub-name for logger
57
56
  # @return [Logger]
58
57
  def named(name)
59
- new_name = self.progname.to_s
58
+ new_name = self.progname.to_s.dup
60
59
  new_name << "." unless new_name.empty?
61
60
  new_name << name
62
61
  new_logger = Logger.new(*@base_args)
@@ -71,15 +70,9 @@ module Bogo
71
70
  next if l_m.to_s.start_with?("_") || l_m.to_s == "object_id"
72
71
  class_eval <<-EOC
73
72
  def #{l_m}(*ma, &mb)
74
- wrapped_logger.borrow { |l| l.send(:#{l_m}, *ma, &mb) }
73
+ @lock.synchronize { @logger.send(:#{l_m}, *ma, &mb) }
75
74
  end
76
75
  EOC
77
76
  end
78
-
79
- protected
80
-
81
- def wrapped_logger
82
- @wrapped_logger
83
- end
84
77
  end
85
78
  end
@@ -1,16 +1,12 @@
1
- require 'bogo'
2
-
3
1
  module Bogo
4
2
  # Memoization helpers
5
3
  module Memoization
6
-
7
4
  # Lock for providing exclusive access
8
5
  EXCLUSIVE_LOCK = Mutex.new
9
6
  # Holder for global memoization items
10
7
  GLOBAL_MEMOS = Smash.new
11
8
 
12
9
  class << self
13
-
14
10
  # Clean up isolated memoizations
15
11
  #
16
12
  # @param object_id [Object]
@@ -38,7 +34,6 @@ module Bogo
38
34
  GLOBAL_MEMOS.clear
39
35
  end
40
36
  end
41
-
42
37
  end
43
38
 
44
39
  # Memoize data
@@ -123,6 +118,5 @@ module Bogo
123
118
  end
124
119
  true
125
120
  end
126
-
127
121
  end
128
122
  end
@@ -1,10 +1,7 @@
1
- require 'bogo'
2
-
3
1
  module Bogo
4
2
  # Specialized priority based queue
5
3
  # @note does not allow duplicate objects to be queued
6
4
  class PriorityQueue
7
-
8
5
  # Create a new priority queue
9
6
  #
10
7
  # @return [self]
@@ -24,10 +21,12 @@ module Bogo
24
21
  def push(item, cost=nil, &block)
25
22
  lock.synchronize do
26
23
  if(queue[item])
27
- raise ArgumentError.new "Item already exists in queue. Items must be unique! (#{item})"
24
+ raise ArgumentError,
25
+ "Item already exists in queue. Items must be unique! (#{item})"
28
26
  end
29
27
  unless(cost || block_given?)
30
- raise ArgumentError.new 'Cost must be provided as parameter or block!'
28
+ raise ArgumentError,
29
+ 'Cost must be provided as parameter or block!'
31
30
  end
32
31
  @block_costs += 1 if cost.nil?
33
32
  queue[item] = cost || block
@@ -45,10 +44,12 @@ module Bogo
45
44
  items.each do |item_pair|
46
45
  item, cost = item_pair
47
46
  if(queue[item])
48
- raise ArgumentError.new "Item already exists in queue. Items must be unique! (#{item})"
47
+ raise ArgumentError,
48
+ "Item already exists in queue. Items must be unique! (#{item})"
49
49
  end
50
50
  unless(cost.is_a?(Numeric) || cost.is_a?(Proc))
51
- raise ArgumentError.new "Cost must be provided as parameter or proc! (item: #{item})"
51
+ raise ArgumentError,
52
+ "Cost must be provided as parameter or proc! (item: #{item})"
52
53
  end
53
54
  @block_costs += 1 if cost.is_a?(Proc)
54
55
  queue[item] = cost
@@ -106,7 +107,5 @@ module Bogo
106
107
  protected
107
108
 
108
109
  attr_reader :queue, :lock
109
-
110
110
  end
111
-
112
111
  end
data/lib/bogo/retry.rb CHANGED
@@ -1,10 +1,6 @@
1
- require 'bogo'
2
-
3
1
  module Bogo
4
-
5
2
  # Perform action and retry until successful or abort
6
3
  class Retry
7
-
8
4
  # Create a type of retry
9
5
  #
10
6
  # @param type [String, Symbol] name of retry type
@@ -38,7 +34,8 @@ module Bogo
38
34
  # @return [self]
39
35
  def initialize(args={}, &block)
40
36
  unless(block)
41
- raise ArgumentError.new 'Expecting block but no block was provided!'
37
+ raise ArgumentError,
38
+ 'Expecting block but no block was provided!'
42
39
  end
43
40
  args = args.to_smash
44
41
  @ui = args[:ui]
@@ -58,7 +55,8 @@ module Bogo
58
55
  # @return [Object] result of action
59
56
  def run!
60
57
  if(dead)
61
- raise RuntimeError.new "Action has already reached maximum allowed attempts (#{max_attempts})!"
58
+ raise RuntimeError,
59
+ "Action has already reached maximum allowed attempts (#{max_attempts})!"
62
60
  else
63
61
  begin
64
62
  log_attempt!
@@ -110,7 +108,6 @@ module Bogo
110
108
 
111
109
  # Flat retry implementation
112
110
  class Flat < Retry
113
-
114
111
  # @return [Numeric]
115
112
  attr_reader :wait_interval
116
113
 
@@ -133,12 +130,10 @@ module Bogo
133
130
  def wait_on_failure(*_)
134
131
  wait_interval
135
132
  end
136
-
137
133
  end
138
134
 
139
135
  # Linear retry implementation
140
136
  class Linear < Retry
141
-
142
137
  # @return [Numeric]
143
138
  attr_reader :wait_interval
144
139
 
@@ -161,12 +156,10 @@ module Bogo
161
156
  def wait_on_failure(*_)
162
157
  wait_interval * attempts
163
158
  end
164
-
165
159
  end
166
160
 
167
161
  # Exponential retry implementation
168
162
  class Exponential < Retry
169
-
170
163
  # @return [Numeric]
171
164
  attr_reader :wait_interval
172
165
  # @return [Numeric]
@@ -196,9 +189,6 @@ module Bogo
196
189
  def wait_on_failure(*_)
197
190
  retries == 0 ? wait_interval : (wait_interval + retries) ** wait_exponent
198
191
  end
199
-
200
192
  end
201
-
202
193
  end
203
-
204
194
  end
data/lib/bogo/smash.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  require 'hashie'
2
2
  require 'digest/sha2'
3
- require 'bogo'
4
3
 
5
4
  module Bogo
6
-
7
5
  # Customized Hash
8
6
  class Smash < Hash
9
-
10
7
  class NoValue; end
11
8
  NO_VALUE = NoValue.new
12
9
 
@@ -25,7 +22,7 @@ module Bogo
25
22
  if(args.first.is_a?(::Hash))
26
23
  base = args.shift
27
24
  end
28
- super *args
25
+ super(*args)
29
26
  if(base)
30
27
  self.replace(base.to_smash)
31
28
  end
@@ -89,7 +86,8 @@ module Bogo
89
86
  elsif(args.size > 1)
90
87
  default_value = args.pop
91
88
  elsif(args.size < 1)
92
- raise ArgumentError.new("Default value must be provided for #fetch")
89
+ raise ArgumentError,
90
+ "Default value must be provided for #fetch"
93
91
  end
94
92
  result = retrieve(*args)
95
93
  if(result == NO_VALUE)
@@ -105,7 +103,8 @@ module Bogo
105
103
  # @return [Object] value set
106
104
  def set(*args)
107
105
  unless(args.size > 1)
108
- raise ArgumentError.new 'Set requires at least one key and a value'
106
+ raise ArgumentError,
107
+ 'Set requires at least one key and a value'
109
108
  end
110
109
  value = args.pop
111
110
  set_key = args.pop
@@ -132,13 +131,11 @@ module Bogo
132
131
  def checksum
133
132
  Digest::SHA256.hexdigest(self.to_smash(:sorted).to_s)
134
133
  end
135
-
136
134
  end
137
135
  end
138
136
 
139
137
  # Hook helper into toplevel `Hash`
140
138
  class Hash
141
-
142
139
  # Convert to Smash
143
140
  #
144
141
  # @return [Smash]
@@ -198,11 +195,9 @@ class Hash
198
195
  args.include?(:freeze) ? obj.freeze : obj
199
196
  end
200
197
  end
201
-
202
198
  end
203
199
 
204
200
  class Array
205
-
206
201
  # Iterates searching for Hash types to auto convert
207
202
  #
208
203
  # @return [Array]
@@ -215,7 +210,6 @@ class Array
215
210
  end
216
211
  end
217
212
  end
218
-
219
213
  end
220
214
 
221
215
  unless(defined?(Smash))