dry-core 0.1.0 → 0.2.0

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: f18461caed54954ed1ded7991e22481fb2460f54
4
- data.tar.gz: 6f14a3398ad397e64db754967b4315a440b225f1
3
+ metadata.gz: 67a852de7314c5546f3d556d5f814270b1f4bd41
4
+ data.tar.gz: 8f34325aacc8019f2203c9486abdddacccaa4be1
5
5
  SHA512:
6
- metadata.gz: b68b62a1b7bceb698b669c9462c4bfded77dd1536dbcaaa201c76c34414df3d28e85042e106d2809ad118caabbd8ce84a4e5d09da835cf03dfa7f1f53ea7cda7
7
- data.tar.gz: 0960b20d7483027f61502c64c0c06d69f37bca79c90f6bc4aedc190328bf9d354ca323c17e34a28a281f9cf27b59b6acd6c51fb0d7f36089fb1665d9103257e2
6
+ metadata.gz: 4c8b853aecef987b247b614ddc828c94bf403660fd38b751f5f12042b5984049a7971df2c82e4de7c176d2655c91964366ca2fbb8285875478d48c586f051831
7
+ data.tar.gz: 6afcac12f9ad38b5fea9d069b48b6a6488c757cbb0c791833eb24298d35e0d3346544c1a84fba14149ea83aeae88cfc6af94719b6268cf95f9ecbdbbe81b444f
@@ -1,17 +1,18 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.1.9
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
@@ -3,6 +3,8 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
+ gem 'activesupport', '~> 4.2'
7
+ gem 'inflecto', '~> 0.0', '>= 0.0.2'
6
8
  gem 'codeclimate-test-reporter', require: false
7
9
  gem 'simplecov', require: false
8
10
  end
@@ -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'
@@ -1 +1 @@
1
- require 'dry-core'
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
- logger.warn(msg.gsub(/^\s+/, ''))
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(tag = nil, output = nil)
79
+ def logger(output = nil)
80
80
  if defined?(@logger)
81
81
  @logger
82
82
  else
83
- set_logger!(output: output, tag: tag)
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
- # @option [String, Symbol] tag optional prefix
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
- # Mark instance method as deprecated
104
- #
105
- # @param [Symbol] old_name deprecated method
106
- # @param [Symbol] new_name replacement (not required)
107
- # @option [String] message optional deprecation message
108
- def deprecate(old_name, new_name = nil, message: nil)
109
- full_msg = Deprecations.deprecated_method_message(
110
- "#{self.name}##{old_name}",
111
- new_name ? "#{self.name}##{new_name}" : nil,
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
- else
122
- aliased_name = :"#{old_name}_without_deprecation"
123
- alias_method aliased_name, old_name
124
- private aliased_name
125
- undef_method old_name
126
- define_method(old_name) do |*args, &block|
127
- Deprecations.warn(full_msg)
128
- __send__(aliased_name, *args, &block)
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
- # Mark class-level method as deprecated
134
- #
135
- # @param [Symbol] old_name deprecated method
136
- # @param [Symbol] new_name replacement (not required)
137
- # @option [String] message optional deprecation message
138
- def deprecate_class_method(old_name, new_name = nil, message: nil)
139
- full_msg = Deprecations.deprecated_method_message(
140
- "#{self.name}.#{old_name}",
141
- new_name ? "#{self.name}.#{new_name}" : nil,
142
- message
143
- )
144
-
145
- meth = new_name ? method(new_name) : method(old_name)
146
-
147
- singleton_class.instance_exec do
148
- undef_method old_name
149
- define_method(old_name) do |*args, &block|
150
- Deprecations.warn(full_msg)
151
- meth.call(*args, &block)
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Core
3
- VERSION = '0.1.0'.freeze
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  end
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.1.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-09-17 00:00:00.000000000 Z
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: '0'
108
+ version: 2.1.0
108
109
  required_rubygems_version: !ruby/object:Gem::Requirement
109
110
  requirements:
110
111
  - - ">="