ownership 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/README.md +139 -0
- data/Rakefile +11 -0
- data/lib/ownership.rb +38 -0
- data/lib/ownership/controller_methods.rb +15 -0
- data/lib/ownership/global_methods.rb +26 -0
- data/lib/ownership/job_methods.rb +15 -0
- data/lib/ownership/marginalia.rb +9 -0
- data/lib/ownership/rollbar.rb +48 -0
- data/lib/ownership/version.rb +3 -0
- data/ownership.gemspec +27 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 38e0f9794b246e9f4d788f460db5aeb663f6f45e
|
4
|
+
data.tar.gz: a7d3477d27cbd3aa0cddd55269246922d198a919
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c57c183a32991967c30aba4a926d4c1ef2076b8100d4ae7aa09e32e3ea395214fe3d833209263fd399547105c3ab9484676eeba0f9ee5577889f1b60524b6146
|
7
|
+
data.tar.gz: d3df7b1a97faacd87fb05248001358244466c656a2fc9fa2fb2638a670729f9cd60ac42468d207afe1f0c68f6ff9471bec0bb992559056bb1ee787ac9999218d
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# Ownership
|
2
|
+
|
3
|
+
Code ownership for your Rails app
|
4
|
+
|
5
|
+
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application’s Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'ownership'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Getting Started
|
16
|
+
|
17
|
+
Ownership provides the ability to specify owners for different parts of the codebase. **We highly recommend owners are teams rather than individuals.** You can then use this information however you’d like, like routing errors to the correct team.
|
18
|
+
|
19
|
+
## Specifying Ownership
|
20
|
+
|
21
|
+
### Controllers
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class OrdersController < ApplicationController
|
25
|
+
owner :logistics
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
You can use any options that `before_action` supports.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
class OrdersController < ApplicationController
|
33
|
+
owner :logistics, only: [:index]
|
34
|
+
owner :customers, except: [:index]
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
### Jobs
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class SomeJob < ApplicationJob
|
42
|
+
owner :logistics
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
### Anywhere
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
owner :logistics do
|
50
|
+
# code
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Default
|
55
|
+
|
56
|
+
You can set a default owner with:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Ownership.default_owner = :logistics
|
60
|
+
```
|
61
|
+
|
62
|
+
## Integrations
|
63
|
+
|
64
|
+
There are a few built-in integrations with other gems.
|
65
|
+
|
66
|
+
### Marginalia
|
67
|
+
|
68
|
+
[Marginalia](https://github.com/basecamp/marginalia) adds comments to ActiveRecord queries. If installed, the owner is added.
|
69
|
+
|
70
|
+
```sql
|
71
|
+
SELECT ...
|
72
|
+
/*application:MyApp,controller:posts,action:index,owner:logistics*/
|
73
|
+
```
|
74
|
+
|
75
|
+
This can be useful when looking at the most time-consuming queries on your database.
|
76
|
+
|
77
|
+
### Rollbar
|
78
|
+
|
79
|
+
[Rollbar](https://github.com/rollbar/rollbar-gem) tracks exceptions. This integration makes it easy to send exceptions to different projects based on the owner. We recommend having a project for each team.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Ownership::Rollbar.access_token = {
|
83
|
+
logistics: "token1",
|
84
|
+
customers: "token2"
|
85
|
+
}
|
86
|
+
```
|
87
|
+
|
88
|
+
Also works with a proc
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Ownership::Rollbar.access_token = -> (owner) { ENV["#{owner.to_s.upcase}_ROLLBAR_ACCESS_TOKEN"] }
|
92
|
+
```
|
93
|
+
|
94
|
+
## Custom Integrations
|
95
|
+
|
96
|
+
You can define a custom block of code to run with:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
Ownership.around_change = proc do |owner, block|
|
100
|
+
puts "New owner: #{owner}"
|
101
|
+
block.call
|
102
|
+
puts "Done"
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
Please don’t hesitate to [submit a pull request](https://github.com/ankane/ownership/pulls) if you create an integration that others can use.
|
107
|
+
|
108
|
+
Exceptions that bubble up from an `owner` block have the owner, which your exception reporting library can use.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
begin
|
112
|
+
owner :logistics do
|
113
|
+
raise "error"
|
114
|
+
end
|
115
|
+
rescue => e
|
116
|
+
puts e.owner # :logistics
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
## Other Useful Tools
|
121
|
+
|
122
|
+
- [GitHub Code Owners](https://github.com/blog/2392-introducing-code-owners) for code reviews
|
123
|
+
|
124
|
+
## Thanks
|
125
|
+
|
126
|
+
Thanks to [Nick Elser](https://github.com/nickelser) for creating this pattern.
|
127
|
+
|
128
|
+
## History
|
129
|
+
|
130
|
+
View the [changelog](https://github.com/ankane/ownership/blob/master/CHANGELOG.md).
|
131
|
+
|
132
|
+
## Contributing
|
133
|
+
|
134
|
+
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
135
|
+
|
136
|
+
- [Report bugs](https://github.com/ankane/ownership/issues)
|
137
|
+
- Fix bugs and [submit pull requests](https://github.com/ankane/ownership/pulls)
|
138
|
+
- Write, clarify, or fix documentation
|
139
|
+
- Suggest or add new features
|
data/Rakefile
ADDED
data/lib/ownership.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "ownership/global_methods"
|
2
|
+
require "ownership/rollbar"
|
3
|
+
require "ownership/version"
|
4
|
+
|
5
|
+
module Ownership
|
6
|
+
class << self
|
7
|
+
attr_accessor :default_owner
|
8
|
+
attr_accessor :around_change
|
9
|
+
|
10
|
+
def owner
|
11
|
+
Thread.current[:ownership_owner] || default_owner
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Object.send :include, Ownership::GlobalMethods
|
17
|
+
|
18
|
+
if defined?(ActiveSupport)
|
19
|
+
ActiveSupport.on_load(:action_controller) do
|
20
|
+
require "ownership/controller_methods"
|
21
|
+
include Ownership::ControllerMethods
|
22
|
+
end
|
23
|
+
|
24
|
+
ActiveSupport.on_load(:active_record) do
|
25
|
+
require "ownership/marginalia" if defined?(Marginalia)
|
26
|
+
end
|
27
|
+
|
28
|
+
ActiveSupport.on_load(:active_job) do
|
29
|
+
require "ownership/job_methods"
|
30
|
+
include Ownership::JobMethods
|
31
|
+
end
|
32
|
+
else
|
33
|
+
require "ownership/marginalia" if defined?(Marginalia)
|
34
|
+
end
|
35
|
+
|
36
|
+
class Exception
|
37
|
+
attr_accessor :owner
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
|
3
|
+
module Ownership
|
4
|
+
module ControllerMethods
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def owner(owner, options = {})
|
9
|
+
around_action options do |_, block|
|
10
|
+
owner(owner) { block.call }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ownership
|
2
|
+
module GlobalMethods
|
3
|
+
def owner(owner, &block)
|
4
|
+
raise ArgumentError, "Missing block" unless block_given?
|
5
|
+
|
6
|
+
previous_value = Thread.current[:ownership_owner]
|
7
|
+
begin
|
8
|
+
Thread.current[:ownership_owner] = owner
|
9
|
+
|
10
|
+
begin
|
11
|
+
# callbacks
|
12
|
+
if Ownership.around_change
|
13
|
+
Ownership.around_change.call(owner, block)
|
14
|
+
else
|
15
|
+
block.call
|
16
|
+
end
|
17
|
+
rescue Exception => e
|
18
|
+
e.owner = owner
|
19
|
+
raise
|
20
|
+
end
|
21
|
+
ensure
|
22
|
+
Thread.current[:ownership_owner] = previous_value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Ownership
|
2
|
+
module Rollbar
|
3
|
+
class << self
|
4
|
+
attr_reader :access_token
|
5
|
+
|
6
|
+
def access_token=(access_token)
|
7
|
+
@access_token = access_token
|
8
|
+
@configure ||= configure # just once
|
9
|
+
access_token
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def owner_access_token(owner)
|
15
|
+
access_token.respond_to?(:call) ? access_token.call(owner) : access_token[owner]
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure
|
19
|
+
::Rollbar.configure do |config|
|
20
|
+
config.before_process << proc do |options|
|
21
|
+
options[:scope][:ownership_owner] = Ownership.owner if Ownership.owner
|
22
|
+
end
|
23
|
+
|
24
|
+
config.transform << proc do |options|
|
25
|
+
# clean up payload
|
26
|
+
options[:payload]["data"].delete(:ownership_owner)
|
27
|
+
|
28
|
+
owner = options[:exception].owner if options[:exception].respond_to?(:owner)
|
29
|
+
unless owner
|
30
|
+
owner = options[:scope][:ownership_owner] if options[:scope].is_a?(Hash)
|
31
|
+
owner ||= Ownership.default_owner
|
32
|
+
end
|
33
|
+
|
34
|
+
if owner
|
35
|
+
access_token = owner_access_token(owner)
|
36
|
+
if access_token
|
37
|
+
options[:payload]["access_token"] = access_token
|
38
|
+
else
|
39
|
+
warn "[ownership] Missing Rollbar access token for owner: #{owner}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/ownership.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "ownership/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ownership"
|
8
|
+
spec.version = Ownership::VERSION
|
9
|
+
spec.authors = ["Andrew Kane"]
|
10
|
+
spec.email = ["andrew@chartkick.com"]
|
11
|
+
|
12
|
+
spec.summary = "Code ownership for your Rails app"
|
13
|
+
spec.homepage = "https://github.com/ankane/ownership"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "minitest"
|
25
|
+
spec.add_development_dependency "activejob"
|
26
|
+
spec.add_development_dependency "marginalia"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ownership
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Kane
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activejob
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: marginalia
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- andrew@chartkick.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- CHANGELOG.md
|
92
|
+
- Gemfile
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- lib/ownership.rb
|
96
|
+
- lib/ownership/controller_methods.rb
|
97
|
+
- lib/ownership/global_methods.rb
|
98
|
+
- lib/ownership/job_methods.rb
|
99
|
+
- lib/ownership/marginalia.rb
|
100
|
+
- lib/ownership/rollbar.rb
|
101
|
+
- lib/ownership/version.rb
|
102
|
+
- ownership.gemspec
|
103
|
+
homepage: https://github.com/ankane/ownership
|
104
|
+
licenses: []
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.6.13
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Code ownership for your Rails app
|
126
|
+
test_files: []
|