hatless-hoptoad_notifier 2.2.6
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.
- data/CHANGELOG +149 -0
- data/INSTALL +25 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +382 -0
- data/Rakefile +217 -0
- data/SUPPORTED_RAILS_VERSIONS +9 -0
- data/TESTING.rdoc +8 -0
- data/generators/hoptoad/hoptoad_generator.rb +54 -0
- data/generators/hoptoad/lib/insert_commands.rb +34 -0
- data/generators/hoptoad/lib/rake_commands.rb +24 -0
- data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
- data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +25 -0
- data/generators/hoptoad/templates/initializer.rb +6 -0
- data/lib/hoptoad_notifier/backtrace.rb +99 -0
- data/lib/hoptoad_notifier/capistrano.rb +20 -0
- data/lib/hoptoad_notifier/configuration.rb +232 -0
- data/lib/hoptoad_notifier/notice.rb +318 -0
- data/lib/hoptoad_notifier/rack.rb +40 -0
- data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
- data/lib/hoptoad_notifier/rails/controller_methods.rb +58 -0
- data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
- data/lib/hoptoad_notifier/rails.rb +37 -0
- data/lib/hoptoad_notifier/rails3_tasks.rb +90 -0
- data/lib/hoptoad_notifier/railtie.rb +23 -0
- data/lib/hoptoad_notifier/sender.rb +63 -0
- data/lib/hoptoad_notifier/tasks.rb +97 -0
- data/lib/hoptoad_notifier/version.rb +3 -0
- data/lib/hoptoad_notifier.rb +148 -0
- data/lib/hoptoad_tasks.rb +40 -0
- data/lib/rails/generators/hoptoad/hoptoad_generator.rb +64 -0
- data/lib/templates/rescue.erb +91 -0
- data/rails/init.rb +1 -0
- data/script/integration_test.rb +38 -0
- data/test/backtrace_test.rb +118 -0
- data/test/catcher_test.rb +324 -0
- data/test/configuration_test.rb +208 -0
- data/test/helper.rb +239 -0
- data/test/hoptoad_tasks_test.rb +138 -0
- data/test/logger_test.rb +85 -0
- data/test/notice_test.rb +443 -0
- data/test/notifier_test.rb +222 -0
- data/test/rack_test.rb +58 -0
- data/test/rails_initializer_test.rb +36 -0
- data/test/sender_test.rb +123 -0
- metadata +204 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
require 'rake/gempackagetask'
|
|
5
|
+
require 'cucumber/rake/task'
|
|
6
|
+
|
|
7
|
+
desc 'Default: run unit tests.'
|
|
8
|
+
task :default => [:test, :cucumber]
|
|
9
|
+
|
|
10
|
+
desc 'Test the hoptoad_notifier gem.'
|
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
|
12
|
+
t.libs << 'lib'
|
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
|
14
|
+
t.verbose = true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'Run ginger tests'
|
|
18
|
+
task :ginger do
|
|
19
|
+
$LOAD_PATH << File.join(*%w[vendor ginger lib])
|
|
20
|
+
ARGV.clear
|
|
21
|
+
ARGV << 'test'
|
|
22
|
+
load File.join(*%w[vendor ginger bin ginger])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
namespace :changeling do
|
|
26
|
+
desc "Bumps the version by a minor or patch version, depending on what was passed in."
|
|
27
|
+
task :bump, :part do |t, args|
|
|
28
|
+
# Thanks, Jeweler!
|
|
29
|
+
if HoptoadNotifier::VERSION =~ /^(\d+)\.(\d+)\.(\d+)(?:\.(.*?))?$/
|
|
30
|
+
major = $1.to_i
|
|
31
|
+
minor = $2.to_i
|
|
32
|
+
patch = $3.to_i
|
|
33
|
+
build = $4
|
|
34
|
+
else
|
|
35
|
+
abort
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
case args[:part]
|
|
39
|
+
when /minor/
|
|
40
|
+
minor += 1
|
|
41
|
+
patch = 0
|
|
42
|
+
when /patch/
|
|
43
|
+
patch += 1
|
|
44
|
+
else
|
|
45
|
+
abort
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
version = [major, minor, patch, build].compact.join('.')
|
|
49
|
+
|
|
50
|
+
File.open(File.join("lib", "hoptoad_notifier", "version.rb"), "w") do |f|
|
|
51
|
+
f.write <<EOF
|
|
52
|
+
module HoptoadNotifier
|
|
53
|
+
VERSION = "#{version}".freeze
|
|
54
|
+
end
|
|
55
|
+
EOF
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc "Writes out the new CHANGELOG and prepares the release"
|
|
60
|
+
task :change do
|
|
61
|
+
load 'lib/hoptoad_notifier/version.rb'
|
|
62
|
+
file = "CHANGELOG"
|
|
63
|
+
old = File.read(file)
|
|
64
|
+
version = HoptoadNotifier::VERSION
|
|
65
|
+
message = "Bumping to version #{version}"
|
|
66
|
+
|
|
67
|
+
File.open(file, "w") do |f|
|
|
68
|
+
f.write <<EOF
|
|
69
|
+
Version #{version} - #{Date.today}
|
|
70
|
+
===============================================================================
|
|
71
|
+
|
|
72
|
+
#{`git log $(git tag | tail -1)..HEAD | git shortlog`}
|
|
73
|
+
#{old}
|
|
74
|
+
EOF
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
exec ["#{ENV["EDITOR"]} #{file}",
|
|
78
|
+
"git commit -aqm '#{message}'",
|
|
79
|
+
"git tag -a -m '#{message}' v#{version}",
|
|
80
|
+
"echo '\n\n\033[32mMarked v#{version} /' `git show-ref -s refs/heads/master` 'for release. Run: rake changeling:push\033[0m\n\n'"].join(' && ')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
desc "Bump by a minor version (1.2.3 => 1.3.0)"
|
|
84
|
+
task :minor do |t|
|
|
85
|
+
Rake::Task['changeling:bump'].invoke(t.name)
|
|
86
|
+
Rake::Task['changeling:change'].invoke
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
desc "Bump by a patch version, (1.2.3 => 1.2.4)"
|
|
90
|
+
task :patch do |t|
|
|
91
|
+
Rake::Task['changeling:bump'].invoke(t.name)
|
|
92
|
+
Rake::Task['changeling:change'].invoke
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
desc "Push the latest version and tags"
|
|
96
|
+
task :push do |t|
|
|
97
|
+
system("git push origin master")
|
|
98
|
+
system("git push origin $(git tag | tail -1)")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
begin
|
|
103
|
+
require 'yard'
|
|
104
|
+
YARD::Rake::YardocTask.new do |t|
|
|
105
|
+
t.files = ['lib/**/*.rb', 'TESTING.rdoc']
|
|
106
|
+
end
|
|
107
|
+
rescue LoadError
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
GEM_ROOT = File.dirname(__FILE__).freeze
|
|
111
|
+
VERSION_FILE = File.join(GEM_ROOT, 'lib', 'hoptoad_notifier', 'version')
|
|
112
|
+
|
|
113
|
+
require VERSION_FILE
|
|
114
|
+
|
|
115
|
+
gemspec = Gem::Specification.new do |s|
|
|
116
|
+
s.name = %q{hoptoad_notifier}
|
|
117
|
+
s.version = HoptoadNotifier::VERSION
|
|
118
|
+
s.summary = %q{Send your application errors to our hosted service and reclaim your inbox.}
|
|
119
|
+
|
|
120
|
+
s.files = FileList['[A-Z]*', 'generators/**/*.*', 'lib/**/*.rb',
|
|
121
|
+
'test/**/*.rb', 'rails/**/*.rb', 'script/*',
|
|
122
|
+
'lib/templates/*.erb']
|
|
123
|
+
s.require_path = 'lib'
|
|
124
|
+
s.test_files = Dir[*['test/**/*_test.rb']]
|
|
125
|
+
|
|
126
|
+
s.has_rdoc = true
|
|
127
|
+
s.extra_rdoc_files = ["README.rdoc"]
|
|
128
|
+
s.rdoc_options = ['--line-numbers', "--main", "README.rdoc"]
|
|
129
|
+
|
|
130
|
+
s.add_runtime_dependency("activesupport")
|
|
131
|
+
s.add_development_dependency("activerecord")
|
|
132
|
+
s.add_development_dependency("actionpack")
|
|
133
|
+
s.add_development_dependency("jferris-mocha")
|
|
134
|
+
s.add_development_dependency("nokogiri")
|
|
135
|
+
s.add_development_dependency("shoulda")
|
|
136
|
+
|
|
137
|
+
s.authors = ["thoughtbot, inc"]
|
|
138
|
+
s.email = %q{support@hoptoadapp.com}
|
|
139
|
+
s.homepage = "http://www.hoptoadapp.com"
|
|
140
|
+
|
|
141
|
+
s.platform = Gem::Platform::RUBY
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
Rake::GemPackageTask.new gemspec do |pkg|
|
|
145
|
+
pkg.need_tar = true
|
|
146
|
+
pkg.need_zip = true
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
desc "Clean files generated by rake tasks"
|
|
150
|
+
task :clobber => [:clobber_rdoc, :clobber_package]
|
|
151
|
+
|
|
152
|
+
desc "Generate a gemspec file"
|
|
153
|
+
task :gemspec do
|
|
154
|
+
File.open("#{gemspec.name}.gemspec", 'w') do |f|
|
|
155
|
+
f.write gemspec.to_ruby
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
LOCAL_GEM_ROOT = File.join(GEM_ROOT, 'tmp', 'local_gems').freeze
|
|
160
|
+
RAILS_VERSIONS = IO.read('SUPPORTED_RAILS_VERSIONS').strip.split("\n")
|
|
161
|
+
LOCAL_GEMS = [['sham_rack', nil], ['capistrano', nil], ['sqlite3-ruby', nil], ['sinatra', nil]] +
|
|
162
|
+
RAILS_VERSIONS.collect { |version| ['rails', version] }
|
|
163
|
+
|
|
164
|
+
task :vendor_test_gems do
|
|
165
|
+
old_gem_path = ENV['GEM_PATH']
|
|
166
|
+
old_gem_home = ENV['GEM_HOME']
|
|
167
|
+
ENV['GEM_PATH'] = LOCAL_GEM_ROOT
|
|
168
|
+
ENV['GEM_HOME'] = LOCAL_GEM_ROOT
|
|
169
|
+
LOCAL_GEMS.each do |gem_name, version|
|
|
170
|
+
gem_file_pattern = [gem_name, version || '*'].compact.join('-')
|
|
171
|
+
version_option = version ? "-v #{version}" : ''
|
|
172
|
+
pattern = File.join(LOCAL_GEM_ROOT, 'gems', "#{gem_file_pattern}")
|
|
173
|
+
existing = Dir.glob(pattern).first
|
|
174
|
+
unless existing
|
|
175
|
+
command = "gem install -i #{LOCAL_GEM_ROOT} --no-ri --no-rdoc --backtrace #{version_option} #{gem_name}"
|
|
176
|
+
puts "Vendoring #{gem_file_pattern}..."
|
|
177
|
+
unless system("#{command} 2>&1")
|
|
178
|
+
puts "Command failed: #{command}"
|
|
179
|
+
exit(1)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
ENV['GEM_PATH'] = old_gem_path
|
|
184
|
+
ENV['GEM_HOME'] = old_gem_home
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
|
188
|
+
t.fork = true
|
|
189
|
+
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
task :cucumber => [:gemspec, :vendor_test_gems]
|
|
193
|
+
|
|
194
|
+
def define_rails_cucumber_tasks(additional_cucumber_args = '')
|
|
195
|
+
namespace :rails do
|
|
196
|
+
RAILS_VERSIONS.each do |version|
|
|
197
|
+
desc "Test integration of the gem with Rails #{version}"
|
|
198
|
+
task version => [:gemspec, :vendor_test_gems] do
|
|
199
|
+
puts "Testing Rails #{version}"
|
|
200
|
+
ENV['RAILS_VERSION'] = version
|
|
201
|
+
system("cucumber --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} #{additional_cucumber_args} features/rails.feature")
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
desc "Test integration of the gem with all Rails versions"
|
|
206
|
+
task :all => RAILS_VERSIONS
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
namespace :cucumber do
|
|
211
|
+
namespace :wip do
|
|
212
|
+
define_rails_cucumber_tasks('--tags @wip')
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
define_rails_cucumber_tasks
|
|
216
|
+
end
|
|
217
|
+
|
data/TESTING.rdoc
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
= For Maintainers:
|
|
2
|
+
|
|
3
|
+
When developing the Hoptoad Notifier, be sure to use the integration test
|
|
4
|
+
against an existing project on staging before pushing to master.
|
|
5
|
+
|
|
6
|
+
+./script/integration_test.rb <test project's api key> <staging server hostname>+
|
|
7
|
+
|
|
8
|
+
+./script/integration_test.rb <test project's api key> <staging server hostname> secure+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
|
|
3
|
+
|
|
4
|
+
class HoptoadGenerator < Rails::Generator::Base
|
|
5
|
+
def add_options!(opt)
|
|
6
|
+
opt.on('-k', '--api-key=key', String, "Your Hoptoad API key") {|v| options[:api_key] = v}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def manifest
|
|
10
|
+
if !api_key_configured? && !options[:api_key]
|
|
11
|
+
puts "Must pass --api-key or create config/initializers/hoptoad.rb"
|
|
12
|
+
exit
|
|
13
|
+
end
|
|
14
|
+
if plugin_is_present?
|
|
15
|
+
puts "You must first remove the hoptoad_notifier plugin. Please run: script/plugin remove hoptoad_notifier"
|
|
16
|
+
exit
|
|
17
|
+
end
|
|
18
|
+
record do |m|
|
|
19
|
+
m.directory 'lib/tasks'
|
|
20
|
+
m.file 'hoptoad_notifier_tasks.rake', 'lib/tasks/hoptoad_notifier_tasks.rake'
|
|
21
|
+
if ['config/deploy.rb', 'Capfile'].all? { |file| File.exists?(file) }
|
|
22
|
+
m.append_to 'config/deploy.rb', capistrano_hook
|
|
23
|
+
end
|
|
24
|
+
if options[:api_key]
|
|
25
|
+
if use_initializer?
|
|
26
|
+
m.template 'initializer.rb', 'config/initializers/hoptoad.rb',
|
|
27
|
+
:assigns => {:api_key => options[:api_key]}
|
|
28
|
+
else
|
|
29
|
+
m.template 'initializer.rb', 'config/hoptoad.rb',
|
|
30
|
+
:assigns => {:api_key => options[:api_key]}
|
|
31
|
+
m.append_to 'config/environment.rb', "require 'config/hoptoad'"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
m.rake "hoptoad:test", :generate_only => true
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def use_initializer?
|
|
39
|
+
Rails::VERSION::MAJOR > 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def api_key_configured?
|
|
43
|
+
File.exists?('config/initializers/hoptoad.rb') ||
|
|
44
|
+
system("grep HoptoadNotifier config/environment.rb")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def capistrano_hook
|
|
48
|
+
IO.read(source_path('capistrano_hook.rb'))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def plugin_is_present?
|
|
52
|
+
File.exists?('vendor/plugins/hoptoad_notifier')
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
|
|
2
|
+
|
|
3
|
+
Rails::Generator::Commands::Base.class_eval do
|
|
4
|
+
def file_contains?(relative_destination, line)
|
|
5
|
+
File.read(destination_path(relative_destination)).include?(line)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Rails::Generator::Commands::Create.class_eval do
|
|
10
|
+
def append_to(file, line)
|
|
11
|
+
logger.insert "#{line} appended to #{file}"
|
|
12
|
+
unless options[:pretend] || file_contains?(file, line)
|
|
13
|
+
File.open(file, "a") do |file|
|
|
14
|
+
file.puts
|
|
15
|
+
file.puts line
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
|
22
|
+
def append_to(file, line)
|
|
23
|
+
logger.remove "#{line} removed from #{file}"
|
|
24
|
+
unless options[:pretend]
|
|
25
|
+
gsub_file file, "\n#{line}", ''
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Rails::Generator::Commands::List.class_eval do
|
|
31
|
+
def append_to(file, line)
|
|
32
|
+
logger.insert "#{line} appended to #{file}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Rails::Generator::Commands::Create.class_eval do
|
|
2
|
+
def rake(cmd, opts = {})
|
|
3
|
+
logger.rake "rake #{cmd}"
|
|
4
|
+
unless system("rake #{cmd}")
|
|
5
|
+
logger.rake "#{cmd} failed. Rolling back"
|
|
6
|
+
command(:destroy).invoke!
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
|
12
|
+
def rake(cmd, opts = {})
|
|
13
|
+
unless opts[:generate_only]
|
|
14
|
+
logger.rake "rake #{cmd}"
|
|
15
|
+
system "rake #{cmd}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
Rails::Generator::Commands::List.class_eval do
|
|
21
|
+
def rake(cmd, opts = {})
|
|
22
|
+
logger.rake "rake #{cmd}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Don't load anything when running the gems:* tasks.
|
|
2
|
+
# Otherwise, hoptoad_notifier will be considered a framework gem.
|
|
3
|
+
# https://thoughtbot.lighthouseapp.com/projects/14221/tickets/629
|
|
4
|
+
unless ARGV.any? {|a| a =~ /^gems/}
|
|
5
|
+
|
|
6
|
+
Dir[File.join(RAILS_ROOT, 'vendor', 'gems', 'hoptoad_notifier-*')].each do |vendored_notifier|
|
|
7
|
+
$: << File.join(vendored_notifier, 'lib')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
require 'hoptoad_notifier/tasks'
|
|
12
|
+
rescue LoadError => exception
|
|
13
|
+
namespace :hoptoad do
|
|
14
|
+
%w(deploy test log_stdout).each do |task_name|
|
|
15
|
+
desc "Missing dependency for hoptoad:#{task_name}"
|
|
16
|
+
task task_name do
|
|
17
|
+
$stderr.puts "Failed to run hoptoad:#{task_name} because of missing dependency."
|
|
18
|
+
$stderr.puts "You probably need to run `rake gems:install` to install the hoptoad_notifier gem"
|
|
19
|
+
abort exception.inspect
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module HoptoadNotifier
|
|
2
|
+
# Front end to parsing the backtrace for each notice
|
|
3
|
+
class Backtrace
|
|
4
|
+
|
|
5
|
+
# Handles backtrace parsing line by line
|
|
6
|
+
class Line
|
|
7
|
+
|
|
8
|
+
INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
|
|
9
|
+
|
|
10
|
+
# The file portion of the line (such as app/models/user.rb)
|
|
11
|
+
attr_reader :file
|
|
12
|
+
|
|
13
|
+
# The line number portion of the line
|
|
14
|
+
attr_reader :number
|
|
15
|
+
|
|
16
|
+
# The method of the line (such as index)
|
|
17
|
+
attr_reader :method
|
|
18
|
+
|
|
19
|
+
# Parses a single line of a given backtrace
|
|
20
|
+
# @param [String] unparsed_line The raw line from +caller+ or some backtrace
|
|
21
|
+
# @return [Line] The parsed backtrace line
|
|
22
|
+
def self.parse(unparsed_line)
|
|
23
|
+
_, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
|
|
24
|
+
new(file, number, method)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(file, number, method)
|
|
28
|
+
self.file = file
|
|
29
|
+
self.number = number
|
|
30
|
+
self.method = method
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Reconstructs the line in a readable fashion
|
|
34
|
+
def to_s
|
|
35
|
+
"#{file}:#{number}:in `#{method}'"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ==(other)
|
|
39
|
+
to_s == other.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def inspect
|
|
43
|
+
"<Line:#{to_s}>"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
attr_writer :file, :number, :method
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# holder for an Array of Backtrace::Line instances
|
|
52
|
+
attr_reader :lines
|
|
53
|
+
|
|
54
|
+
def self.parse(ruby_backtrace, opts = {})
|
|
55
|
+
ruby_lines = split_multiline_backtrace(ruby_backtrace)
|
|
56
|
+
|
|
57
|
+
filters = opts[:filters] || []
|
|
58
|
+
filtered_lines = ruby_lines.to_a.map do |line|
|
|
59
|
+
filters.inject(line) do |line, proc|
|
|
60
|
+
proc.call(line)
|
|
61
|
+
end
|
|
62
|
+
end.compact
|
|
63
|
+
|
|
64
|
+
lines = filtered_lines.collect do |unparsed_line|
|
|
65
|
+
Line.parse(unparsed_line)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
instance = new(lines)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def initialize(lines)
|
|
72
|
+
self.lines = lines
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def inspect
|
|
76
|
+
"<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def ==(other)
|
|
80
|
+
if other.respond_to?(:lines)
|
|
81
|
+
lines == other.lines
|
|
82
|
+
else
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
attr_writer :lines
|
|
90
|
+
|
|
91
|
+
def self.split_multiline_backtrace(backtrace)
|
|
92
|
+
if backtrace.to_a.size == 1
|
|
93
|
+
backtrace.to_a.first.split(/\n\s*/)
|
|
94
|
+
else
|
|
95
|
+
backtrace
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad.
|
|
2
|
+
|
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
|
4
|
+
after "deploy", "deploy:notify_hoptoad"
|
|
5
|
+
after "deploy:migrations", "deploy:notify_hoptoad"
|
|
6
|
+
|
|
7
|
+
namespace :deploy do
|
|
8
|
+
desc "Notify Hoptoad of the deployment"
|
|
9
|
+
task :notify_hoptoad, :except => { :no_release => true } do
|
|
10
|
+
rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production"))
|
|
11
|
+
local_user = ENV['USER'] || ENV['USERNAME']
|
|
12
|
+
executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake'
|
|
13
|
+
notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
|
|
14
|
+
notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
|
|
15
|
+
puts "Notifying Hoptoad of Deploy (#{notify_command})"
|
|
16
|
+
`#{notify_command}`
|
|
17
|
+
puts "Hoptoad Notification Complete."
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|