injectable 1.0.1 → 2.1.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
2
  SHA256:
3
- metadata.gz: 8a32caf8a5fd11f69df5ea9ffe381e63fdaa4d640044c797bc1d6b0ee29bf2f1
4
- data.tar.gz: c57be65098fc9b53b7e7bd6b4f9bce85296390424655d2fed9bb6bf534494c61
3
+ metadata.gz: 39e5192fdea17f097ed9a59e790d420cc57c948d634d62295cf1b4060423b57e
4
+ data.tar.gz: 03df6db3f7c4d49eed4333800a8d1f58a8621d030285327f0bc9b0fc46b12ba6
5
5
  SHA512:
6
- metadata.gz: fa7c6f31fccdbe29d987732dba922c7a6915517340c8833ccd1aaeed9e48c8eb39fb71eda6ae718f951fc5b56ac8aa0cff7d9519105aae9f2a9de8f526ea130c
7
- data.tar.gz: 88b632c250c5cdf4a98e542e1e9801eab4684eb891c2ec9cad2386c10b62d2e749828fd5b21ed40bcdcabcece7ffa48ae8999e6cda2dd57a52a6ffa71bb60b0e
6
+ metadata.gz: b68bf39f92aaccd38780cda67bddf53d3f95eecfcc9a00028787f56a9075d03356fa2533708827deeb5c12441bc007132e8934e6c353de1e109284923764a76f
7
+ data.tar.gz: c9a3fb6173b26269589bcea5ac45a02c86a81df8c6b956405067f7f483afbbf78f395a3678fe98b96b2d02582edad45c2a8d6444fd777e16cea25c33647c4c91
@@ -0,0 +1,25 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby: [ 2.5.x, 2.6, 2.7.x ]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Ruby ${{ matrix.ruby }}
18
+ uses: actions/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby }}
21
+ - name: Build and test with Rake
22
+ run: |
23
+ gem install bundler
24
+ bundle install --jobs 4 --retry 3
25
+ bundle exec rake
data/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ ### Unreleased
2
+
3
+ ### 2.1.1 - 2021-03-15
4
+
5
+ * bug fixes
6
+ * Address final Ruby 2.7 warnings (#24)
7
+
8
+ ### 2.1.0 - 2021-01-05
9
+
10
+ * enhancements
11
+ * Return `method` object instead of monkey patched instance (#17)
12
+ * Prepare for Ruby 3.0 (#22)
13
+
14
+ ### 2.0.0 - 2020-03-16
15
+
16
+ * breaking changes
17
+ * Raises exception if shadowing an existing `#call` method in a dependency (#15)
18
+
19
+ ### 1.0.3 - 2020-03-16
20
+
21
+ * enhancements
22
+ * Added GitHub Actions as CI (#9)
23
+
24
+ * bug fixes
25
+ * Fixed a bug that wouldn't pass a block if `#call` was aliased (#7)
26
+
27
+ ### 1.0.2 - 2020-03-02
28
+
29
+ * security
30
+ * Bump `rake` to 12.3.3 (#11)
data/Gemfile.lock CHANGED
@@ -1,26 +1,35 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- injectable (1.0.0)
4
+ injectable (2.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- diff-lcs (1.3)
10
- rake (12.3.2)
11
- rspec (3.8.0)
12
- rspec-core (~> 3.8.0)
13
- rspec-expectations (~> 3.8.0)
14
- rspec-mocks (~> 3.8.0)
15
- rspec-core (3.8.0)
16
- rspec-support (~> 3.8.0)
17
- rspec-expectations (3.8.3)
9
+ byebug (11.1.3)
10
+ coderay (1.1.3)
11
+ diff-lcs (1.4.4)
12
+ method_source (1.0.0)
13
+ pry (0.13.1)
14
+ coderay (~> 1.1)
15
+ method_source (~> 1.0)
16
+ pry-byebug (3.9.0)
17
+ byebug (~> 11.0)
18
+ pry (~> 0.13.0)
19
+ rake (13.0.3)
20
+ rspec (3.10.0)
21
+ rspec-core (~> 3.10.0)
22
+ rspec-expectations (~> 3.10.0)
23
+ rspec-mocks (~> 3.10.0)
24
+ rspec-core (3.10.1)
25
+ rspec-support (~> 3.10.0)
26
+ rspec-expectations (3.10.1)
18
27
  diff-lcs (>= 1.2.0, < 2.0)
19
- rspec-support (~> 3.8.0)
20
- rspec-mocks (3.8.0)
28
+ rspec-support (~> 3.10.0)
29
+ rspec-mocks (3.10.1)
21
30
  diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.8.0)
23
- rspec-support (3.8.0)
31
+ rspec-support (~> 3.10.0)
32
+ rspec-support (3.10.1)
24
33
 
25
34
  PLATFORMS
26
35
  ruby
@@ -28,8 +37,9 @@ PLATFORMS
28
37
  DEPENDENCIES
29
38
  bundler (~> 2.0)
30
39
  injectable!
31
- rake (~> 12.0)
40
+ pry-byebug
41
+ rake (~> 13.0)
32
42
  rspec (~> 3.0)
33
43
 
34
44
  BUNDLED WITH
35
- 2.0.1
45
+ 2.2.4
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Injectable
2
2
 
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/a45cc5935a5c16b837ed/maintainability)](https://codeclimate.com/github/rubiconmd/injectable/maintainability)![Ruby](https://github.com/rubiconmd/injectable/workflows/Ruby/badge.svg)
4
+
3
5
  `Injectable` is an opinionated and declarative [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) library for ruby.
4
6
 
5
7
  It is being used in production (under ruby 2.5.1) in [RubiconMD](https://github.com/rubiconmd) and was extracted from its codebase.
@@ -209,8 +211,8 @@ There are several ways of declaring a `#dependency`:
209
211
 
210
212
  ```rb
211
213
  class ReportPdfRenderer
212
- include Injectable
213
-
214
+ include Injectable
215
+
214
216
  dependency :some_dependency
215
217
  end
216
218
  ```
@@ -225,9 +227,9 @@ Notice that this happens **at runtime**, not when defining your class.
225
227
  ```rb
226
228
  class MyInjectable
227
229
  include Injectable
228
-
230
+
229
231
  dependency :client, class: Aws::S3::Client
230
- dependency :parser, class: VeryLongClassNameForMyParser
232
+ dependency :parser, class: VeryLongClassNameForMyParser
231
233
  end
232
234
  ```
233
235
 
@@ -353,6 +355,6 @@ Everyone interacting in the Injectable project’s codebases, issue trackers, ch
353
355
 
354
356
  - [RubiconMD](https://github.com/rubiconmd) allowed extracting this gem from its codebase and release it as open source.
355
357
  - [Durran Jordan](https://github.com/durran) allowed the usage of the gem name at rubygems.org.
356
- - [David Marchante](https://github.com/iovis9) brainstormed the `initialize`/`call` approach, did all code reviews and provided lots of insightful feedback and suggestions. He also wrote the inline documentation.
358
+ - [David Marchante](https://github.com/iovis) brainstormed the `initialize`/`call` approach, did all code reviews and provided lots of insightful feedback and suggestions. He also wrote the inline documentation.
357
359
  - [Julio Antequera](https://github.com/jantequera), [Jimmi Carney](https://github.com/ayoformayo) and [Anthony Rocco](https://github.com/amrocco) had the patience to use it and report many bugs. Also most of the features in this gem came up when reviewing their usage of it. Anthony also made the effort of extracting the code from RubiconMD's codebase.
358
360
  - [Rodrigo Álvarez](https://github.com/Papipo) had the idea for the DSL and actually wrote the library.
data/injectable.gemspec CHANGED
@@ -1,29 +1,29 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "injectable/version"
3
+ require 'injectable/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
6
  spec.name = 'injectable'
8
7
  spec.version = Injectable::VERSION
9
- spec.authors = %w(Papipo iovis9 jantequera amrocco)
10
- spec.email = %w(rodrigo@rubiconmd.com david.marchante@rubiconmd.com julio@rubiconmd.com anthony@rubiconmd.com)
8
+ spec.authors = %w[Papipo iovis jantequera amrocco rewritten]
9
+ spec.email = %w[dev@rubiconmd.com]
11
10
 
12
- spec.summary = %q{A library to help you build nice service objects with dependency injection.}
11
+ spec.summary = 'A library to help you build nice service objects with dependency injection.'
13
12
  spec.homepage = 'https://github.com/rubiconmd/injectable'
14
- spec.license = "MIT"
13
+ spec.license = 'MIT'
15
14
 
16
15
  # Specify which files should be added to the gem when it is released.
17
16
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
18
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
19
  end
21
20
  spec.bindir = 'exe'
22
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
22
  spec.require_paths = ['lib']
24
- spec.required_ruby_version = '>= 2.0.0'
23
+ spec.required_ruby_version = '>= 2.5'
25
24
 
26
25
  spec.add_development_dependency 'bundler', '~> 2.0'
27
- spec.add_development_dependency 'rake', '~> 12.0'
26
+ spec.add_development_dependency 'pry-byebug'
27
+ spec.add_development_dependency 'rake', '~> 13.0'
28
28
  spec.add_development_dependency 'rspec', '~> 3.0'
29
29
  end
data/lib/injectable.rb CHANGED
@@ -5,6 +5,7 @@ require 'injectable/dependencies_proxy'
5
5
  require 'injectable/dependency'
6
6
  require 'injectable/instance_methods'
7
7
  require 'injectable/missing_dependencies_exception'
8
+ require 'injectable/method_already_exists_exception'
8
9
 
9
10
  # Convert your class into an injectable service
10
11
  #
@@ -97,7 +97,7 @@ module Injectable
97
97
  options[:block] = block if block_given?
98
98
  options[:depends_on] = Array(options.fetch(:depends_on, []))
99
99
  options[:name] = name
100
- dependencies.add(options)
100
+ dependencies.add(**options)
101
101
  define_method name do
102
102
  instance_variable_get("@#{name}") || dependencies_proxy.get(name)
103
103
  end
@@ -2,27 +2,57 @@ module Injectable
2
2
  # Initialize a dependency based on the options or the block passed
3
3
  Dependency = Struct.new(:name, :block, :class, :call, :with, :depends_on, keyword_init: true) do
4
4
  def instance(args: [], namespace: nil)
5
- args = wrap_args(args)
6
- wrap_call build_instance(args, namespace: namespace)
5
+ positional_args, kwargs = split_args(args)
6
+
7
+ wrap_call build_instance(positional_args, kwargs, namespace: namespace)
7
8
  end
8
9
 
9
10
  private
10
11
 
11
- def wrap_args(args)
12
+ def split_args(args)
13
+ args = preprocess_args(args)
14
+
15
+ return [[], {}] if args.empty?
16
+
17
+ kwargs = args.pop
18
+
19
+ if kwargs.is_a?(Hash) && kwargs.keys.all? { |key| key.is_a?(Symbol) }
20
+ [args, kwargs]
21
+ else
22
+ [args << kwargs, {}]
23
+ end
24
+ end
25
+
26
+ def preprocess_args(args)
12
27
  args = with unless with.nil?
13
- args.is_a?(Array) ? args : [args]
28
+ wrap_args(args)
29
+ end
30
+
31
+ def wrap_args(args)
32
+ args.is_a?(Array) ? args.clone : [args]
14
33
  end
15
34
 
16
35
  def wrap_call(the_instance)
17
36
  return the_instance unless call
18
37
 
19
- lambda do |*args|
20
- the_instance.public_send(call, *args)
38
+ if the_instance.respond_to? :call
39
+ raise Injectable::MethodAlreadyExistsException
21
40
  end
41
+
42
+ the_instance.public_method(call)
22
43
  end
23
44
 
24
- def build_instance(args, namespace:)
25
- block.nil? ? klass(namespace: namespace).new(*args) : block.call(*args)
45
+ def build_instance(args, kwargs, namespace:)
46
+ return build_instance_26(args, kwargs, namespace: namespace) if RUBY_VERSION < '2.7'
47
+
48
+ instantiator = block || klass(namespace: namespace).method(:new)
49
+ if kwargs.empty?
50
+ # otherwise an empty hash will be added in ruby 2.7, which could be taken as
51
+ # positional argument instead.
52
+ instantiator.call(*args)
53
+ else
54
+ instantiator.call(*args, **kwargs)
55
+ end
26
56
  end
27
57
 
28
58
  def klass(namespace:)
@@ -36,5 +66,11 @@ module Injectable
36
66
  def camelcased
37
67
  @camelcased ||= name.to_s.split('_').map(&:capitalize).join
38
68
  end
69
+
70
+ def build_instance_26(args, kwargs, namespace:)
71
+ args << kwargs if kwargs.any?
72
+
73
+ block.nil? ? klass(namespace: namespace).new(*args) : block.call(*args)
74
+ end
39
75
  end
40
76
  end
@@ -0,0 +1,4 @@
1
+ module Injectable
2
+ class MethodAlreadyExistsException < RuntimeError
3
+ end
4
+ end
@@ -1,3 +1,3 @@
1
1
  module Injectable
2
- VERSION = '1.0.1'
2
+ VERSION = '2.1.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: injectable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Papipo
8
- - iovis9
8
+ - iovis
9
9
  - jantequera
10
10
  - amrocco
11
- autorequire:
11
+ - rewritten
12
+ autorequire:
12
13
  bindir: exe
13
14
  cert_chain: []
14
- date: 2019-05-30 00:00:00.000000000 Z
15
+ date: 2021-03-16 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: bundler
@@ -27,20 +28,34 @@ dependencies:
27
28
  - - "~>"
28
29
  - !ruby/object:Gem::Version
29
30
  version: '2.0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: pry-byebug
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
30
45
  - !ruby/object:Gem::Dependency
31
46
  name: rake
32
47
  requirement: !ruby/object:Gem::Requirement
33
48
  requirements:
34
49
  - - "~>"
35
50
  - !ruby/object:Gem::Version
36
- version: '12.0'
51
+ version: '13.0'
37
52
  type: :development
38
53
  prerelease: false
39
54
  version_requirements: !ruby/object:Gem::Requirement
40
55
  requirements:
41
56
  - - "~>"
42
57
  - !ruby/object:Gem::Version
43
- version: '12.0'
58
+ version: '13.0'
44
59
  - !ruby/object:Gem::Dependency
45
60
  name: rspec
46
61
  requirement: !ruby/object:Gem::Requirement
@@ -55,19 +70,18 @@ dependencies:
55
70
  - - "~>"
56
71
  - !ruby/object:Gem::Version
57
72
  version: '3.0'
58
- description:
73
+ description:
59
74
  email:
60
- - rodrigo@rubiconmd.com
61
- - david.marchante@rubiconmd.com
62
- - julio@rubiconmd.com
63
- - anthony@rubiconmd.com
75
+ - dev@rubiconmd.com
64
76
  executables: []
65
77
  extensions: []
66
78
  extra_rdoc_files: []
67
79
  files:
80
+ - ".github/workflows/ruby.yml"
68
81
  - ".gitignore"
69
82
  - ".rspec"
70
83
  - ".travis.yml"
84
+ - CHANGELOG.md
71
85
  - CODE_OF_CONDUCT.md
72
86
  - Gemfile
73
87
  - Gemfile.lock
@@ -83,13 +97,14 @@ files:
83
97
  - lib/injectable/dependencies_proxy.rb
84
98
  - lib/injectable/dependency.rb
85
99
  - lib/injectable/instance_methods.rb
100
+ - lib/injectable/method_already_exists_exception.rb
86
101
  - lib/injectable/missing_dependencies_exception.rb
87
102
  - lib/injectable/version.rb
88
103
  homepage: https://github.com/rubiconmd/injectable
89
104
  licenses:
90
105
  - MIT
91
106
  metadata: {}
92
- post_install_message:
107
+ post_install_message:
93
108
  rdoc_options: []
94
109
  require_paths:
95
110
  - lib
@@ -97,16 +112,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
112
  requirements:
98
113
  - - ">="
99
114
  - !ruby/object:Gem::Version
100
- version: 2.0.0
115
+ version: '2.5'
101
116
  required_rubygems_version: !ruby/object:Gem::Requirement
102
117
  requirements:
103
118
  - - ">="
104
119
  - !ruby/object:Gem::Version
105
120
  version: '0'
106
121
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.7.6
109
- signing_key:
122
+ rubygems_version: 3.1.2
123
+ signing_key:
110
124
  specification_version: 4
111
125
  summary: A library to help you build nice service objects with dependency injection.
112
126
  test_files: []