duck_puncher 4.4.2 → 5.0.1
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 +5 -5
- data/duck_puncher.gemspec +3 -3
- data/lib/duck_puncher.rb +9 -1
- data/lib/duck_puncher/defaults.rb +1 -1
- data/lib/duck_puncher/duck.rb +5 -3
- data/lib/duck_puncher/ducks/active_record.rb +55 -48
- data/lib/duck_puncher/ducks/method.rb +1 -1
- data/lib/duck_puncher/ducks/object.rb +16 -7
- data/lib/duck_puncher/gem_installer.rb +1 -1
- data/lib/duck_puncher/json_storage.rb +2 -2
- data/lib/duck_puncher/registration.rb +20 -8
- data/lib/duck_puncher/version.rb +1 -1
- metadata +10 -46
- data/.gitignore +0 -19
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -10
- data/CHANGELOG.md +0 -20
- data/Gemfile +0 -9
- data/LICENSE.txt +0 -22
- data/README.md +0 -272
- data/Rakefile +0 -13
- data/bin/console +0 -30
- data/test/fixtures/test_classes.rb +0 -42
- data/test/fixtures/wut.rb +0 -7
- data/test/lib/duck_puncher/duck_test.rb +0 -45
- data/test/lib/duck_puncher/enumerable_test.rb +0 -64
- data/test/lib/duck_puncher/hash_test.rb +0 -23
- data/test/lib/duck_puncher/method_test.rb +0 -32
- data/test/lib/duck_puncher/module_test.rb +0 -9
- data/test/lib/duck_puncher/numeric_test.rb +0 -48
- data/test/lib/duck_puncher/object_test.rb +0 -78
- data/test/lib/duck_puncher/string_test.rb +0 -39
- data/test/lib/duck_puncher_test.rb +0 -71
- data/test/test_helper.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d1fcb68e87edfbb74d3a7c6d1d3699e4d636825096d63a4bd0ebf5084e159bf8
|
4
|
+
data.tar.gz: f5ef839a1ee7c73bf22ede9d831142b4d68b97de1c0581269c798e2a86732603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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", "
|
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])
|
data/lib/duck_puncher/duck.rb
CHANGED
@@ -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]
|
18
|
-
# @option options [Array,Symbol]
|
19
|
-
# @option options [Symbol,String]
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
@@ -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
|
-
|
43
|
-
|
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
|
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.
|
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.
|
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
|
-
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
data/lib/duck_puncher/version.rb
CHANGED
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
|
+
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:
|
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
|
-
|
154
|
-
|
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