party_foul 1.2.2 → 1.3.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 +4 -4
- data/README.md +8 -8
- data/lib/generators/party_foul/install_generator.rb +9 -9
- data/lib/generators/party_foul/templates/party_foul.rb +2 -2
- data/lib/party_foul.rb +15 -11
- data/lib/party_foul/exception_handler.rb +12 -10
- data/lib/party_foul/issue_renderers/base.rb +16 -4
- data/lib/party_foul/issue_renderers/rails.rb +2 -2
- data/lib/party_foul/rackless_exception_handler.rb +1 -1
- data/lib/party_foul/version.rb +1 -1
- data/test/generator_test.rb +4 -7
- data/test/party_foul/configure_test.rb +4 -3
- data/test/party_foul/exception_handler_test.rb +33 -41
- data/test/party_foul/issue_renderers/base_test.rb +29 -0
- data/test/party_foul/issue_renderers/rails_test.rb +14 -1
- data/test/test_helper.rb +3 -2
- data/test/tmp/config/initializers/party_foul.rb +2 -2
- metadata +21 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04841443e30d275130c1d6751de062e44feea034
|
4
|
+
data.tar.gz: d3e1222567bfd402d0d337c37dbbfdab1a2833bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 153edf86b0234e3039b971d4a820456857a3c0e90960e69027094326de56a5e0521b59c715682c9da5d761fbd67121bd818e07ae6bc17c5944af1103f0b65c6e
|
7
|
+
data.tar.gz: bf1114177b74cafc812da05af5c8ee87fc458dcf381c0a8012cd0a75501979cb38f5bb63230f78fd94eb4c80c043ed5921dfef9aebbb32fa4f7f97ba894f93ec
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/dockyard/party_foul)
|
4
4
|
[](https://gemnasium.com/dockyard/party_foul)
|
5
|
-
[](https://codeclimate.com/github/dockyard/party_foul)
|
6
6
|
|
7
7
|
Rails exceptions automatically opened as issues on GitHub
|
8
8
|
|
@@ -81,7 +81,7 @@ PartyFoul.configure do |config|
|
|
81
81
|
|
82
82
|
# The API endpoint for GitHub. Unless you are hosting a private
|
83
83
|
# instance of Enterprise GitHub you do not need to include this
|
84
|
-
config.
|
84
|
+
config.api_endpoint = 'https://api.github.com'
|
85
85
|
|
86
86
|
# The Web URL for GitHub. Unless you are hosting a private
|
87
87
|
# instance of Enterprise GitHub you do not need to include this
|
@@ -198,9 +198,9 @@ The code that you want to handle should be wrapped like so:
|
|
198
198
|
```ruby
|
199
199
|
begin
|
200
200
|
... # some code that might raise an error
|
201
|
-
rescue =>
|
202
|
-
PartyFoul::RacklessExceptionHandler.handle(
|
203
|
-
raise
|
201
|
+
rescue => error
|
202
|
+
PartyFoul::RacklessExceptionHandler.handle(error, {class: class_name, method: method_name, params: message)
|
203
|
+
raise error
|
204
204
|
end
|
205
205
|
```
|
206
206
|
|
@@ -215,9 +215,9 @@ module PartyFoul
|
|
215
215
|
def call(worker, msg, queue)
|
216
216
|
begin
|
217
217
|
yield
|
218
|
-
rescue =>
|
219
|
-
PartyFoul::RacklessExceptionHandler.handle(
|
220
|
-
raise
|
218
|
+
rescue => error
|
219
|
+
PartyFoul::RacklessExceptionHandler.handle(error, {class: worker.class.name, method: queue, params: msg})
|
220
|
+
raise error
|
221
221
|
end
|
222
222
|
end
|
223
223
|
end
|
@@ -6,18 +6,18 @@ module PartyFoul
|
|
6
6
|
source_root File.expand_path('../templates', __FILE__)
|
7
7
|
|
8
8
|
def create_initializer_file
|
9
|
-
login
|
10
|
-
password
|
11
|
-
@owner
|
12
|
-
@repo
|
13
|
-
@
|
14
|
-
@web_url
|
9
|
+
login = ask 'GitHub login:'
|
10
|
+
password = ask 'GitHub password:'
|
11
|
+
@owner = ask_with_default "\nRepository owner:", login
|
12
|
+
@repo = ask 'Repository name:'
|
13
|
+
@api_endpoint = ask_with_default 'Api Endpoint:', 'https://api.github.com'
|
14
|
+
@web_url = ask_with_default 'Web URL:', 'https://github.com'
|
15
15
|
|
16
16
|
begin
|
17
|
-
|
18
|
-
@oauth_token =
|
17
|
+
octokit = Octokit.new :login => login, :password => password, :api_endpoint => @api_endpoint
|
18
|
+
@oauth_token = octokit.create_authorization(scopes: ['repo'], note: "PartyFoul #{@owner}/#{@repo}", note_url: "#{@web_url}/#{@owner}/#{@repo}").token
|
19
19
|
template 'party_foul.rb', 'config/initializers/party_foul.rb'
|
20
|
-
rescue
|
20
|
+
rescue Octokit::Unauthorized
|
21
21
|
say 'There was an error retrieving your GitHub OAuth token'
|
22
22
|
end
|
23
23
|
end
|
@@ -6,9 +6,9 @@ PartyFoul.configure do |config|
|
|
6
6
|
# The OAuth token for the account that is opening the issues on GitHub
|
7
7
|
config.oauth_token = '<%= @oauth_token %>'
|
8
8
|
|
9
|
-
# The API
|
9
|
+
# The API api_endpoint for GitHub. Unless you are hosting a private
|
10
10
|
# instance of Enterprise GitHub you do not need to include this
|
11
|
-
config.
|
11
|
+
config.api_endpoint = '<%= @api_endpoint %>'
|
12
12
|
|
13
13
|
# The Web URL for GitHub. Unless you are hosting a private
|
14
14
|
# instance of Enterprise GitHub you do not need to include this
|
data/lib/party_foul.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
require '
|
1
|
+
require 'octokit'
|
2
2
|
|
3
3
|
module PartyFoul
|
4
4
|
class << self
|
5
|
-
attr_accessor :github, :oauth_token, :
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.whitelisted_rack_variables
|
9
|
-
@whitelisted_rack_variables ||= %w{GATEWAY_INTERFACE PATH_INFO REMOTE_ADDR REMOTE_HOST REQUEST_METHOD REQUEST_URI SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE HTTP_HOST HTTP_CONNECTION HTTP_CACHE_CONTROL HTTP_ACCEPT HTTP_USER_AGENT HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_ACCEPT_CHARSET rack.version rack.input rack.errors rack.multithread rack.multiprocess rack.run_once rack.url_scheme HTTP_VERSION REQUEST_PATH ORIGINAL_FULLPATH action_dispatch.routes action_dispatch.parameter_filter action_dispatch.secret_token action_dispatch.show_exceptions action_dispatch.show_detailed_exceptions action_dispatch.logger action_dispatch.backtrace_cleaner action_dispatch.request_id action_dispatch.remote_ip rack.session rack.session.options rack.request.cookie_hash rack.request.cookie_string action_dispatch.cookies action_dispatch.request.unsigned_session_cookie action_dispatch.request.path_parameters action_controller.instance action_dispatch.request.request_parameters rack.request.query_string rack.request.query_hash action_dispatch.request.query_parameters action_dispatch.request.parameters action_dispatch.request.formats}
|
5
|
+
attr_accessor :github, :oauth_token, :api_endpoint, :owner, :repo, :blacklisted_exceptions, :processor, :web_url, :branch, :whitelisted_rack_variables, :additional_labels, :comment_limit
|
10
6
|
end
|
11
7
|
|
12
8
|
# The git branch that is used for linking in the stack trace
|
@@ -28,8 +24,8 @@ module PartyFoul
|
|
28
24
|
# users
|
29
25
|
#
|
30
26
|
# @return [String] Defaults to 'https://api.github.com' if not set
|
31
|
-
def self.
|
32
|
-
@
|
27
|
+
def self.api_endpoint
|
28
|
+
@api_endpoint ||= 'https://api.github.com'
|
33
29
|
end
|
34
30
|
|
35
31
|
# The processor to be used when handling the exception. Defaults to a
|
@@ -55,12 +51,20 @@ module PartyFoul
|
|
55
51
|
@blacklisted_exceptions || []
|
56
52
|
end
|
57
53
|
|
58
|
-
# The
|
54
|
+
# The GitHub path to the repo
|
55
|
+
# Built using {.owner} and {.repo}
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
def self.repo_path
|
59
|
+
"#{owner}/#{repo}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# The url of the repository. Built using the {.web_url} and {.repo_path}
|
59
63
|
# values
|
60
64
|
#
|
61
65
|
# @return [String]
|
62
66
|
def self.repo_url
|
63
|
-
"#{web_url}/#{
|
67
|
+
"#{web_url}/#{repo_path}"
|
64
68
|
end
|
65
69
|
|
66
70
|
# The configure block for PartyFoul. Use to initialize settings
|
@@ -76,7 +80,7 @@ module PartyFoul
|
|
76
80
|
# @param [Block]
|
77
81
|
def self.configure(&block)
|
78
82
|
yield self
|
79
|
-
self.github ||=
|
83
|
+
self.github ||= Octokit.new oauth_token: oauth_token, api_endpoint: api_endpoint
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
@@ -36,8 +36,8 @@ class PartyFoul::ExceptionHandler
|
|
36
36
|
|
37
37
|
# Hits the GitHub API to find the matching issue using the fingerprint.
|
38
38
|
def find_issue
|
39
|
-
unless issue = PartyFoul.github.
|
40
|
-
issue = PartyFoul.github.
|
39
|
+
unless issue = PartyFoul.github.search_issues(PartyFoul.repo_path, fingerprint, 'open').first
|
40
|
+
issue = PartyFoul.github.search_issues(PartyFoul.repo_path, fingerprint, 'closed').first
|
41
41
|
end
|
42
42
|
|
43
43
|
issue
|
@@ -45,9 +45,9 @@ class PartyFoul::ExceptionHandler
|
|
45
45
|
|
46
46
|
# Will create a new issue and a comment with the proper details. All issues are labeled as 'bug'.
|
47
47
|
def create_issue
|
48
|
-
self.sha = PartyFoul.github.
|
49
|
-
issue = PartyFoul.github.
|
50
|
-
PartyFoul.github.
|
48
|
+
self.sha = PartyFoul.github.references(PartyFoul.repo_path, "heads/#{PartyFoul.branch}").object.sha
|
49
|
+
issue = PartyFoul.github.create_issue(PartyFoul.repo_path, rendered_issue.title, rendered_issue.body, labels: ['bug'] + rendered_issue.labels)
|
50
|
+
PartyFoul.github.add_comment(PartyFoul.repo_path, issue['number'], rendered_issue.comment)
|
51
51
|
end
|
52
52
|
|
53
53
|
# Updates the given issue. If the issue is labeled as 'wontfix' nothing is done. If the issue is closed the issue is reopened and labeled as 'regression'.
|
@@ -55,16 +55,18 @@ class PartyFoul::ExceptionHandler
|
|
55
55
|
# @param [Hashie::Mash]
|
56
56
|
def update_issue(issue)
|
57
57
|
unless issue.key?('labels') && issue['labels'].include?('wontfix')
|
58
|
-
|
58
|
+
body = rendered_issue.update_body(issue['body'])
|
59
|
+
params = {state: 'open'}
|
59
60
|
|
60
61
|
if issue['state'] == 'closed'
|
61
62
|
params[:labels] = (['bug', 'regression'] + issue['labels']).uniq
|
62
63
|
end
|
63
64
|
|
64
|
-
self.sha = PartyFoul.github.
|
65
|
-
PartyFoul.github.
|
65
|
+
self.sha = PartyFoul.github.references(PartyFoul.repo_path, "heads/#{PartyFoul.branch}").object.sha
|
66
|
+
PartyFoul.github.update_issue(PartyFoul.repo_path, issue['number'], issue.title, body, params)
|
67
|
+
|
66
68
|
unless comment_limit_met?(issue['body'])
|
67
|
-
PartyFoul.github.
|
69
|
+
PartyFoul.github.add_comment(PartyFoul.repo_path, issue['number'], rendered_issue.comment)
|
68
70
|
end
|
69
71
|
end
|
70
72
|
end
|
@@ -72,7 +74,7 @@ class PartyFoul::ExceptionHandler
|
|
72
74
|
private
|
73
75
|
|
74
76
|
def self.clean_env(env)
|
75
|
-
env.select { |key, value|
|
77
|
+
env.select { |key, value| Marshal.dump(value) rescue false }
|
76
78
|
end
|
77
79
|
|
78
80
|
def fingerprint
|
@@ -53,10 +53,10 @@ BODY
|
|
53
53
|
# @return [String]
|
54
54
|
def stack_trace
|
55
55
|
exception.backtrace.map do |line|
|
56
|
-
if matches = extract_file_name_and_line_number(line)
|
57
|
-
"<a href='#{PartyFoul.repo_url}/blob/#{sha}/#{matches[2]}#L#{matches[3]}'>#{line}</a>"
|
56
|
+
if (matches = extract_file_name_and_line_number(line))
|
57
|
+
"<a href='#{PartyFoul.repo_url}/blob/#{sha}/#{matches[2]}#L#{matches[3]}'>#{format_line(line)}</a>"
|
58
58
|
else
|
59
|
-
line
|
59
|
+
format_line(line)
|
60
60
|
end
|
61
61
|
end.join("\n")
|
62
62
|
end
|
@@ -107,7 +107,6 @@ BODY
|
|
107
107
|
{ 'Occurred At' => occurred_at }
|
108
108
|
end
|
109
109
|
|
110
|
-
|
111
110
|
# Builds an HTML table from hash
|
112
111
|
#
|
113
112
|
# @return [String]
|
@@ -149,6 +148,10 @@ BODY
|
|
149
148
|
Dir.pwd
|
150
149
|
end
|
151
150
|
|
151
|
+
def bundle_root
|
152
|
+
Bundler.bundle_path.to_s if defined?(Bundler)
|
153
|
+
end
|
154
|
+
|
152
155
|
def extract_file_name_and_line_number(backtrace_line)
|
153
156
|
backtrace_line.match(/#{app_root}\/((.+?):(\d+))/)
|
154
157
|
end
|
@@ -156,4 +159,13 @@ BODY
|
|
156
159
|
def raw_title
|
157
160
|
raise NotImplementedError
|
158
161
|
end
|
162
|
+
|
163
|
+
def format_line(line)
|
164
|
+
if bundle_root
|
165
|
+
line.sub(app_root, '[app]...').sub(bundle_root, '[bundle]...')
|
166
|
+
else
|
167
|
+
line.sub(app_root, '[app]...')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
159
171
|
end
|
@@ -12,13 +12,13 @@ class PartyFoul::IssueRenderers::Rails < PartyFoul::IssueRenderers::Rack
|
|
12
12
|
# @return [Hash]
|
13
13
|
def session
|
14
14
|
parameter_filter = ActionDispatch::Http::ParameterFilter.new(env['action_dispatch.parameter_filter'])
|
15
|
-
parameter_filter.filter(env['rack.session'])
|
15
|
+
parameter_filter.filter(env['rack.session'] || { } )
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def app_root
|
21
|
-
Rails.root
|
21
|
+
Rails.root.to_s
|
22
22
|
end
|
23
23
|
|
24
24
|
def raw_title
|
@@ -5,7 +5,7 @@ class PartyFoul::RacklessExceptionHandler < PartyFoul::ExceptionHandler
|
|
5
5
|
#
|
6
6
|
# @param [Exception, Hash]
|
7
7
|
def self.handle(exception, env)
|
8
|
-
self.new(exception, env).run
|
8
|
+
self.new(exception, clean_env(env)).run
|
9
9
|
end
|
10
10
|
|
11
11
|
# Uses the Rackless IssueRenderer for a rackless environment
|
data/lib/party_foul/version.rb
CHANGED
data/test/generator_test.rb
CHANGED
@@ -8,17 +8,14 @@ class PartyFoul::GeneratorTest < Rails::Generators::TestCase
|
|
8
8
|
test 'it copies the initializer' do
|
9
9
|
owner = 'test_owner'
|
10
10
|
repo = 'test_repo'
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
github = mock('Github')
|
15
|
-
github.stubs(:oauth).returns(oauth)
|
16
|
-
Github.stubs(:new).with(:login => 'test_login', :password => 'test_password', :endpoint => 'http://api.example.com').returns(github)
|
11
|
+
octokit = mock('Octokit')
|
12
|
+
octokit.expects(:create_authorization).with(scopes: ['repo'], note: 'PartyFoul test_owner/test_repo', note_url: 'http://example.com/test_owner/test_repo').returns(Hashie::Mash.new(token: 'test_token'))
|
13
|
+
Octokit.stubs(:new).with(:login => 'test_login', :password => 'test_password', :api_endpoint => 'http://api.example.com').returns(octokit)
|
17
14
|
$stdin.stubs(:gets).returns('test_login').then.returns('test_password').then.returns(owner).then.returns(repo).then.returns('http://api.example.com').then.returns('http://example.com').then.returns('')
|
18
15
|
run_generator
|
19
16
|
|
20
17
|
assert_file 'config/initializers/party_foul.rb' do |initializer|
|
21
|
-
assert_match(/config\.
|
18
|
+
assert_match(/config\.api_endpoint\s+=\s'http:\/\/api\.example\.com'/, initializer)
|
22
19
|
assert_match(/config\.web_url\s+=\s'http:\/\/example\.com'/, initializer)
|
23
20
|
assert_match(/config\.owner\s+=\s'test_owner'/, initializer)
|
24
21
|
assert_match(/config\.repo\s+=\s'test_repo'/, initializer)
|
@@ -11,7 +11,7 @@ describe 'Party Foul Confg' do
|
|
11
11
|
config.blacklisted_exceptions = ['StandardError']
|
12
12
|
config.oauth_token = 'test_token'
|
13
13
|
config.web_url = 'http://example.com'
|
14
|
-
config.
|
14
|
+
config.api_endpoint = 'http://api.example.com'
|
15
15
|
config.owner = 'test_owner'
|
16
16
|
config.repo = 'test_repo'
|
17
17
|
config.branch = 'master'
|
@@ -19,11 +19,12 @@ describe 'Party Foul Confg' do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
PartyFoul.blacklisted_exceptions.must_equal ['StandardError']
|
22
|
-
PartyFoul.github.must_be_instance_of
|
22
|
+
PartyFoul.github.must_be_instance_of Octokit::Client
|
23
23
|
PartyFoul.github.oauth_token.must_equal 'test_token'
|
24
|
-
PartyFoul.github.
|
24
|
+
PartyFoul.github.api_endpoint.must_equal 'http://api.example.com'
|
25
25
|
PartyFoul.owner.must_equal 'test_owner'
|
26
26
|
PartyFoul.repo.must_equal 'test_repo'
|
27
|
+
PartyFoul.repo_path.must_equal 'test_owner/test_repo'
|
27
28
|
PartyFoul.repo_url.must_equal 'http://example.com/test_owner/test_repo'
|
28
29
|
PartyFoul.branch.must_equal 'master'
|
29
30
|
PartyFoul.comment_limit.must_equal 10
|
@@ -9,13 +9,6 @@ describe 'Party Foul Exception Handler' do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
PartyFoul.stubs(:branch).returns('deploy')
|
12
|
-
PartyFoul.github.stubs(:issues).returns(mock('Issues'))
|
13
|
-
PartyFoul.github.stubs(:search).returns(mock('Search'))
|
14
|
-
PartyFoul.github.git_data.references.stubs(:get)
|
15
|
-
PartyFoul.github.issues.stubs(:create)
|
16
|
-
PartyFoul.github.issues.stubs(:edit)
|
17
|
-
PartyFoul.github.issues.stubs(:comments).returns(mock('Comments'))
|
18
|
-
PartyFoul.github.issues.comments.stubs(:create)
|
19
12
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:title).returns('Test Title')
|
20
13
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:fingerprint).returns('test_fingerprint')
|
21
14
|
end
|
@@ -24,11 +17,11 @@ describe 'Party Foul Exception Handler' do
|
|
24
17
|
it 'will open a new error on GitHub' do
|
25
18
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:body).returns('Test Body')
|
26
19
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:comment).returns('Test Comment')
|
27
|
-
PartyFoul.github.
|
28
|
-
PartyFoul.github.
|
29
|
-
PartyFoul.github.
|
30
|
-
PartyFoul.github.
|
31
|
-
PartyFoul.github.
|
20
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([])
|
21
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'closed').returns([])
|
22
|
+
PartyFoul.github.expects(:create_issue).with('test_owner/test_repo', 'Test Title', 'Test Body', :labels => ['bug']).returns(Hashie::Mash.new('number' => 1))
|
23
|
+
PartyFoul.github.expects(:references).with('test_owner/test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
24
|
+
PartyFoul.github.expects(:add_comment).with('test_owner/test_repo', 1, 'Test Comment')
|
32
25
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
33
26
|
end
|
34
27
|
|
@@ -44,11 +37,11 @@ describe 'Party Foul Exception Handler' do
|
|
44
37
|
it 'will open a new error on GitHub with the additional labels' do
|
45
38
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:body).returns('Test Body')
|
46
39
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:comment).returns('Test Comment')
|
47
|
-
PartyFoul.github.
|
48
|
-
PartyFoul.github.
|
49
|
-
PartyFoul.github.
|
50
|
-
PartyFoul.github.
|
51
|
-
PartyFoul.github.
|
40
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([])
|
41
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'closed').returns([])
|
42
|
+
PartyFoul.github.expects(:create_issue).with('test_owner/test_repo', 'Test Title', 'Test Body', :labels => ['bug', 'custom', 'label']).returns(Hashie::Mash.new('number' => 1))
|
43
|
+
PartyFoul.github.expects(:references).with('test_owner/test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
44
|
+
PartyFoul.github.expects(:add_comment).with('test_owner/test_repo', 1, 'Test Comment')
|
52
45
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
53
46
|
end
|
54
47
|
end
|
@@ -66,27 +59,27 @@ describe 'Party Foul Exception Handler' do
|
|
66
59
|
end
|
67
60
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:body).returns('Test Body')
|
68
61
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:comment).returns('Test Comment')
|
69
|
-
PartyFoul.github.
|
70
|
-
PartyFoul.github.
|
71
|
-
PartyFoul.github.
|
72
|
-
PartyFoul.github.
|
62
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([])
|
63
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'closed').returns([])
|
64
|
+
PartyFoul.github.expects(:references).with('test_owner/test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
65
|
+
PartyFoul.github.expects(:add_comment).with('test_owner/test_repo', 1, 'Test Comment')
|
73
66
|
end
|
74
67
|
after do
|
75
68
|
clean_up_party
|
76
69
|
end
|
77
70
|
|
78
71
|
it 'will open a new error on GitHub with the default labels if no additional labels are returned from the proc' do
|
79
|
-
PartyFoul.github.
|
72
|
+
PartyFoul.github.expects(:create_issue).with('test_owner/test_repo', 'Test Title', 'Test Body', :labels => ['bug']).returns(Hashie::Mash.new('number' => 1))
|
80
73
|
PartyFoul::ExceptionHandler.new(stub(:message => ''), {}).run
|
81
74
|
end
|
82
75
|
|
83
76
|
it 'will open a new error on GitHub with the additional labels based on the exception message' do
|
84
|
-
PartyFoul.github.
|
77
|
+
PartyFoul.github.expects(:create_issue).with('test_owner/test_repo', 'Test Title', 'Test Body', :labels => ['bug', 'database_error']).returns(Hashie::Mash.new('number' => 1))
|
85
78
|
PartyFoul::ExceptionHandler.new(stub(:message => 'Database'), {}).run
|
86
79
|
end
|
87
80
|
|
88
81
|
it 'will open a new error on GitHub with the additional labels based on the env' do
|
89
|
-
PartyFoul.github.
|
82
|
+
PartyFoul.github.expects(:create_issue).with('test_owner/test_repo', 'Test Title', 'Test Body', :labels => ['bug', 'beta']).returns(Hashie::Mash.new('number' => 1))
|
90
83
|
PartyFoul::ExceptionHandler.new(stub(:message => ''), {:http_host => 'beta.example.com'}).run
|
91
84
|
end
|
92
85
|
end
|
@@ -100,13 +93,13 @@ describe 'Party Foul Exception Handler' do
|
|
100
93
|
|
101
94
|
context 'and open' do
|
102
95
|
before do
|
103
|
-
PartyFoul.github.
|
104
|
-
PartyFoul.github.
|
105
|
-
PartyFoul.github.
|
106
|
-
PartyFoul.github.git_data.references.expects(:get).with('test_owner', 'test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
96
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([Hashie::Mash.new(title: 'Test Title', body: 'Test Body', state: 'open', number: 1)])
|
97
|
+
PartyFoul.github.expects(:update_issue).with('test_owner/test_repo', 1, 'Test Title', 'New Body', state: 'open')
|
98
|
+
PartyFoul.github.expects(:references).with('test_owner/test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
107
99
|
end
|
108
100
|
|
109
101
|
it 'will update the issue' do
|
102
|
+
PartyFoul.github.expects(:add_comment).with('test_owner/test_repo', 1, 'Test Comment')
|
110
103
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
111
104
|
end
|
112
105
|
|
@@ -115,19 +108,18 @@ describe 'Party Foul Exception Handler' do
|
|
115
108
|
config.comment_limit = 10
|
116
109
|
end
|
117
110
|
PartyFoul::ExceptionHandler.any_instance.expects(:occurrence_count).returns(10)
|
118
|
-
PartyFoul.github.
|
119
|
-
PartyFoul.github.issues.comments.expects(:create).never
|
111
|
+
PartyFoul.github.expects(:add_comment).never
|
120
112
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
121
113
|
end
|
122
114
|
end
|
123
115
|
|
124
116
|
context 'and closed' do
|
125
117
|
it 'will update the count on the body and re-open the issue' do
|
126
|
-
PartyFoul.github.
|
127
|
-
PartyFoul.github.
|
128
|
-
PartyFoul.github.
|
129
|
-
PartyFoul.github.
|
130
|
-
PartyFoul.github.
|
118
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([])
|
119
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'closed').returns([Hashie::Mash.new(title: 'Test Title', body: 'Test Body', state: 'closed', number: 1, labels: ['staging'])])
|
120
|
+
PartyFoul.github.expects(:update_issue).with('test_owner/test_repo', 1, 'Test Title', 'New Body', state: 'open', labels: ['bug', 'regression', 'staging'])
|
121
|
+
PartyFoul.github.expects(:add_comment).with('test_owner/test_repo', 1, 'Test Comment')
|
122
|
+
PartyFoul.github.expects(:references).with('test_owner/test_repo', 'heads/deploy').returns(Hashie::Mash.new(object: Hashie::Mash.new(sha: 'abcdefg1234567890')))
|
131
123
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
132
124
|
end
|
133
125
|
end
|
@@ -136,12 +128,12 @@ describe 'Party Foul Exception Handler' do
|
|
136
128
|
context 'when issue is marked as "wontfix"' do
|
137
129
|
it 'does nothing' do
|
138
130
|
PartyFoul::IssueRenderers::Rails.any_instance.stubs(:body).returns('Test Body')
|
139
|
-
PartyFoul.github.
|
140
|
-
PartyFoul.github.
|
141
|
-
PartyFoul.github.
|
142
|
-
PartyFoul.github.
|
143
|
-
PartyFoul.github.
|
144
|
-
PartyFoul.github.
|
131
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'open').returns([])
|
132
|
+
PartyFoul.github.expects(:search_issues).with('test_owner/test_repo', 'test_fingerprint', 'closed').returns([Hashie::Mash.new(title: 'Test Title', body: 'Test Body', state: 'closed', number: 1, labels: ['wontfix'])])
|
133
|
+
PartyFoul.github.expects(:create_issue).never
|
134
|
+
PartyFoul.github.expects(:update_issue).never
|
135
|
+
PartyFoul.github.expects(:add_comment).never
|
136
|
+
PartyFoul.github.expects(:references).never
|
145
137
|
PartyFoul::ExceptionHandler.new(nil, {}).run
|
146
138
|
end
|
147
139
|
end
|
@@ -112,4 +112,33 @@ Fingerprint: `abcdefg1234567890`
|
|
112
112
|
rendered_issue.title.must_equal 'Error for #<ClassName:0xXXXXXX>'
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
describe '#stack_trace' do
|
117
|
+
it 'returns the stack trace' do
|
118
|
+
exception = mock do
|
119
|
+
stubs backtrace: ['/path/to/gems/gem-name/lib/some/file.rb:123 in `method`']
|
120
|
+
end
|
121
|
+
rendered_issue = PartyFoul::IssueRenderers::Base.new(exception, nil)
|
122
|
+
rendered_issue.stack_trace.must_equal exception.backtrace.first
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'formats the stack trace with shortened bundle paths' do
|
126
|
+
exception = mock do
|
127
|
+
stubs backtrace: ["#{Bundler.bundle_path}/some_gem/lib/some/file.rb:123 in `method`"]
|
128
|
+
end
|
129
|
+
rendered_issue = PartyFoul::IssueRenderers::Base.new(exception, nil)
|
130
|
+
rendered_issue.stack_trace.must_equal '[bundle].../some_gem/lib/some/file.rb:123 in `method`'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'formats the stack trace with link to shortened application path' do
|
134
|
+
exception = mock do
|
135
|
+
stubs backtrace: ['/path/to/app/lib/some/file.rb:123 in `method`']
|
136
|
+
end
|
137
|
+
rendered_issue = PartyFoul::IssueRenderers::Base.new(exception, nil)
|
138
|
+
rendered_issue.stubs app_root: '/path/to/app'
|
139
|
+
rendered_issue.stack_trace.must_match "<a href='https://github.com/"
|
140
|
+
rendered_issue.stack_trace.must_match ">[app].../lib/some/file.rb:123 in `method`</a>"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
115
144
|
end
|
@@ -13,14 +13,27 @@ describe 'Rails Issue Renderer' do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#session' do
|
16
|
+
let(:params) { {'action_dispatch.parameter_filter' => ['password'], 'rack.session' => { 'status' => 'ok', 'password' => 'test' }, 'QUERY_STRING' => { 'status' => 'fail' } } }
|
17
|
+
|
16
18
|
before do
|
17
|
-
@rendered_issue = PartyFoul::IssueRenderers::Rails.new(nil,
|
19
|
+
@rendered_issue = PartyFoul::IssueRenderers::Rails.new(nil, params)
|
18
20
|
end
|
19
21
|
|
20
22
|
it 'returns ok' do
|
21
23
|
@rendered_issue.session['status'].must_equal 'ok'
|
22
24
|
@rendered_issue.session['password'].must_equal '[FILTERED]'
|
23
25
|
end
|
26
|
+
|
27
|
+
context "without session" do
|
28
|
+
|
29
|
+
let(:params) { {'action_dispatch.parameter_filter' => ['password'], 'QUERY_STRING' => { 'status' => 'fail' } } }
|
30
|
+
|
31
|
+
it 'returns empty hash' do
|
32
|
+
@rendered_issue.session.must_be_empty
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
24
37
|
end
|
25
38
|
|
26
39
|
describe '#raw_title' do
|
data/test/test_helper.rb
CHANGED
@@ -6,12 +6,13 @@ else
|
|
6
6
|
require 'minitest/autorun'
|
7
7
|
end
|
8
8
|
begin
|
9
|
-
require '
|
9
|
+
require 'byebug'
|
10
10
|
rescue LoadError
|
11
11
|
end
|
12
12
|
require 'rack/test'
|
13
13
|
require 'mocha/setup'
|
14
14
|
require 'party_foul'
|
15
|
+
require 'hashie/mash'
|
15
16
|
|
16
17
|
class MiniTest::Spec
|
17
18
|
class << self
|
@@ -24,7 +25,7 @@ module MiniTest::Expectations
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def clean_up_party
|
27
|
-
%w{github oauth_token
|
28
|
+
%w{github oauth_token api_endpoint owner repo blacklisted_exceptions processor web_url branch additional_labels comment_limit}.each do |attr|
|
28
29
|
PartyFoul.send("#{attr}=", nil)
|
29
30
|
end
|
30
31
|
end
|
@@ -6,9 +6,9 @@ PartyFoul.configure do |config|
|
|
6
6
|
# The OAuth token for the account that is opening the issues on GitHub
|
7
7
|
config.oauth_token = 'test_token'
|
8
8
|
|
9
|
-
# The API
|
9
|
+
# The API api_endpoint for GitHub. Unless you are hosting a private
|
10
10
|
# instance of Enterprise GitHub you do not need to include this
|
11
|
-
config.
|
11
|
+
config.api_endpoint = 'http://api.example.com'
|
12
12
|
|
13
13
|
# The Web URL for GitHub. Unless you are hosting a private
|
14
14
|
# instance of Enterprise GitHub you do not need to include this
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: party_foul
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Cardarella
|
@@ -9,78 +9,78 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: octokit
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - '>='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '0
|
20
|
+
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '0
|
27
|
+
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: actionpack
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 4.0
|
34
|
+
version: '4.0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 4.0
|
41
|
+
version: '4.0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: activesupport
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - ~>
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 4.0
|
48
|
+
version: '4.0'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 4.0
|
55
|
+
version: '4.0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: railties
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 4.0
|
62
|
+
version: '4.0'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 4.0
|
69
|
+
version: '4.0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: minitest
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
76
|
+
version: '4.7'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ~>
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
83
|
+
version: '4.7'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: webmock
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +137,7 @@ dependencies:
|
|
137
137
|
- - '>='
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
|
-
description: Auto-submit Rails exceptions as new
|
140
|
+
description: Auto-submit Rails exceptions as new issues on GitHub
|
141
141
|
email:
|
142
142
|
- bcardarella@gmail.com
|
143
143
|
- rubygems@danmcclain.net
|
@@ -187,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
187
187
|
requirements:
|
188
188
|
- - '>='
|
189
189
|
- !ruby/object:Gem::Version
|
190
|
-
version:
|
190
|
+
version: 1.9.3
|
191
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
193
|
- - '>='
|
@@ -195,10 +195,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
195
|
version: '0'
|
196
196
|
requirements: []
|
197
197
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.0.
|
198
|
+
rubygems_version: 2.0.3
|
199
199
|
signing_key:
|
200
200
|
specification_version: 4
|
201
|
-
summary: Auto-submit Rails exceptions as new
|
201
|
+
summary: Auto-submit Rails exceptions as new issues on GitHub
|
202
202
|
test_files:
|
203
203
|
- test/generator_test.rb
|
204
204
|
- test/party_foul/configure_test.rb
|