dry-core 0.1.0 → 0.2.0
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 +4 -4
- data/.travis.yml +3 -3
- data/Gemfile +2 -0
- data/dry-core.gemspec +1 -0
- data/lib/dry-core.rb +1 -1
- data/lib/dry/core/deprecations.rb +94 -60
- data/lib/dry/core/extensions.rb +8 -0
- data/lib/dry/core/inflector.rb +134 -0
- data/lib/dry/core/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67a852de7314c5546f3d556d5f814270b1f4bd41
|
4
|
+
data.tar.gz: 8f34325aacc8019f2203c9486abdddacccaa4be1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c8b853aecef987b247b614ddc828c94bf403660fd38b751f5f12042b5984049a7971df2c82e4de7c176d2655c91964366ca2fbb8285875478d48c586f051831
|
7
|
+
data.tar.gz: 6afcac12f9ad38b5fea9d069b48b6a6488c757cbb0c791833eb24298d35e0d3346544c1a84fba14149ea83aeae88cfc6af94719b6268cf95f9ecbdbbe81b444f
|
data/.travis.yml
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.1.
|
4
|
+
- 2.1.10
|
5
5
|
- 2.2.5
|
6
6
|
- 2.3.1
|
7
|
-
- rbx-2
|
8
7
|
- jruby-9.1.4.0
|
9
8
|
- ruby-head
|
9
|
+
- rbx
|
10
10
|
|
11
11
|
before_install: gem update bundler
|
12
12
|
matrix:
|
13
13
|
allow_failures:
|
14
14
|
- rvm: ruby-head
|
15
|
+
- rvm: rbx
|
15
16
|
notifications:
|
16
17
|
email:
|
17
18
|
recipients:
|
@@ -25,4 +26,3 @@ notifications:
|
|
25
26
|
on_success: change # options: [always|never|change] default: always
|
26
27
|
on_failure: always # options: [always|never|change] default: always
|
27
28
|
on_start: false # default: false
|
28
|
-
|
data/Gemfile
CHANGED
data/dry-core.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.bindir = 'exe'
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ['lib']
|
28
|
+
spec.required_ruby_version = '>= 2.1.0'
|
28
29
|
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
|
29
30
|
|
30
31
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
data/lib/dry-core.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'dry
|
1
|
+
require 'dry/core'
|
@@ -29,16 +29,17 @@ module Dry
|
|
29
29
|
# Prints a warning
|
30
30
|
#
|
31
31
|
# @param [String] msg Warning string
|
32
|
-
def warn(msg)
|
33
|
-
|
32
|
+
def warn(msg, tag: nil)
|
33
|
+
tagged = "[#{tag || 'deprecated'}] #{msg.gsub(/^\s+/, '')}"
|
34
|
+
logger.warn(tagged)
|
34
35
|
end
|
35
36
|
|
36
37
|
# Wraps arguments with a standard message format and prints a warning
|
37
38
|
#
|
38
39
|
# @param [Object] name what is deprecated
|
39
40
|
# @param [String] msg additional message usually containing upgrade instructions
|
40
|
-
def announce(name, msg)
|
41
|
-
warn(deprecation_message(name, msg))
|
41
|
+
def announce(name, msg, tag: nil)
|
42
|
+
warn(deprecation_message(name, msg), tag: tag)
|
42
43
|
end
|
43
44
|
|
44
45
|
# @api private
|
@@ -72,83 +73,116 @@ module Dry
|
|
72
73
|
# Returns the logger used for printing warnings.
|
73
74
|
# You can provide your own with .set_logger!
|
74
75
|
#
|
75
|
-
# @param [String, Symbol] tag optional prefix for messages
|
76
76
|
# @param [IO] output output stream
|
77
77
|
#
|
78
78
|
# @return [Logger]
|
79
|
-
def logger(
|
79
|
+
def logger(output = nil)
|
80
80
|
if defined?(@logger)
|
81
81
|
@logger
|
82
82
|
else
|
83
|
-
set_logger!(output
|
83
|
+
set_logger!(output)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
87
|
# Sets a custom logger. This is a global settings.
|
88
88
|
#
|
89
89
|
# @option [IO] output output stream for messages
|
90
|
-
|
91
|
-
#
|
92
|
-
# TODO: Add support for per-module loggers so that at least
|
93
|
-
# tag option won't conflict.
|
94
|
-
def set_logger!(output: nil, tag: nil)
|
90
|
+
def set_logger!(output = nil)
|
95
91
|
@logger = Logger.new(output || $stdout)
|
96
|
-
@logger.formatter = proc { |_severity, _datetime, _progname, msg|
|
97
|
-
"[#{tag || 'deprecated'}] #{msg}\n"
|
98
|
-
}
|
92
|
+
@logger.formatter = proc { |_severity, _datetime, _progname, msg| "#{msg}\n" }
|
99
93
|
@logger
|
100
94
|
end
|
95
|
+
|
96
|
+
def [](tag)
|
97
|
+
Tagged.new(tag)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# @api private
|
102
|
+
class Tagged < Module
|
103
|
+
def initialize(tag)
|
104
|
+
@tag = tag
|
105
|
+
end
|
106
|
+
|
107
|
+
def extended(base)
|
108
|
+
base.extend Interface
|
109
|
+
base.deprecation_tag @tag
|
110
|
+
end
|
101
111
|
end
|
102
112
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
message
|
113
|
-
)
|
114
|
-
|
115
|
-
if new_name
|
116
|
-
undef_method old_name
|
117
|
-
define_method(old_name) do |*args, &block|
|
118
|
-
Deprecations.warn(full_msg)
|
119
|
-
__send__(new_name, *args, &block)
|
113
|
+
module Interface
|
114
|
+
# Sets/gets deprecation tag
|
115
|
+
#
|
116
|
+
# @option [String,Symbol] tag tag
|
117
|
+
def deprecation_tag(tag = nil)
|
118
|
+
if defined?(@deprecation_tag)
|
119
|
+
@deprecation_tag
|
120
|
+
else
|
121
|
+
@deprecation_tag = tag
|
120
122
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
123
|
+
end
|
124
|
+
|
125
|
+
# Issue a tagged warning message
|
126
|
+
#
|
127
|
+
# @param [String] msg warning message
|
128
|
+
def warn(msg)
|
129
|
+
Deprecations.warn(msg, tag: deprecation_tag)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Mark instance method as deprecated
|
133
|
+
#
|
134
|
+
# @param [Symbol] old_name deprecated method
|
135
|
+
# @param [Symbol] new_name replacement (not required)
|
136
|
+
# @option [String] message optional deprecation message
|
137
|
+
def deprecate(old_name, new_name = nil, message: nil)
|
138
|
+
full_msg = Deprecations.deprecated_method_message(
|
139
|
+
"#{self.name}##{old_name}",
|
140
|
+
new_name ? "#{self.name}##{new_name}" : nil,
|
141
|
+
message
|
142
|
+
)
|
143
|
+
mod = self
|
144
|
+
|
145
|
+
if new_name
|
146
|
+
undef_method old_name
|
147
|
+
|
148
|
+
define_method(old_name) do |*args, &block|
|
149
|
+
mod.warn(full_msg)
|
150
|
+
__send__(new_name, *args, &block)
|
151
|
+
end
|
152
|
+
else
|
153
|
+
aliased_name = :"#{old_name}_without_deprecation"
|
154
|
+
alias_method aliased_name, old_name
|
155
|
+
private aliased_name
|
156
|
+
undef_method old_name
|
157
|
+
|
158
|
+
define_method(old_name) do |*args, &block|
|
159
|
+
mod.warn(full_msg)
|
160
|
+
__send__(aliased_name, *args, &block)
|
161
|
+
end
|
129
162
|
end
|
130
163
|
end
|
131
|
-
end
|
132
164
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
165
|
+
# Mark class-level method as deprecated
|
166
|
+
#
|
167
|
+
# @param [Symbol] old_name deprecated method
|
168
|
+
# @param [Symbol] new_name replacement (not required)
|
169
|
+
# @option [String] message optional deprecation message
|
170
|
+
def deprecate_class_method(old_name, new_name = nil, message: nil)
|
171
|
+
full_msg = Deprecations.deprecated_method_message(
|
172
|
+
"#{self.name}.#{old_name}",
|
173
|
+
new_name ? "#{self.name}.#{new_name}" : nil,
|
174
|
+
message
|
175
|
+
)
|
176
|
+
|
177
|
+
meth = new_name ? method(new_name) : method(old_name)
|
178
|
+
|
179
|
+
singleton_class.instance_exec do
|
180
|
+
undef_method old_name
|
181
|
+
|
182
|
+
define_method(old_name) do |*args, &block|
|
183
|
+
warn(full_msg)
|
184
|
+
meth.call(*args, &block)
|
185
|
+
end
|
152
186
|
end
|
153
187
|
end
|
154
188
|
end
|
data/lib/dry/core/extensions.rb
CHANGED
@@ -34,6 +34,14 @@ module Dry
|
|
34
34
|
@__available_extensions__[name] = block
|
35
35
|
end
|
36
36
|
|
37
|
+
# Whether an extension is available
|
38
|
+
#
|
39
|
+
# @param [Symbol] name extension name
|
40
|
+
# @return [Boolean] Extension availability
|
41
|
+
def available_extension?(name)
|
42
|
+
@__available_extensions__.key?(name)
|
43
|
+
end
|
44
|
+
|
37
45
|
# Enables specified extensions. Already enabled extensions remain untouched
|
38
46
|
#
|
39
47
|
# @param [Array<Symbol>] extensions list of extension names
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Dry
|
2
|
+
module Core
|
3
|
+
# Helper module providing thin interface around an inflection backend.
|
4
|
+
module Inflector
|
5
|
+
# List of supported backends
|
6
|
+
BACKENDS = {
|
7
|
+
activesupport: [
|
8
|
+
'active_support/inflector',
|
9
|
+
proc { ::ActiveSupport::Inflector }
|
10
|
+
],
|
11
|
+
inflecto: [
|
12
|
+
'inflecto',
|
13
|
+
proc { ::Inflecto }
|
14
|
+
]
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Try to activate a backend
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
def self.realize_backend(path, backend_factory)
|
21
|
+
require path
|
22
|
+
rescue LoadError
|
23
|
+
nil
|
24
|
+
else
|
25
|
+
backend_factory.call
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set up first available backend
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def self.detect_backend
|
32
|
+
BACKENDS.inject(nil) do |backend, (_, (path, factory))|
|
33
|
+
backend || realize_backend(path, factory)
|
34
|
+
end || raise(LoadError,
|
35
|
+
"No inflector library could be found: "\
|
36
|
+
"please install either the `inflecto` or `activesupport` gem.")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set preferred backend
|
40
|
+
#
|
41
|
+
# @param [Symbol] name backend name (:activesupport or :inflecto)
|
42
|
+
def self.select_backend(name = nil)
|
43
|
+
if name && !BACKENDS.key?(name)
|
44
|
+
raise NameError, "Invalid inflector library selection: '#{name}'"
|
45
|
+
end
|
46
|
+
@inflector = name ? realize_backend(*BACKENDS[name]) : detect_backend
|
47
|
+
end
|
48
|
+
|
49
|
+
# Inflector accessor. Lazily initializes a backend
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
def self.inflector
|
53
|
+
defined?(@inflector) ? @inflector : select_backend
|
54
|
+
end
|
55
|
+
|
56
|
+
# Transform string to camel case
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# Dry::Core::Inflector.camelize('foo_bar') # => 'FooBar'
|
60
|
+
#
|
61
|
+
# @param [String] input input string
|
62
|
+
# @return Transformed string
|
63
|
+
def self.camelize(input)
|
64
|
+
inflector.camelize(input)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Transform string to snake case
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# Dry::Core::Inflector.underscore('FooBar') # => 'foo_bar'
|
71
|
+
#
|
72
|
+
# @param [String] input input string
|
73
|
+
# @return Transformed string
|
74
|
+
def self.underscore(input)
|
75
|
+
inflector.underscore(input)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get a singlular form of a word
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# Dry::Core::Inflector.singularize('chars') # => 'char'
|
82
|
+
#
|
83
|
+
# @param [String] input input string
|
84
|
+
# @return Transformed string
|
85
|
+
def self.singularize(input)
|
86
|
+
inflector.singularize(input)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Get a plural form of a word
|
90
|
+
#
|
91
|
+
# @example
|
92
|
+
# Dry::Core::Inflector.pluralize('string') # => 'strings'
|
93
|
+
#
|
94
|
+
# @param [String] input input string
|
95
|
+
# @return Transformed string
|
96
|
+
def self.pluralize(input)
|
97
|
+
inflector.pluralize(input)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Remove namespaces from a constant name
|
101
|
+
#
|
102
|
+
# @example
|
103
|
+
# Dry::Core::Inflector.demodulize('Deeply::Nested::Name') # => 'Name'
|
104
|
+
#
|
105
|
+
# @param [String] input input string
|
106
|
+
# @return Unnested constant name
|
107
|
+
def self.demodulize(input)
|
108
|
+
inflector.demodulize(input)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get a constant value by its name
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# Dry::Core::Inflector.constantize('Foo::Bar') # => Foo::Bar
|
115
|
+
#
|
116
|
+
# @param [String] input input constant name
|
117
|
+
# @return Constant value
|
118
|
+
def self.constantize(input)
|
119
|
+
inflector.constantize(input)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Transform a file path to a constant name
|
123
|
+
#
|
124
|
+
# @example
|
125
|
+
# Dry::Core::Inflector.classify('foo/bar') # => 'Foo::Bar'
|
126
|
+
#
|
127
|
+
# @param [String] input input string
|
128
|
+
# @return Constant name
|
129
|
+
def self.classify(input)
|
130
|
+
inflector.classify(input)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/dry/core/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Shilnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/dry/core/constants.rb
|
91
91
|
- lib/dry/core/deprecations.rb
|
92
92
|
- lib/dry/core/extensions.rb
|
93
|
+
- lib/dry/core/inflector.rb
|
93
94
|
- lib/dry/core/version.rb
|
94
95
|
homepage: https://github.com/dry-rb/dry-code
|
95
96
|
licenses:
|
@@ -104,7 +105,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
105
|
requirements:
|
105
106
|
- - ">="
|
106
107
|
- !ruby/object:Gem::Version
|
107
|
-
version:
|
108
|
+
version: 2.1.0
|
108
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
110
|
requirements:
|
110
111
|
- - ">="
|