Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Specs passing with newly modularized structure and config system
- Loading branch information
Showing
15 changed files
with
454 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
require 'builder' | ||
require 'net/http' | ||
require 'rack' | ||
|
||
lib = File.dirname(__FILE__) | ||
require "#{lib}/lilypad/config" | ||
require "#{lib}/lilypad/config/request" | ||
require "#{lib}/lilypad/log" | ||
require "#{lib}/lilypad/hoptoad/deploy" | ||
require "#{lib}/lilypad/hoptoad/notify" | ||
require "#{lib}/lilypad/hoptoad/xml" | ||
require "#{lib}/rack/lilypad" | ||
|
||
class Lilypad | ||
class <<self | ||
|
||
def active? | ||
Config.api_key | ||
end | ||
|
||
def config(api_key=nil, &block) | ||
if api_key | ||
Config.api_key api_key | ||
end | ||
if block_given? | ||
Config.class_eval &block | ||
end | ||
end | ||
|
||
def deploy(options) | ||
if active? && production? | ||
Hoptoad::Deploy.new options | ||
end | ||
end | ||
|
||
def notify(exception, env=nil) | ||
if active? && production? | ||
Hoptoad::Notify.new env, exception | ||
end | ||
end | ||
|
||
def production? | ||
Config.environments.include? ENV['RACK_ENV'] | ||
end | ||
end | ||
end | ||
|
||
def Lilypad(api_key=nil, &block) | ||
Lilypad.config api_key, &block | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class Lilypad | ||
module Rails | ||
|
||
def self.included(base) | ||
ENV['RACK_ENV'] = ENV['RAILS_ENV'] | ||
base.send(:include, LilypadMethods) if Lilypad.production? | ||
end | ||
|
||
module LilypadMethods | ||
|
||
private | ||
|
||
def rescue_action_without_handler(exception) | ||
super | ||
Config::Request.action params[:action] | ||
Config::Request.component params[:controller] | ||
raise exception | ||
end | ||
end | ||
end | ||
end | ||
|
||
ActionController::Base.send(:include, Lilypad::Rails) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class Lilypad | ||
module Sinatra | ||
|
||
def self.included(base) | ||
base.set(:raise_errors, true) if Lilypad.production? | ||
end | ||
end | ||
end | ||
|
||
Sinatra::Base.send(:include, Lilypad::Sinatra) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
class Lilypad | ||
class Config | ||
class <<self | ||
|
||
def api_key(api_key=nil, &block) | ||
@api_key = api_key unless api_key.nil? | ||
@api_key_block = block if block_given? | ||
@api_key || @api_key_block | ||
end | ||
|
||
def deploy_url(url=nil) | ||
@deploy_url = url unless url.nil? | ||
@deploy_url || "http://hoptoadapp.com/deploys.txt" | ||
end | ||
|
||
def environments(environments=nil) | ||
@environments = environments unless environments.nil? | ||
@environments || %w(production staging) | ||
end | ||
|
||
def filters(filters=nil) | ||
@filters = filters unless filters.nil? | ||
@filters | ||
end | ||
|
||
def log(log=nil) | ||
@log = log unless log.nil? | ||
@log | ||
end | ||
|
||
def notify_url(url=nil) | ||
@notify_url = url unless url.nil? | ||
@url || "http://hoptoadapp.com:80/notify_url/v2/notices" | ||
end | ||
|
||
def rails | ||
require "#{File.dirname(__FILE__)}/adapters/rails" | ||
end | ||
|
||
def reset! | ||
self.instance_variables.each do |name| | ||
eval "#{name} = nil" | ||
end | ||
end | ||
|
||
def sinatra | ||
require "#{File.dirname(__FILE__)}/adapters/sinatra" | ||
end | ||
|
||
end | ||
|
||
module Methods | ||
|
||
def api_key(env=nil, exception=nil) | ||
if Config.api_key.respond_to?(:call) | ||
Config.api_key.call env, exception | ||
else | ||
Config.api_key | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class Lilypad | ||
class Config | ||
class Request | ||
class <<self | ||
|
||
def action(action=nil) | ||
@action = action unless action.nil? | ||
@action | ||
end | ||
|
||
def component(component=nil) | ||
@component = component unless component.nil? | ||
@component | ||
end | ||
|
||
def reset! | ||
self.instance_variables.each do |name| | ||
eval "#{name} = nil" | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
class Lilypad | ||
class Hoptoad | ||
class Deploy | ||
|
||
include Config::Methods | ||
include Log::Methods | ||
|
||
def initialize(options) | ||
@options = options | ||
|
||
begin | ||
post | ||
rescue Exception => e | ||
end | ||
|
||
log :debug, @response | ||
success? | ||
end | ||
|
||
private | ||
|
||
def params | ||
{ | ||
'api_key' => api_key, | ||
'deploy[local_username]' => @options[:username], | ||
'deploy[rails_env]' => @options[:environment], | ||
'deploy[scm_revision]' => @options[:revision], | ||
'deploy[scm_repository]' => @options[:repository] | ||
} | ||
end | ||
|
||
def post | ||
url = URI.parse Config.deploy_url | ||
@response = Net::HTTP.post_form url, params | ||
end | ||
|
||
def success? | ||
@response.class.superclass == Net::HTTPSuccess | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
class Lilypad | ||
class Hoptoad | ||
class Notify | ||
|
||
include Log::Methods | ||
|
||
def initialize(env, exception) | ||
@exception = exception | ||
@env = env | ||
|
||
http_start do |http| | ||
begin | ||
xml = XML.build *parse | ||
http.post @uri.path, xml, headers | ||
rescue Exception => e | ||
end | ||
end | ||
|
||
if env && success? | ||
env['hoptoad.notified'] = true | ||
end | ||
|
||
Config::Request.reset! | ||
log :notify, @response | ||
success? | ||
end | ||
|
||
private | ||
|
||
def backtrace | ||
regex = %r{^([^:]+):(\d+)(?::in `([^']+)')?$} | ||
@exception.backtrace.map do |line| | ||
_, file, number, method = line.match(regex).to_a | ||
Backtrace.new file, number, method | ||
end | ||
end | ||
|
||
def filter(hash) | ||
return unless Config.filters | ||
hash.inject({}) do |acc, (key, val)| | ||
match = Config.filters.any? { |f| key.to_s =~ Regexp.new(f) } | ||
acc[key] = match ? "[FILTERED]" : val | ||
acc | ||
end | ||
end | ||
|
||
def headers | ||
{ | ||
'Content-type' => 'text/xml', | ||
'Accept' => 'text/xml, application/xml' | ||
} | ||
end | ||
|
||
def http_start(&block) | ||
@uri = URI.parse Config.notify_url | ||
Net::HTTP.start @uri.host, @uri.port do |http| | ||
http.read_timeout = 5 # seconds | ||
http.open_timeout = 2 # seconds | ||
@response = yield http | ||
end | ||
end | ||
|
||
def parse | ||
env = filter ENV.to_hash.merge(@env || {}) | ||
if @env | ||
request = Rack::Request.new @env | ||
request_path = request.script_name + request.path_info | ||
else | ||
request = nil | ||
request_path = 'Internal' | ||
end | ||
[ backtrace, env, @exception, request, request_path ] | ||
end | ||
|
||
def success? | ||
@response.class.superclass == Net::HTTPSuccess | ||
end | ||
|
||
class Backtrace < Struct.new(:file, :number, :method) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
class Lilypad | ||
class Hoptoad | ||
class XML | ||
class <<self | ||
|
||
include Config::Methods | ||
|
||
def build(backtrace, env, exception, request, request_path) | ||
@@last_request = nil | ||
xml = ::Builder::XmlMarkup.new | ||
xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8" | ||
xml.notice :version => '2.0.0' do |n| | ||
n.tag! 'api-key', api_key | ||
n.notifier do |n| | ||
n.name 'Lilypad' | ||
n.url 'http://github.com/winton/lilypad' | ||
n.version '0.2.4' | ||
end | ||
n.error do |e| | ||
e.tag! 'class', exception.class.name | ||
e.message exception.message | ||
e.backtrace do |b| | ||
backtrace.each do |line| | ||
b.line :method => line.method, :file => line.file, :number => line.number | ||
end | ||
end | ||
end | ||
n.request do |r| | ||
r.action Config::Request.action | ||
r.component Config::Request.component || request_path | ||
r.url request_path | ||
if request && request.params.any? | ||
r.params do |p| | ||
request.params.each do |key, value| | ||
p.var value.to_s, :key => key | ||
end | ||
end | ||
end | ||
if env.any? | ||
r.tag! 'cgi-data' do |c| | ||
env.each do |key, value| | ||
c.var value.to_s, :key => key | ||
end | ||
end | ||
end | ||
end | ||
n.tag! 'server-environment' do |s| | ||
s.tag! 'project-root', Dir.pwd | ||
s.tag! 'environment-name', ENV['RACK_ENV'] || 'development' | ||
end | ||
end | ||
@@last_request = xml.target! | ||
end | ||
|
||
def last_request | ||
@@last_request | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.