duck_puncher 4.4.2 → 5.0.1

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
- SHA1:
3
- metadata.gz: 62f4cac1d15e159d6ba58d71681cec7e34be8c71
4
- data.tar.gz: 53ee95a89344c33f8960cf5d957cbb5dbf6d3562
2
+ SHA256:
3
+ metadata.gz: d1fcb68e87edfbb74d3a7c6d1d3699e4d636825096d63a4bd0ebf5084e159bf8
4
+ data.tar.gz: f5ef839a1ee7c73bf22ede9d831142b4d68b97de1c0581269c798e2a86732603
5
5
  SHA512:
6
- metadata.gz: ea6d68c9efd49449907ccfb6aab5b810f6b0081ce399817afc78804a813cf0c66feea9ea0cfe74492e3b1091baa3011cc0cc1492d2bdb2ed6ca5e27433f9e9eb
7
- data.tar.gz: dd5bf802c09382798460d26c81650588f10f64de8e2cba77fec53d82e55fffb932fe785178233037d96965b53b9093c7088e2c2f87c608c23828df71f81b05c8
6
+ metadata.gz: 19cc97cf751f1bd1bd2b140da0ecc267b02832ddfbd5ce165682409e575c233784fd4f45035e320d254965dedb933f6726473b5d1f2e34d0aa98abdf6fabd2f5
7
+ data.tar.gz: d17270cbdb1634ead0c15e3c24238eeea6b50270fc5e01371a28bc60c9aeaaa007852ab5f385620b99707087cf8b1165d9b7a9fe8de6677710d0a8fd6943ed66
data/duck_puncher.gemspec CHANGED
@@ -13,16 +13,16 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/ridiculous/duck_puncher"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files`.split($/).keep_if { |f| f =~ /duck_puncher/ and f !~ %r{test/} }
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.test_files = spec.files.grep(%r{^(test)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.required_ruby_version = ">= 2.0.0"
22
22
 
23
23
  spec.add_runtime_dependency "usable", ">= 3.3"
24
24
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "bundler", ">= 1.3"
26
26
  spec.add_development_dependency "rake", '~> 10.1'
27
27
  spec.add_development_dependency "minitest", '~> 5.0'
28
28
  spec.add_development_dependency "minitest-reporters", '~> 1.1'
data/lib/duck_puncher.rb CHANGED
@@ -23,7 +23,7 @@ module DuckPuncher
23
23
 
24
24
  class << self
25
25
  # @description Include additional functionality
26
- include Registration # [:register, :deregister]
26
+ include Registration # [:register, :register!, :deregister]
27
27
  include Decoration # [:decorators, :build_decorator_class, :decorate, :cached_decorators, :undecorate]
28
28
  include Utilities # [:lookup_constant, :redefine_constant]
29
29
  include AncestralHash # [:ancestral_hash]
@@ -62,6 +62,14 @@ module DuckPuncher
62
62
  @punched_ducks ||= Set.new
63
63
  end
64
64
 
65
+ # Register an extension with a target class
66
+ # When given a block, the block is used to create an anonymous module
67
+ # @param target [Class,Module,Object] constant or instance to extend
68
+ # @param mods [Array<Module>] modules to extend or mix into the target. The last argument can be a hash of options to customize the extension
69
+ # @option :only [Symbol, Array<Symbol>] list of methods to extend onto the target (the module must have these defined)
70
+ # @option :method [Symbol,String] the method used to apply the module, e.g. :extend (:include)
71
+ # @option :before [Proc] A hook that is called with the target class before #punch
72
+ # @option :after [Proc] A hook that is called with the target class after #punch
65
73
  def register(*)
66
74
  target, *_ = super
67
75
  decorators[target] = build_decorator_class(*Ducks[target])
@@ -24,5 +24,5 @@ ducks = [
24
24
  ]
25
25
  ducks << [ActiveRecord::Base, DuckPuncher::Ducks::ActiveRecord] if defined?(Rails) && defined?(ActiveRecord) && defined?(ActiveRecord::Base)
26
26
  ducks.each do |duck|
27
- DuckPuncher.register *duck
27
+ DuckPuncher.register(*duck)
28
28
  end
@@ -5,6 +5,8 @@ module DuckPuncher
5
5
  # @param target [String,Class] Class or module to punch
6
6
  # @param mod [String,Module] The module that defines the extensions
7
7
  # @param [Hash] options to modify the duck #punch method behavior
8
+ # @option options :only [Symbol, Array<Symbol>] list of methods to extend onto the target (the module must have these defined)
9
+ # @option options :method [Symbol,String] the method used to apply the module, e.g. :extend (:include)
8
10
  # @option options :before [Proc] A hook that is called with the target class before +punch+
9
11
  # @option options :after [Proc] A hook that is called with the target class after +punch+
10
12
  def initialize(target, mod, options = {})
@@ -14,9 +16,9 @@ module DuckPuncher
14
16
  end
15
17
 
16
18
  # @param [Hash] opts to modify punch
17
- # @option options [Class] :target Specifies the class to be punched
18
- # @option options [Array,Symbol] :only Specifies the methods to extend onto the current object
19
- # @option options [Symbol,String] :method Specifies if the methods should be included or prepended (:include)
19
+ # @option options :target [Class] Specifies the class to be punched (overrides @target)
20
+ # @option options :only [Array,Symbol] Specifies the methods to extend onto the current object
21
+ # @option options :method [Symbol,String] Specifies if the methods should be included or prepended (:include)
20
22
  # @return [Class] The class that was just punched
21
23
  def call(opts = {})
22
24
  opts = options.merge(opts)
@@ -1,50 +1,57 @@
1
1
  module DuckPuncher
2
- module Ducks
3
- module ActiveRecord
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
-
8
- def associations?
9
- associations.present?
10
- end
11
-
12
- def associations
13
- reflections.select { |key, _| send(key).present? rescue nil }.keys
14
- end
15
-
16
- module ClassMethods
17
- def except_for(*ids)
18
- scoped.where("#{quoted_table_name}.id NOT IN (?)", ids)
19
- end
20
-
21
- def since(time)
22
- scoped.where("#{quoted_table_name}.created_at > ?", time)
23
- end
24
-
25
- alias created_since since
26
-
27
- def before(time)
28
- scoped.where("#{quoted_table_name}.created_at < ?", time)
29
- end
30
-
31
- def updated_since(time)
32
- scoped.where("#{quoted_table_name}.updated_at > ?", time)
33
- end
34
-
35
- def between(start_at, end_at)
36
- scoped.where("#{quoted_table_name}.created_at BETWEEN ? AND ", start_at, end_at)
37
- end
38
-
39
- def latest
40
- scoped.order("#{quoted_table_name}.id ASC").last
41
- end
42
-
43
- # shim for backwards compatibility with Rails 3
44
- def scoped
45
- where(nil)
46
- end if ::Rails::VERSION::MAJOR > 3
47
- end
48
- end
49
- end
2
+ module Ducks
3
+ module ActiveRecord
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ def associations?
9
+ associations.present?
10
+ end
11
+
12
+ def associations
13
+ results = []
14
+ refls = send respond_to?(:reflections) ? :reflections : :_reflections
15
+ refls.each do |key, reflection|
16
+ begin
17
+ if reflection.macro.to_s =~ /many/ ? public_send(key).exists? : public_send(key).present?
18
+ results << key
19
+ end
20
+ rescue
21
+ nil
22
+ end
23
+ end
24
+ results
25
+ end
26
+
27
+ module ClassMethods
28
+ def except_for(*ids)
29
+ scoped.where("#{quoted_table_name}.#{primary_key} NOT IN (?)", ids)
30
+ end
31
+
32
+ def since(time)
33
+ scoped.where("#{quoted_table_name}.created_at > ?", time)
34
+ end
35
+
36
+ alias created_since since
37
+
38
+ def before(time)
39
+ scoped.where("#{quoted_table_name}.created_at < ?", time)
40
+ end
41
+
42
+ def updated_since(time)
43
+ scoped.where("#{quoted_table_name}.updated_at > ?", time)
44
+ end
45
+
46
+ def between(start_at, end_at)
47
+ scoped.where("#{quoted_table_name}.created_at BETWEEN ? AND ", start_at, end_at)
48
+ end
49
+
50
+ # shim for backwards compatibility with Rails 3
51
+ def scoped
52
+ where(nil)
53
+ end if ::Rails::VERSION::MAJOR > 3
54
+ end
55
+ end
56
+ end
50
57
  end
@@ -41,7 +41,7 @@ module DuckPuncher
41
41
 
42
42
  def to_s
43
43
  if lines.any?
44
- lines.join.gsub /^\s{#{find_indent_size(lines.first)}}/, ''
44
+ lines.join.gsub(/^\s{#{find_indent_size(lines.first)}}/, '')
45
45
  else
46
46
  ''
47
47
  end
@@ -5,10 +5,17 @@ module DuckPuncher
5
5
  Marshal.load Marshal.dump self
6
6
  end unless defined? clone!
7
7
 
8
- def require!(file_or_gem, version = '')
8
+ def require!(file_or_gem, version = '', patience: 1)
9
9
  if DuckPuncher::GemInstaller.new.perform(file_or_gem, version)
10
- require file_or_gem.tr('-', '/')
10
+ if require file_or_gem.tr('-', '/')
11
+ true
12
+ elsif patience > 0
13
+ sleep 0.005
14
+ require!(file_or_gem, version, patience: patience - 1)
15
+ end
11
16
  end
17
+ rescue ::LoadError
18
+ require!(file_or_gem, version, patience: patience - 1) unless patience.zero?
12
19
  end
13
20
 
14
21
  # @description Returns a new decorated version of ourself with the punches mixed in (adds ancestors decorators)
@@ -32,15 +39,17 @@ module DuckPuncher
32
39
  self
33
40
  end
34
41
 
35
- def track
42
+ def track!(patience: 1)
36
43
  begin
37
- require 'object_tracker' || raise(LoadError)
38
- rescue LoadError
44
+ require 'object_tracker' || raise(::LoadError)
45
+ rescue ::LoadError
39
46
  DuckPuncher.(Object, only: :require!) unless respond_to? :require!
40
47
  require! 'object_tracker'
41
48
  end
42
- extend ::ObjectTracker
43
- track_all!
49
+ ::ObjectTracker.(self)
50
+ rescue ::Exception
51
+ sleep 0.005
52
+ track!(patience: patience - 1) unless patience.zero?
44
53
  end
45
54
  end
46
55
  end
@@ -19,7 +19,7 @@ class DuckPuncher::GemInstaller
19
19
  def perform(*args)
20
20
  require 'rubygems/dependency_installer'
21
21
  installer = Gem::DependencyInstaller.new(install_dir: Bundler.bundle_path.to_s, bin_dir: RbConfig::CONFIG['bindir'])
22
- installer.install *args.reject(&:empty?)
22
+ installer.install(*args.reject(&:empty?))
23
23
  installer.installed_gems.each do |gem|
24
24
  full_load_path = Bundler.bundle_path.join('gems', "#{gem.name}-#{gem.version}", "lib")
25
25
  next if $LOAD_PATH.include?(full_load_path.to_s)
@@ -7,7 +7,7 @@ module DuckPuncher
7
7
  end
8
8
 
9
9
  def self.write(file_name, key, load_path)
10
- FileUtils.mkdir(dir_name) unless File.exists?(dir_name)
10
+ FileUtils.mkdir(dir_name) unless File.exist?(dir_name)
11
11
  data = read(file_name)
12
12
  key = key.to_sym
13
13
  data[key] ||= {}
@@ -18,7 +18,7 @@ module DuckPuncher
18
18
  end
19
19
 
20
20
  def self.read(file_name)
21
- if File.exists?(dir_name.join file_name)
21
+ if File.exist?(dir_name.join file_name)
22
22
  JSON.parse File.read(dir_name.join file_name), symbolize_names: true
23
23
  else
24
24
  {}
@@ -1,25 +1,37 @@
1
1
  module DuckPuncher
2
2
  # @note When updating this file please update comment regarding this module in duck_puncher.rb
3
3
  module Registration
4
- def register(target, *mods)
4
+ # Register an extension with a target class
5
+ # When given a block, the block is used to create an anonymous module
6
+ # @param target [Class,Module,Object] constant or instance to extend
7
+ # @param mods [Array<Module>] modules to extend or mix into the target. The last argument can be a hash of options to customize the extension
8
+ # @option :only [Symbol, Array<Symbol>] list of methods to extend onto the target (the module must have these defined)
9
+ # @option :method [Symbol,String] the method used to apply the module, e.g. :extend (:include)
10
+ # @option :before [Proc] A hook that is called with the target class before #punch
11
+ # @option :after [Proc] A hook that is called with the target class after #punch
12
+ def register(target, *mods, &block)
5
13
  options = mods.last.is_a?(Hash) ? mods.pop : {}
14
+ mods << Module.new(&block) if block
6
15
  target = DuckPuncher.lookup_constant target
7
16
  Ducks.list[target] = Set.new [] unless Ducks.list.key?(target)
8
17
  mods = Array(mods).each do |mod|
9
- duck = UniqueDuck.new Duck.new target, mod, options
18
+ duck = UniqueDuck.new Duck.new(target, mod, options)
10
19
  Ducks.list[target] << duck
11
20
  end
12
21
  [target, *mods]
13
22
  end
14
23
 
15
- def register!(*args)
16
- register *args
17
- call args.first
24
+ # Register an extension and then immediately activate it
25
+ # See #register for accepted arguments
26
+ def register!(*args, &block)
27
+ register(*args, &block)
28
+ call(args.first)
18
29
  end
19
30
 
20
- def deregister(*classes)
21
- classes.each &Ducks.list.method(:delete)
22
- classes.each &decorators.method(:delete)
31
+ # Remove extensions for a given class or list of classes
32
+ def deregister(*targets)
33
+ targets.each(&Ducks.list.method(:delete))
34
+ targets.each(&decorators.method(:delete))
23
35
  end
24
36
  end
25
37
  end
@@ -1,3 +1,3 @@
1
1
  module DuckPuncher
2
- VERSION = '4.4.2'.freeze
2
+ VERSION = '5.0.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duck_puncher
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.2
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-11 00:00:00.000000000 Z
11
+ date: 2021-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: usable
@@ -28,14 +28,14 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
@@ -83,21 +83,10 @@ dependencies:
83
83
  description: Administer precision punches
84
84
  email:
85
85
  - arebuckley@gmail.com
86
- executables:
87
- - console
86
+ executables: []
88
87
  extensions: []
89
88
  extra_rdoc_files: []
90
89
  files:
91
- - ".gitignore"
92
- - ".ruby-gemset"
93
- - ".ruby-version"
94
- - ".travis.yml"
95
- - CHANGELOG.md
96
- - Gemfile
97
- - LICENSE.txt
98
- - README.md
99
- - Rakefile
100
- - bin/console
101
90
  - duck_puncher.gemspec
102
91
  - lib/duck_puncher.rb
103
92
  - lib/duck_puncher/ancestral_hash.rb
@@ -119,23 +108,11 @@ files:
119
108
  - lib/duck_puncher/unique_duck.rb
120
109
  - lib/duck_puncher/utilities.rb
121
110
  - lib/duck_puncher/version.rb
122
- - test/fixtures/test_classes.rb
123
- - test/fixtures/wut.rb
124
- - test/lib/duck_puncher/duck_test.rb
125
- - test/lib/duck_puncher/enumerable_test.rb
126
- - test/lib/duck_puncher/hash_test.rb
127
- - test/lib/duck_puncher/method_test.rb
128
- - test/lib/duck_puncher/module_test.rb
129
- - test/lib/duck_puncher/numeric_test.rb
130
- - test/lib/duck_puncher/object_test.rb
131
- - test/lib/duck_puncher/string_test.rb
132
- - test/lib/duck_puncher_test.rb
133
- - test/test_helper.rb
134
111
  homepage: https://github.com/ridiculous/duck_puncher
135
112
  licenses:
136
113
  - MIT
137
114
  metadata: {}
138
- post_install_message:
115
+ post_install_message:
139
116
  rdoc_options: []
140
117
  require_paths:
141
118
  - lib
@@ -150,21 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
127
  - !ruby/object:Gem::Version
151
128
  version: '0'
152
129
  requirements: []
153
- rubyforge_project:
154
- rubygems_version: 2.5.1
155
- signing_key:
130
+ rubygems_version: 3.2.11
131
+ signing_key:
156
132
  specification_version: 4
157
133
  summary: Administer precision extensions (a.k.a "punches") to your favorite Ruby classes
158
- test_files:
159
- - test/fixtures/test_classes.rb
160
- - test/fixtures/wut.rb
161
- - test/lib/duck_puncher/duck_test.rb
162
- - test/lib/duck_puncher/enumerable_test.rb
163
- - test/lib/duck_puncher/hash_test.rb
164
- - test/lib/duck_puncher/method_test.rb
165
- - test/lib/duck_puncher/module_test.rb
166
- - test/lib/duck_puncher/numeric_test.rb
167
- - test/lib/duck_puncher/object_test.rb
168
- - test/lib/duck_puncher/string_test.rb
169
- - test/lib/duck_puncher_test.rb
170
- - test/test_helper.rb
134
+ test_files: []
data/.gitignore DELETED
@@ -1,19 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- .duck_puncher/
19
- .byebug_history