coach 0.5.2 → 1.0.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
- SHA1:
3
- metadata.gz: 55ee934083e8a8e015a13a1bab92877e1643475e
4
- data.tar.gz: c54472da279b95b157b4c446d611be3fdaa5127b
2
+ SHA256:
3
+ metadata.gz: 6f4c3a75e36f5a68ae2833e84b8bc6ccc45acbde8a137644fad05960620ae1d9
4
+ data.tar.gz: fcb6e844520cd5d19bcab21acc7b3e50b02708c3f750eb078dd52f844d09c3ae
5
5
  SHA512:
6
- metadata.gz: f3d692848efe36f3a591af122a3f8393a9dddae02f6cd38c122f80b37d8dc4b49512ae00b9700734b15f5be72b4f731aa49486d09185975590b1bf894631e6c2
7
- data.tar.gz: 9fde65cf951062595231bee30227b44d083543fd84435f21b034f4a87877290918de21bce3b0cb2ff0598028d6def49696da53eeb313cac7fbfeb23cd5590d91
6
+ metadata.gz: c98ecef9fe5dc20158a6285c8d7f0c4c7bf0c9d7e1529c5c4a8c639cbab57a1cd17f3a43164eaffbd33c81441203904b899d282bebb55b280c3e544c2c9d4284
7
+ data.tar.gz: ef8d52b4fb9596707ee21f7e6908ed7bc2b47a242e7452b507e0c90efa84d5ce8b25b0f6b61a9722636d801b368c5318c06617ae796c65dfd619a599e461692c
@@ -0,0 +1,96 @@
1
+ version: 2
2
+
3
+ references:
4
+ steps: &steps
5
+ - checkout
6
+
7
+ - type: shell
8
+ name: Write RAILS_VERSION to a file so we can use it for caching purposes
9
+ command: echo "$RAILS_VERSION" > ~/RAILS_VERSION.txt
10
+
11
+ - type: cache-restore
12
+ key: coach-bundler-{{ checksum "coach.gemspec" }}-{{ checksum "~/RAILS_VERSION.txt" }}
13
+
14
+ - run: gem install bundler
15
+
16
+ - run: bundle install --path vendor/bundle
17
+
18
+ - type: cache-save
19
+ key: coach-bundler-{{ checksum "coach.gemspec" }}-{{ checksum "~/RAILS_VERSION.txt" }}
20
+ paths:
21
+ - vendor/bundle
22
+
23
+ - type: shell
24
+ command: |
25
+ bundle exec rspec --profile 10 \
26
+ --format RspecJunitFormatter \
27
+ --out /tmp/test-results/rspec.xml \
28
+ --format progress \
29
+ spec
30
+
31
+ - type: store_test_results
32
+ path: /tmp/test-results
33
+
34
+ - run: bundle exec rubocop
35
+ jobs:
36
+ build-ruby22-rails515:
37
+ docker:
38
+ - image: ruby:2.2
39
+ environment:
40
+ - RAILS_VERSION=5.1.5
41
+ steps: *steps
42
+ build-ruby22-rails4210:
43
+ docker:
44
+ - image: ruby:2.2
45
+ environment:
46
+ - RAILS_VERSION=4.2.10
47
+ steps: *steps
48
+ build-ruby23-rails515:
49
+ docker:
50
+ - image: ruby:2.3
51
+ environment:
52
+ - RAILS_VERSION=5.1.5
53
+ steps: *steps
54
+ build-ruby23-rails4210:
55
+ docker:
56
+ - image: ruby:2.3
57
+ environment:
58
+ - RAILS_VERSION=4.2.10
59
+ steps: *steps
60
+ build-ruby24-rails515:
61
+ docker:
62
+ - image: ruby:2.4
63
+ environment:
64
+ - RAILS_VERSION=5.1.5
65
+ steps: *steps
66
+ build-ruby24-rails4210:
67
+ docker:
68
+ - image: ruby:2.4
69
+ environment:
70
+ - RAILS_VERSION=4.2.10
71
+ steps: *steps
72
+ build-ruby25-rails515:
73
+ docker:
74
+ - image: ruby:2.5
75
+ environment:
76
+ - RAILS_VERSION=5.1.5
77
+ steps: *steps
78
+ build-ruby25-rails4210:
79
+ docker:
80
+ - image: ruby:2.5
81
+ environment:
82
+ - RAILS_VERSION=4.2.10
83
+ steps: *steps
84
+
85
+ workflows:
86
+ version: 2
87
+ tests:
88
+ jobs:
89
+ - build-ruby22-rails515
90
+ - build-ruby22-rails4210
91
+ - build-ruby23-rails515
92
+ - build-ruby23-rails4210
93
+ - build-ruby24-rails515
94
+ - build-ruby24-rails4210
95
+ - build-ruby25-rails515
96
+ - build-ruby25-rails4210
@@ -1,117 +1,20 @@
1
- # For all options see https://github.com/bbatsov/rubocop/tree/master/config
1
+ inherit_from: .rubocop_todo.yml
2
2
 
3
- # Limit lines to 90 characters.
4
- LineLength:
5
- Max: 90
3
+ inherit_gem:
4
+ gc_ruboconfig: rubocop.yml
6
5
 
7
- # Avoid methods longer than 30 lines of code
8
- MethodLength:
9
- CountComments: false # count full line comments?
10
- Max: 16
6
+ AllCops:
7
+ TargetRubyVersion: 2.2
11
8
 
12
- StringLiterals:
13
- Enabled: false
14
-
15
- # Wants underscores in all large numbers. Pain in the ass for things like
16
- # unix timestamps.
17
- NumericLiterals:
18
- Enabled: false
19
-
20
- # Wants you to use the same argument names for every reduce. This seems kinda
21
- # naff compared to naming them semantically
22
- SingleLineBlockParams:
23
- Enabled: false
24
-
25
- Style/SignalException:
26
- EnforcedStyle: 'only_raise'
27
-
28
- # Use trailing rather than leading dots on multi-line call chains
29
- Layout/DotPosition:
30
- EnforcedStyle: trailing
31
-
32
- Lint/NestedMethodDefinition:
33
- Enabled: false
34
-
35
- Lint/UnusedBlockArgument:
36
- Enabled: false
37
-
38
- Metrics/AbcSize:
39
- Max: 61
40
-
41
- Metrics/CyclomaticComplexity:
42
- Max: 10
43
-
44
- Metrics/PerceivedComplexity:
45
- Max: 10
46
-
47
- Naming/AccessorMethodName:
48
- Enabled: false
49
-
50
- # Allow non-ASCII characters (e.g. £) in comments
51
- Style/AsciiComments:
52
- Enabled: false
53
-
54
- # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
55
- Layout/AlignHash:
56
- Enabled: false
57
-
58
- # Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
59
- Style/BlockDelimiters:
60
- Enabled: false
61
-
62
- # Configuration parameters: EnforcedStyle, SupportedStyles.
63
- Style/ClassAndModuleChildren:
64
- Enabled: false
65
-
66
- Layout/ClosingParenthesisIndentation:
67
- Enabled: false
68
-
69
- # Configuration parameters: Keywords.
70
- Style/CommentAnnotation:
71
- Enabled: false
72
-
73
- Style/Documentation:
74
- Enabled: false
75
-
76
- Style/DoubleNegation:
77
- Enabled: false
78
-
79
- # Configuration parameters: MinBodyLength.
80
- Style/GuardClause:
81
- Enabled: false
82
-
83
- # Configuration parameters: EnforcedStyle, SupportedStyles.
84
- Layout/IndentHash:
85
- Enabled: false
86
-
87
- Style/Lambda:
88
- Enabled: false
89
-
90
- # Configuration parameters: EnforcedStyle, SupportedStyles.
91
- Layout/MultilineOperationIndentation:
92
- Enabled: false
93
-
94
- # Configuration parameters: NamePrefix, NamePrefixBlacklist.
95
- Naming/PredicateName:
96
- Enabled: false
97
-
98
- Style/RedundantSelf:
99
- Enabled: false
100
-
101
- Layout/SpaceBeforeFirstArg:
102
- Enabled: false
103
-
104
- # Configuration parameters: MultiSpaceAllowedForOperators.
105
- Layout/SpaceAroundOperators:
106
- Enabled: false
107
-
108
- # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
109
- Style/TrivialAccessors:
110
- Enabled: false
111
-
112
- Metrics/BlockLength:
9
+ Style/RescueStandardError:
113
10
  Exclude:
114
- - "**/*_spec.rb"
115
-
116
- Lint/RescueWithoutErrorClass:
117
- Enabled: false
11
+ - "*/**/*_spec.rb"
12
+
13
+ Naming/UncommunicativeMethodParamName:
14
+ AllowedNames:
15
+ # These are the default allowed names, set by Rubocop
16
+ - io
17
+ - id
18
+ # These are some custom names that we want to allow, since they aren't
19
+ # uncommunicative - they're actually rather meaningful!
20
+ - as
@@ -0,0 +1,27 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2018-03-08 12:21:23 +0000 using RuboCop version 0.53.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Max.
11
+ RSpec/ExampleLength:
12
+ Exclude:
13
+ - 'spec/lib/coach/notifications_spec.rb'
14
+
15
+ # Offense count: 5
16
+ # Configuration parameters: AggregateFailuresByDefault.
17
+ RSpec/MultipleExpectations:
18
+ Max: 3
19
+
20
+ # Offense count: 12
21
+ # Configuration parameters: Max.
22
+ RSpec/NestedGroups:
23
+ Exclude:
24
+ - 'spec/lib/coach/handler_spec.rb'
25
+ - 'spec/lib/coach/middleware_validator_spec.rb'
26
+ - 'spec/lib/coach/request_serializer_spec.rb'
27
+ - 'spec/lib/coach/router_spec.rb'
@@ -1,6 +1,26 @@
1
1
  # CHANGELOG
2
2
 
3
- * [#29](https://github.com/gocardless/coach/pull/29) Replace Coach.require_matchers! with actual require
3
+ # 1.0.0 / 2018-04-19
4
+
5
+ ## Breaking changes
6
+
7
+ * [#41](https://github.com/gocardless/coach/pull/41) Ruby versions before 2.1 are no
8
+ longer supported.
9
+ * [#29](https://github.com/gocardless/coach/pull/29) To use Coach's included matchers
10
+ in RSpec, you should now `require coach/rspec`. `Coach.require_matchers!` is deprecated
11
+ and will be removed in a future version.
12
+ * [#47](https://github.com/gocardless/coach/pull/47) If you're using Coach's support for
13
+ [instrumentation](https://github.com/gocardless/coach#instrumentation) with
14
+ `ActiveSupport::Notifications`, the event names Coach publishes have changed to be more
15
+ consistent with other libraries. The previous names will work for now, but will be removed in a future version. The changes are as follows:
16
+
17
+ | Before | After |
18
+ | ----------------------- | ------------------------|
19
+ | coach.handler.start | start_handler.coach |
20
+ | coach.middleware.start | start_middleware.coach |
21
+ | coach.middleware.finish | finish_middleware.coach |
22
+ | coach.handler.finish | finish_handler.coach |
23
+ | coach.request | request.coach |
4
24
 
5
25
  # 0.5.1 / 2017-08-21
6
26
 
data/Gemfile CHANGED
@@ -2,4 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem "gc_ruboconfig", "~> 2.3.4"
5
6
  gem "rails", "~> #{ENV['RAILS_VERSION']}" if ENV["RAILS_VERSION"]
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017 GoCardless
1
+ Copyright (c) 2018 GoCardless
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -13,6 +13,16 @@ Coach improves your controller code by encouraging:
13
13
  - **Testability** - Test each middleware in isolation, with effortless mocking of test
14
14
  data and natural RSpec matchers.
15
15
 
16
+ # Installation
17
+
18
+ To get started, just add Coach to your `Gemfile`, and then run `bundle`:
19
+
20
+ ```ruby
21
+ gem 'coach'
22
+ ```
23
+
24
+ Coach works with Ruby versions 2.2 and onwards.
25
+
16
26
  ## Coach by example
17
27
 
18
28
  The best way to see the benefits of Coach is with a demonstration.
@@ -284,19 +294,33 @@ Information for how to use `ActiveSupport`s notifications can be found
284
294
 
285
295
  | Event | Arguments |
286
296
  |-------------------------------|------------------------------------------------------- |
287
- | `coach.handler.start` | `event(:middleware, :request)` |
288
- | `coach.middleware.start` | `event(:middleware, :request)` |
289
- | `coach.middleware.finish` | `start`, `finish`, `id`, `event(:middleware, :request)`|
290
- | `coach.handler.finish` | `start`, `finish`, `id`, `event(:middleware, :request)`|
291
- | `coach.request` | `event` containing request data and benchmarking |
297
+ | `start_handler.coach` | `event(:middleware, :request)` |
298
+ | `start_middleware.coach` | `event(:middleware, :request)` |
299
+ | `finish_middleware.coach` | `start`, `finish`, `id`, `event(:middleware, :request)`|
300
+ | `finish_handler.coach` | `start`, `finish`, `id`, `event(:middleware, :request)`|
301
+ | `request.coach` | `event` containing request data and benchmarking |
292
302
 
293
- Of special interest is `coach.request`, which publishes statistics on an entire
303
+ Of special interest is `request.coach`, which publishes statistics on an entire
294
304
  middleware chain and request. This data is particularly useful for logging, and is our
295
305
  solution to Rails `process_action.action_controller` event emitted on controller requests.
296
306
 
297
307
  The benchmarking data includes information on how long each middleware took to process,
298
308
  along with the total duration of the chain.
299
309
 
310
+ You can add additional metadata to the notifications published by Coach by calling the
311
+ `log_metadata` method from inside your Coach middlewares.
312
+
313
+ ```
314
+ class Tracking < Coach::Middleware
315
+ requires :user
316
+
317
+ def call
318
+ log_metadata(user_id: user.id)
319
+ next_middleware.call
320
+ end
321
+ end
322
+ ```
323
+
300
324
  # License & Contributing
301
325
 
302
326
  * Coach is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,25 +1,26 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("lib", __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'coach/version'
3
+ require "coach/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = 'coach'
6
+ spec.name = "coach"
7
7
  spec.version = Coach::VERSION
8
- spec.summary = 'Alternative controllers built with middleware'
8
+ spec.summary = "Alternative controllers built with middleware"
9
9
  spec.authors = %w[GoCardless]
10
10
  spec.homepage = "https://github.com/gocardless/coach"
11
11
  spec.email = %w[developers@gocardless.com]
12
- spec.license = 'MIT'
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = ">= 2.2"
13
14
 
14
15
  spec.files = `git ls-files -z`.split("\x0")
15
16
  spec.test_files = spec.files.grep(%r{^spec/})
16
- spec.require_paths = ['lib']
17
+ spec.require_paths = ["lib"]
17
18
 
18
- spec.add_dependency 'actionpack', '>= 4.2'
19
- spec.add_dependency 'activesupport', '>= 4.2'
19
+ spec.add_dependency "actionpack", ">= 4.2"
20
+ spec.add_dependency "activesupport", ">= 4.2"
20
21
 
21
- spec.add_development_dependency 'rspec', '~> 3.2'
22
- spec.add_development_dependency 'rspec-its', '~> 1.2'
23
- spec.add_development_dependency 'pry', '~> 0.10'
24
- spec.add_development_dependency 'rubocop', '~> 0.50.0'
22
+ spec.add_development_dependency "pry", "~> 0.10"
23
+ spec.add_development_dependency "rspec", "~> 3.2"
24
+ spec.add_development_dependency "rspec-its", "~> 1.2"
25
+ spec.add_development_dependency "rspec_junit_formatter", "~> 0.3.0"
25
26
  end
@@ -1,21 +1,21 @@
1
- require 'active_support'
2
- require 'action_dispatch'
1
+ require "active_support"
2
+ require "action_dispatch"
3
3
 
4
- require_relative 'coach/errors'
5
- require_relative 'coach/handler'
6
- require_relative 'coach/middleware'
7
- require_relative 'coach/middleware_item'
8
- require_relative 'coach/middleware_validator'
9
- require_relative 'coach/notifications'
10
- require_relative 'coach/request_benchmark'
11
- require_relative 'coach/request_serializer'
12
- require_relative 'coach/router'
13
- require_relative 'coach/version'
4
+ require_relative "coach/errors"
5
+ require_relative "coach/handler"
6
+ require_relative "coach/middleware"
7
+ require_relative "coach/middleware_item"
8
+ require_relative "coach/middleware_validator"
9
+ require_relative "coach/notifications"
10
+ require_relative "coach/request_benchmark"
11
+ require_relative "coach/request_serializer"
12
+ require_relative "coach/router"
13
+ require_relative "coach/version"
14
14
 
15
15
  module Coach
16
16
  def self.require_matchers!
17
17
  puts "Calling Coach.require_matchers! is deprecated, " \
18
18
  "please use `require 'coach/rspec'` instead"
19
- require_relative 'coach/rspec'
19
+ require_relative "coach/rspec"
20
20
  end
21
21
  end
@@ -1,4 +1,5 @@
1
1
  require "coach/errors"
2
+ require "active_support/core_ext/object/try"
2
3
 
3
4
  module Coach
4
5
  class Handler
@@ -15,10 +16,11 @@ module Coach
15
16
 
16
17
  # Run validation on the root of the middleware chain
17
18
  delegate :validate!, to: :@root_item
18
- delegate :publish, :instrument, to: ActiveSupport::Notifications
19
+ delegate :publish, :instrument, :notifier, to: ActiveSupport::Notifications
19
20
 
20
21
  # The Rack interface to handler - builds a middleware chain based on
21
22
  # the current request, and invokes it.
23
+ # rubocop:disable Metrics/MethodLength
22
24
  def call(env)
23
25
  context = { request: ActionDispatch::Request.new(env) }
24
26
  sequence = build_sequence(@root_item, context)
@@ -26,8 +28,8 @@ module Coach
26
28
 
27
29
  event = build_event(context)
28
30
 
29
- publish('coach.handler.start', event.dup)
30
- instrument('coach.handler.finish', event) do
31
+ publish_start(event.dup)
32
+ instrumented_call(event) do
31
33
  begin
32
34
  response = chain.instrument.call
33
35
  ensure
@@ -36,15 +38,16 @@ module Coach
36
38
  # simplest way to do this is pass the event by reference to ActiveSupport, then
37
39
  # modify the hash to contain this detail before the instrumentation completes.
38
40
  #
39
- # This way, the last coach.handler.finish event will have all the details.
41
+ # This way, the last finish_handler.coach event will have all the details.
40
42
  status = response.try(:first) || STATUS_CODE_FOR_EXCEPTIONS
41
43
  event.merge!(
42
44
  response: { status: status },
43
- metadata: context.fetch(:_metadata, {})
45
+ metadata: context.fetch(:_metadata, {}),
44
46
  )
45
47
  end
46
48
  end
47
49
  end
50
+ # rubocop:enable Metrics/MethodLength
48
51
 
49
52
  # Traverse the middlware tree to build a linear middleware sequence,
50
53
  # containing only middlewares that apply to this request.
@@ -81,8 +84,31 @@ module Coach
81
84
  def build_event(context)
82
85
  {
83
86
  middleware: @root_item.middleware.name,
84
- request: context[:request]
87
+ request: context[:request],
85
88
  }
86
89
  end
90
+
91
+ def publish_start(event)
92
+ if notifier.listening?("coach.handler.start")
93
+ ActiveSupport::Deprecation.warn("The 'coach.handler.start' event has been " \
94
+ "renamed to 'start_handler.coach' and the old name will be removed in a " \
95
+ "future version.")
96
+ publish("coach.handler.start", event)
97
+ end
98
+ publish("start_handler.coach", event)
99
+ end
100
+
101
+ def instrumented_call(event, &block)
102
+ if notifier.listening?("coach.handler.finish")
103
+ ActiveSupport::Deprecation.warn("The 'coach.handler.find' event has been " \
104
+ "renamed to 'finish_handler.coach' and the old name will be removed in a " \
105
+ "future version.")
106
+ instrument("coach.handler.finish", event) do
107
+ instrument("finish_handler.coach", event, &block)
108
+ end
109
+ else
110
+ instrument("finish_handler.coach", event, &block)
111
+ end
112
+ end
87
113
  end
88
114
  end