Skip to content

Commit

Permalink
Added Yard documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Burke Libbey committed Mar 3, 2012
1 parent 04b2403 commit 7aec248
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 27 deletions.
6 changes: 6 additions & 0 deletions .yardoc/checksums
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
lib/wolverine.rb 861eb12cbc0ed64bce8686185f29aa074b616278
lib/wolverine/script.rb 7c277f52a23920ee01692efb0cb5e22e722720c6
lib/wolverine/version.rb fae7ba042e53838d423f6fbaad49189a3010e141
lib/wolverine/lua_error.rb f720715715252e868527f445a1bc35e6ef0a76e1
lib/wolverine/configuration.rb fd8112dc1b5262530e9315926de886755a5e630f
lib/wolverine/path_component.rb 1faee0cb4ca7cdab968765a3be5cb9995200219b
Binary file added .yardoc/objects/root.dat
Binary file not shown.
Binary file added .yardoc/proxy_types
Binary file not shown.
9 changes: 9 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,13 @@ Rake::TestTask.new do |t|
t.pattern = "test/**/*_test.rb"
end

require 'yard'
require 'yard/rake/yardoc_task'
YARD::Rake::YardocTask.new do |yardoc|
yardoc.options = ['--verbose', '--markup', 'markdown']
# yardoc.files = [
# 'lib/**/*.rb', 'README.md', 'CHANGELOG.md', 'LICENSE'
# ]
end

task default: :test
28 changes: 24 additions & 4 deletions lib/wolverine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,46 @@
require 'wolverine/lua_error'

module Wolverine
# Returns the configuration object for reading and writing
# configuration values.
#
# @return [Wolverine::Configuration] the configuration object
def self.config
@config ||= Configuration.new
end

# Provides access to the redis connection currently in use by Wolverine.
#
# @return [Redis] the redis connection used by Wolverine
def self.redis
config.redis
end

# Resets all the scripts cached by Wolverine. Scripts are lazy-loaded and
# cached in-memory, so if a file changes on disk, it will be necessary to
# manually reset the cache using +reset!+.
#
# @return nil
def self.reset!
@root_directory = nil
end

def self.root_directory
@root_directory ||= PathComponent.new(config.script_path)
end

# Used to handle dynamic accesses to scripts. Successful lookups will be
# cached on the {PathComponent} object. See {PathComponent#method_missing}
# for more detail on how this works.
#
# @return [PathComponent, Object] a PathComponent if the method maps to a
# directory, or an execution result if the the method maps to a lua file.
def self.method_missing sym, *args
root_directory.send(sym, *args)
rescue PathComponent::MissingTemplate
super
end

private

def self.root_directory
@root_directory ||= PathComponent.new(config.script_path)
end

end
36 changes: 25 additions & 11 deletions lib/wolverine/lua_error.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
module Wolverine
# Reformats errors raised by redis representing failures while executing
# a lua script. The default errors have confusing messages and backtraces,
# and a type of +RuntimeError+. This class improves the message and
# modifies the backtrace to include the lua script itself in a reasonable
# way.
class LuaError < StandardError
PATTERN = /ERR Error (compiling|running) script \(.*?\): \[.*?\]:(\d+): (.*)/
WOLVERINE_LIB_PATH = File.expand_path('../../', __FILE__)

def self.intercepts?(e)
e.message =~ PATTERN
# Is this error one that should be reformatted?
#
# @param error [StandardError] the original error raised by redis
# @return [Boolean] is this an error that should be reformatted?
def self.intercepts? error
error.message =~ PATTERN
end

attr_reader :error, :file
def initialize(error, file)
# Initialize a new {LuaError} from an existing redis error, adjusting
# the message and backtrace in the process.
#
# @param error [StandardError] the original error raised by redis
# @param file [Pathname] full path to the lua file the error ocurred in
def initialize error, file
@error = error
@file = file

error.message =~ PATTERN
@error.message =~ PATTERN
stage, line_number, message = $1, $2, $3


super(message)
set_backtrace generate_backtrace(file, line_number)
super message
set_backtrace generate_backtrace file, line_number
end

private

def generate_backtrace(file, line_number)
pre_wolverine = backtrace_before_entering_wolverine(error.backtrace)
index_of_first_wolverine_line = (error.backtrace.size - pre_wolverine.size - 1)
pre_wolverine.unshift(error.backtrace[index_of_first_wolverine_line])
pre_wolverine = backtrace_before_entering_wolverine(@error.backtrace)
index_of_first_wolverine_line = (@error.backtrace.size - pre_wolverine.size - 1)
pre_wolverine.unshift(@error.backtrace[index_of_first_wolverine_line])
pre_wolverine.unshift("#{file}:#{line_number}")
pre_wolverine
end
Expand Down
19 changes: 18 additions & 1 deletion lib/wolverine/path_component.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
module Wolverine
class PathComponent
# A {PathComponent} represents either the +Wolverine.config.script_path+
# directory, or a subdirectory of it. Calling (nearly) any method on it will
# cause it to look in the filesystem at the location it refers to for a file
# or directory matching the method name. These results are cached.
#
# Calling a method that maps to a directory will return a new {PathComponent}
# with a +path+ referring to that directory.
#
# Calling a method that maps to a file (with +'.lua'+ automatically appended
# to the name) will load the file via {Script} and call it with the
# arugments passed, returning the result ({method_missing}).
class PathComponent
class MissingTemplate < StandardError ; end

# @param path [Pathname] full path to the current file or directory
def initialize path
@path = path
end

# @param sym [Symbol] the file or directory to look up and execute
# @param args [*Objects] arguments to pass to the {Script}, if +sym+ resolves to a lua file
# @return [PathComponent, Object] A new, nested {PathComponent} if +sym+ resolves to
# a directory, or an execution result if it resolves to a file.
# @raise [MissingTemplate] if +sym+ maps to neither a directory or a file
def method_missing sym, *args
create_method sym, *args
send sym, *args
Expand Down
26 changes: 21 additions & 5 deletions lib/wolverine/script.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
require 'digest/sha1'

module Wolverine

# {Script} represents a lua script in the filesystem. It loads the script
# from disk and handles talking to redis to execute it. Error handling
# is handled by {LuaError}.
class Script
attr_reader :content, :digest, :file

# Loads the script file from disk and calculates its +SHA1+ sum.
#
# @param file [Pathname] the full path to the indicated file
def initialize file
@file = file
@content = load_lua file
@digest = Digest::SHA1.hexdigest @content
end

# Passes the script and supplied arguments to redis for evaulation.
# It first attempts to use a script redis has already cached by using
# the +EVALSHA+ command, but falls back to providing the full script
# text via +EVAL+ if redis has not seen this script before. Future
# invocations will then use +EVALSHA+ without erroring.
#
# @param redis [Redis] the redis connection to run against
# @param args [*Objects] the arguments to the script
# @return [Object] the value passed back by redis after script execution
# @raise [LuaError] if the script failed to compile of encountered a
# runtime error
def call redis, *args
begin
run_evalsha redis, *args
Expand All @@ -18,7 +34,7 @@ def call redis, *args
end
rescue => e
if LuaError.intercepts?(e)
raise LuaError.new(e, file)
raise LuaError.new(e, @file)
else
raise
end
Expand All @@ -27,11 +43,11 @@ def call redis, *args
private

def run_evalsha redis, *args
redis.evalsha digest, args.size, *args
redis.evalsha @digest, args.size, *args
end

def run_eval redis, *args
redis.eval content, args.size, *args
redis.eval @content, args.size, *args
end

def load_lua file
Expand Down
6 changes: 0 additions & 6 deletions test/wolverine/script_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ def test_runtime_error
end
end

def test_digest_and_content
content = "return 1"
assert_equal CONTENT, script.content
assert_equal DIGEST, script.digest
end

def test_call_with_cache_hit
tc = self
redis = Class.new do
Expand Down

0 comments on commit 7aec248

Please sign in to comment.