co_aspects 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4280bc3de7d746955cbdcf86d00a9d923c46c034
4
+ data.tar.gz: f6aaba63af472ae3371cafbdfcd605f69cd05585
5
+ SHA512:
6
+ metadata.gz: b649ebc4c074d271daaa09713f9090418be1c79babaf38dac88fdb37c7c15a251042bfa1a54d10694a74ef7c2de34a4d0535421c4aba5915e02347e39568b27b
7
+ data.tar.gz: 3da34d1981848f065e22b1843ff9aae685eb38bb0d16e61050579e407f9d5101d89b4e52ee11837a00d7e8ebbf8a3ba3f75e46da90825a2a07dc7d507fc9c555
data/.gitignore ADDED
@@ -0,0 +1,37 @@
1
+ *.gem
2
+ *.rbc
3
+ /.caches/
4
+ /.config
5
+ /InstalledFiles
6
+ /Gemfile.lock
7
+ /coverage/
8
+ /pkg/
9
+ /spec/reports/
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+
14
+ ## Specific to RubyMotion:
15
+ .dat*
16
+ .repl_history
17
+ build/
18
+
19
+ ## Documentation cache and generated files:
20
+ /.yardoc/
21
+ /_yardoc/
22
+ /doc/
23
+ /rdoc/
24
+
25
+ ## Environment normalisation:
26
+ /.bundle/
27
+ /vendor/bundle
28
+ /lib/bundler/man/
29
+
30
+ # for a library or gem, you might want to ignore these files since the code is
31
+ # intended to run in multiple environments; otherwise, check them in:
32
+ # Gemfile.lock
33
+ # .ruby-version
34
+ # .ruby-gemset
35
+
36
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
37
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Gaston Jorquera
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # CoAspects
2
+
3
+ Easily attach [aspector](https://github.com/gcao/aspector) aspects via
4
+ annotations.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'co_aspects'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ ## Usage
19
+
20
+ To start using the annotations, first tell the class that you want them:
21
+
22
+ ```ruby
23
+ class MyClass
24
+ aspects_annotations!
25
+
26
+ ...
27
+ end
28
+ ```
29
+
30
+ Then you can attach any aspect to a given method via the analogous annotation:
31
+
32
+ ```ruby
33
+ class MyClass
34
+ ...
35
+
36
+ _rescue_and_notify
37
+ def important!
38
+ ...
39
+ end
40
+ end
41
+ ```
42
+
43
+ The aspect attached to a method is the camelized version of the annotation
44
+ followed by "Aspect". For example, the `_rescue_and_notify` will attach the
45
+ `RescueAndNotifyAspect` aspect.
46
+
47
+ Several aspects can be attached to the same method, and the same aspect can be
48
+ attached to different methods.
49
+
50
+ ### Arguments
51
+
52
+ Aspects can receive hash arguments and a block if it needs some dynamic
53
+ information from the call. These hash arguments and block must be passed via the
54
+ annotation:
55
+
56
+ ```ruby
57
+ class Quoter
58
+ ...
59
+
60
+ _stats_increment as: 'ws.quoteapp' { |quote| key(quote) }
61
+ def save_quote(quote)
62
+ ...
63
+ end
64
+ end
65
+ ```
66
+
67
+ The `StatsIncrementAspect`, for example, can receive an alias to override the
68
+ default StatsD prefix key, and a block to include a dynamic part at the end of
69
+ the StatsD key.
70
+
71
+ Each aspect defines which arguments it supports and if it support a block.
72
+
73
+ ## Aspects
74
+
75
+ For documentation on the available aspects, refer to each aspect class located
76
+ in the [aspects
77
+ directory](https://github.com/comparaonline/co_aspects/tree/master/lib/co_aspects/aspects).
78
+
79
+ ## Development
80
+
81
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
82
+ `bin/test` to run the tests. You can also run `bin/console` for an interactive
83
+ prompt that will allow you to experiment.
84
+
85
+ To install this gem onto your local machine, run `bundle exec rake install`.
86
+
87
+ ## Deployment
88
+
89
+ To release a new version, update the version number in `version.rb`, and then
90
+ run `bundle exec rake release`, which will create a git tag for the version,
91
+ push git commits and tags, and push the `.gem` file to
92
+ [rubygems.org](https://rubygems.org).
93
+
94
+ ## Contributing
95
+
96
+ Bug reports and pull requests are welcome on GitHub
97
+ [Issues](https://github.com/comparaonline/co_aspects).
98
+
99
+ ## License
100
+
101
+ The gem is available as open source under the terms of the [MIT
102
+ License](http://opensource.org/licenses/MIT).
103
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'co_aspects'
5
+
6
+ require 'irb'
7
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+ IFS=$'\n\t'
5
+
6
+ cd $(dirname $0)/..
7
+
8
+ mkdir -p .caches
9
+
10
+ if [[ $(cat .caches/gemspec 2>&1) = $(shasum *.gemspec) ]]; then
11
+ echo "✓ Gemspec cache up to date."
12
+ else
13
+ echo "✗ Gemspec cache invalid."
14
+
15
+ bundle check || bundle install
16
+ echo "✓ Bundle installed"
17
+
18
+ shasum *.gemspec > .caches/gemspec
19
+ echo "✓ Gemspec cache updated."
20
+ fi
data/bin/test ADDED
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+ IFS=$'\n\t'
5
+
6
+ cd $(dirname $0)/..
7
+
8
+ ./bin/setup
9
+
10
+ bundle exec rspec
data/circle.yml ADDED
@@ -0,0 +1,3 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.5
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'co_aspects/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'co_aspects'
8
+ spec.version = CoAspects::VERSION
9
+ spec.authors = ['Gaston Jorquera']
10
+ spec.email = ['gjorquera@gmail.com']
11
+
12
+ spec.summary = %q{Collection of ready to use aspects.}
13
+ spec.description = <<-EOF.gsub(/^\s{4}/, '')
14
+ Collection of ready to use aspects with an annotation-like syntax to attach
15
+ it to methods.
16
+ EOF
17
+ spec.homepage = 'https://github.com/comparaonline/co_aspects'
18
+ spec.license = 'MIT'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'activesupport', '>= 3.0'
26
+ spec.add_dependency 'aspector', '~> 0.14.0'
27
+ spec.add_dependency 'newrelic_rpm', '~> 3.14'
28
+ spec.add_dependency 'statsd-instrument', '~> 2.0'
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.9'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec'
33
+ end
@@ -0,0 +1,4 @@
1
+ module CoAspects
2
+ class Annotation < Struct.new(:aspect, :options, :block)
3
+ end
4
+ end
@@ -0,0 +1,41 @@
1
+ module CoAspects
2
+ module Aspects
3
+ # Generates a warning message saying that the method is deprecated and
4
+ # mentioning the new one.
5
+ #
6
+ # Examples
7
+ #
8
+ # class MyClass
9
+ # aspects_annotations!
10
+ #
11
+ # _deprecate use: :new_method
12
+ # def old_method
13
+ # end
14
+ #
15
+ # def new_method
16
+ # end
17
+ #
18
+ # _deprecate
19
+ # def deprecated_method
20
+ # end
21
+ # end
22
+ #
23
+ # MyClass.new.old_method
24
+ # # => DEPRECATION WARNING: Target.old_method deprecated, use new_method instead.
25
+ #
26
+ # MyClass.new.deprecated_method
27
+ # # => DEPRECATION WARNING: Target.deprecated_method deprecated.
28
+ class DeprecateAspect < Aspector::Base
29
+ before interception_arg: true, method_arg: true do |interception, method|
30
+ old_method_name = "#{self.class}.#{method}"
31
+ new_method_name = interception.options[:annotation][:use]
32
+
33
+ message = "DEPRECATION WARNING: #{old_method_name} deprecated"
34
+ message += ", use #{new_method_name} instead" if new_method_name
35
+ message += '.'
36
+
37
+ Kernel.warn(message)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ module CoAspects
2
+ module Aspects
3
+ # Generates a log in the Rails logger with the method call, arguments and
4
+ # result.
5
+ #
6
+ # Examples
7
+ #
8
+ # class MyClass
9
+ # aspects_annotations!
10
+ #
11
+ # _log_call
12
+ # def method(arg1, arg2)
13
+ # :success
14
+ # end
15
+ # end
16
+ #
17
+ # MyClass.new.method(:first, :second)
18
+ # # => [DEBUG] MyClass.method called, args(:first,:second), result: :success
19
+ class LogCallAspect < Aspector::Base
20
+ around method_arg: true do |method, proxy, *args, &block|
21
+ result = proxy.call(*args, &block)
22
+ method_name = "#{self.class}.#{method}"
23
+ args_list = args.join(',')
24
+
25
+ message = "#{method_name} called" +
26
+ ", args: (#{args_list})" +
27
+ ", result: #{result}"
28
+ Rails.logger.debug(message)
29
+
30
+ result
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ require 'newrelic_rpm'
2
+
3
+ module CoAspects
4
+ module Aspects
5
+ # Rescues any error and notifies NewRelic about it, without raising it
6
+ # again.
7
+ #
8
+ # Important: If CoAspects::Aspects::RescueAndNotifyAspect.enable_test_mode!
9
+ # is executed, then instead of calling NewRelic, it will raise the exception
10
+ # as if this aspect didn't exist. It's to be used by tests, to see
11
+ # exceptions being raised inside `_rescue_and_notify` annotated methods.
12
+ #
13
+ # Enabling test mode is not thread safe!
14
+ #
15
+ # Examples
16
+ #
17
+ # class MyClass
18
+ # aspects_annotations!
19
+ #
20
+ # _rescue_and_notify
21
+ # def perform_with_error
22
+ # fail 'Error'
23
+ # end
24
+ #
25
+ # _rescue_and_notify
26
+ # def perform_without_error
27
+ # :success
28
+ # end
29
+ # end
30
+ #
31
+ # MyClass.new.perform_with_error
32
+ # # NewRelic::Agent.notify_error(...)
33
+ # # => nil
34
+ #
35
+ # MyClass.new.perform_without_error
36
+ # # => :success
37
+ class RescueAndNotifyAspect < Aspector::Base
38
+ class << self
39
+ def test_mode
40
+ !!@test_mode
41
+ end
42
+
43
+ def enable_test_mode!
44
+ @test_mode = true
45
+ end
46
+
47
+ def disable_test_mode!
48
+ @test_mode = false
49
+ end
50
+ end
51
+
52
+ around method_arg: true do |_, proxy, *args, &block|
53
+ begin
54
+ proxy.call(*args, &block)
55
+ rescue => e
56
+ if RescueAndNotifyAspect.test_mode
57
+ raise e
58
+ else
59
+ NewRelic::Agent.notice_error(e, stack_trace: e.backtrace)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,50 @@
1
+ require 'statsd-instrument'
2
+
3
+ module CoAspects
4
+ module Aspects
5
+ # Increments a StatsD key after the method is executed.
6
+ #
7
+ # The key is automatically generated converting the modules, class name and
8
+ # method name into underscores.
9
+ #
10
+ # The key can be overridden via the `as:` option and a dynamic part can be
11
+ # added at the end using a block that receives the same arguments as the
12
+ # method.
13
+ #
14
+ # Examples
15
+ #
16
+ # module MyModule
17
+ # class MyClass
18
+ # aspects_annotations!
19
+ #
20
+ # _stats_increment
21
+ # def task1
22
+ # ...
23
+ # end
24
+ #
25
+ # _stats_increment(as: 'my_key') { |arg| arg }
26
+ # def task2(arg)
27
+ # ...
28
+ # end
29
+ # end
30
+ # end
31
+ #
32
+ # MyClass.new.task1
33
+ # # => StatsD.increment('my_module.my_class.task1')
34
+ #
35
+ # MyClass.new.task2('dynamic')
36
+ # # => StatsD.increment('my_key.dynamic')
37
+ class StatsIncrementAspect < Aspector::Base
38
+ around interception_arg: true, method_arg: true do |interception, method, proxy, *args, &block|
39
+ key = StatsdHelper.key(self.class,
40
+ method,
41
+ args,
42
+ interception.options[:annotation][:as],
43
+ interception.options[:block])
44
+ result = proxy.call(*args, &block)
45
+ StatsD.increment(key)
46
+ result
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ require 'statsd-instrument'
2
+ require_relative 'statsd_helper'
3
+
4
+ module CoAspects
5
+ module Aspects
6
+ # Measures a method and stores the result on StatsD.
7
+ #
8
+ # The key is automatically generated converting the modules, class name and
9
+ # method name into underscores.
10
+ #
11
+ # The key can be overridden via the `as:` option and a dynamic part can be
12
+ # added at the end using a block that receives the same arguments as the
13
+ # method.
14
+ #
15
+ # Examples
16
+ #
17
+ # module MyModule
18
+ # class MyClass
19
+ # aspects_annotations!
20
+ #
21
+ # _stats_measure
22
+ # def task1
23
+ # ...
24
+ # end
25
+ #
26
+ # _stats_measure(as: 'my_key') { |arg| arg }
27
+ # def task2(arg)
28
+ # ...
29
+ # end
30
+ # end
31
+ # end
32
+ #
33
+ # MyClass.new.task1
34
+ # # => StatsD.measure('my_module.my_class.task1')
35
+ #
36
+ # MyClass.new.task2('dynamic')
37
+ # # => StatsD.measure('my_key.dynamic')
38
+ class StatsMeasureAspect < Aspector::Base
39
+ around interception_arg: true, method_arg: true do |interception, method, proxy, *args, &block|
40
+ key = StatsdHelper.key(self.class,
41
+ method,
42
+ args,
43
+ interception.options[:annotation][:as],
44
+ interception.options[:block])
45
+ StatsD.measure(key) do
46
+ proxy.call(*args, &block)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ module CoAspects
2
+ module Aspects
3
+ module StatsdHelper
4
+ module_function
5
+
6
+ def default_prefix(klass, method_name)
7
+ klass.name.underscore.tr('/', '.') + ".#{method_name}"
8
+ end
9
+
10
+ def key(klass, method_name, method_args, statsd_prefix, statsd_block)
11
+ key = statsd_prefix || default_prefix(klass, method_name)
12
+ key += ".#{statsd_block.call(*method_args)}" if statsd_block
13
+ key
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module CoAspects
4
+ class Attacher
5
+ def initialize
6
+ @pending = []
7
+ end
8
+
9
+ def add(method_name, options, block)
10
+ aspect_class = aspect_from_method(method_name)
11
+ @pending << Annotation.new(aspect_class, options, block)
12
+ end
13
+
14
+ def attach(klass, method_name)
15
+ blocking do
16
+ @pending.each do |pending|
17
+ pending.aspect.apply klass,
18
+ method: method_name,
19
+ annotation: pending.options,
20
+ block: pending.block
21
+ end
22
+ @pending = []
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def aspect_from_method(method_name)
29
+ aspect_name_from_method(method_name).constantize
30
+ rescue NameError => e
31
+ fail AspectNotFoundError.new(e.name, method_name)
32
+ end
33
+
34
+ def aspect_name_from_method(annotation)
35
+ "::CoAspects::Aspects::#{annotation[1..-1].camelize}Aspect"
36
+ end
37
+
38
+ def blocking
39
+ @enabled = true unless defined?(@enabled)
40
+ return unless @enabled
41
+ @enabled = false
42
+ begin
43
+ yield
44
+ ensure
45
+ @enabled = true
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module CoAspects
2
+ module Callbacks
3
+ def method_added(method_name)
4
+ super
5
+ (@__aspects_attacher__ ||= Attacher.new).attach(self, method_name)
6
+ end
7
+
8
+ def method_missing(method_name, *args, &block)
9
+ return super unless /\A_/ =~ method_name
10
+ args.each { |arg| fail InvalidArgument.new(arg) unless arg.kind_of?(Hash) }
11
+ options = Hash[*args.map(&:to_a).flatten]
12
+ (@__aspects_attacher__ ||= Attacher.new).add(method_name, options, block)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module CoAspects
2
+ class AspectNotFoundError < StandardError
3
+ def initialize(aspect, method)
4
+ super("Aspect `#{aspect}` for annotation `#{method}` does not exist.")
5
+ end
6
+ end
7
+
8
+ class InvalidArgument < ArgumentError
9
+ def initialize(argument)
10
+ super("Invalid annotation argument `#{argument}`, only hashes valid.")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ class Module
2
+ private
3
+
4
+ def aspects_annotations!
5
+ extend CoAspects::Callbacks
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ CoAspects::Aspects::RescueAndNotifyAspect.enable_test_mode!
@@ -0,0 +1,3 @@
1
+ module CoAspects
2
+ VERSION = '0.1.0'
3
+ end
data/lib/co_aspects.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'co_aspects/version'
2
+
3
+ require 'co_aspects/annotation'
4
+ require 'co_aspects/attacher'
5
+ require 'co_aspects/callbacks'
6
+ require 'co_aspects/errors'
7
+ require 'co_aspects/module'
8
+
9
+ require 'aspector'
10
+
11
+ require 'co_aspects/aspects/deprecate_aspect'
12
+ require 'co_aspects/aspects/log_call_aspect'
13
+ require 'co_aspects/aspects/rescue_and_notify_aspect'
14
+ require 'co_aspects/aspects/stats_increment_aspect'
15
+ require 'co_aspects/aspects/stats_measure_aspect'
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: co_aspects
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gaston Jorquera
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aspector
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.14.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.14.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: newrelic_rpm
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.14'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: statsd-instrument
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: |
112
+ Collection of ready to use aspects with an annotation-like syntax to attach
113
+ it to methods.
114
+ email:
115
+ - gjorquera@gmail.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - Gemfile
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - bin/console
127
+ - bin/setup
128
+ - bin/test
129
+ - circle.yml
130
+ - co_aspects.gemspec
131
+ - lib/co_aspects.rb
132
+ - lib/co_aspects/annotation.rb
133
+ - lib/co_aspects/aspects/deprecate_aspect.rb
134
+ - lib/co_aspects/aspects/log_call_aspect.rb
135
+ - lib/co_aspects/aspects/rescue_and_notify_aspect.rb
136
+ - lib/co_aspects/aspects/stats_increment_aspect.rb
137
+ - lib/co_aspects/aspects/stats_measure_aspect.rb
138
+ - lib/co_aspects/aspects/statsd_helper.rb
139
+ - lib/co_aspects/attacher.rb
140
+ - lib/co_aspects/callbacks.rb
141
+ - lib/co_aspects/errors.rb
142
+ - lib/co_aspects/module.rb
143
+ - lib/co_aspects/rspec.rb
144
+ - lib/co_aspects/version.rb
145
+ homepage: https://github.com/comparaonline/co_aspects
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.4.8
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Collection of ready to use aspects.
169
+ test_files: []