Skip to content
Browse files

Identify application directory with Caller class

We need a way to find the directory in which hovercraft was required. By
removing all the junk from caller we're left with a pretty good guess as
to where the directory is.
  • Loading branch information...
1 parent 2e2bcc9 commit a6ae0bac50d1793401f5b1699b5946167cfc29c8 @vanstee committed Jun 20, 2012
Showing with 58 additions and 5 deletions.
  1. +1 −5 lib/hovercraft.rb
  2. +29 −0 lib/hovercraft/caller.rb
  3. +28 −0 spec/hovercraft/caller_spec.rb
View
6 lib/hovercraft.rb
@@ -1,5 +1 @@
-require "hovercraft/version"
-
-module Hovercraft
- # Your code goes here...
-end
+require 'hovercraft/version'
View
29 lib/hovercraft/caller.rb
@@ -0,0 +1,29 @@
+module Hovercraft
+ class Caller
+ CALLERS_TO_IGNORE = [
+ /\/hovercraft(\/(caller|loader|builder|server))?\.rb$/, # hovercraft libary
+ /\/sinatra(\/(base|main|showexceptions))?\.rb$/, # sinatra library
+ /^\(.*\)$/, # generated code
+ /lib\/ruby/, # ruby core libraries
+ /rubygems\/custom_require\.rb$/, # rubygems require hacks
+ /active_support/, # active_support require hack
+ /bundler(\/runtime)?\.rb/, # bundler require hacks
+ /<internal:/, # internal in ruby >= 1.9.2
+ /src\/kernel\/bootstrap\/[A-Z]/ # maglev kernel files
+ ]
+
+ def directory
+ File.dirname(caller_file)
+ end
+
+ def caller_file
+ cleaned_caller_files.first || $PROGRAM_NAME
+ end
+
+ def cleaned_caller_files
+ caller(1).map { |line| line.split(/:(?=\d|in )/, 3)[0, 1] }.
+ reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }.
+ flatten
+ end
+ end
+end
View
28 spec/hovercraft/caller_spec.rb
@@ -0,0 +1,28 @@
+require 'hovercraft/caller'
+
+describe Hovercraft::Caller do
+ describe '#directory' do
+ before { subject.stub(caller_file: '/gems/futurama/parallel_universe_box.rb:10 in `universe`') }
+
+ it 'returns the directory of the file at the top of the execution stack' do
+ subject.directory.should == '/gems/futurama'
+ end
+ end
+
+ describe '#cleaned_caller_files' do
+ let(:files) do
+ [
+ '/gems/futurama/parallel_universe_box.rb:10 in `universe`',
+ '/gems/futurama/parallel_universe_box.rb:3 in `initialize`',
+ '<internal: (irb)'
+ ]
+ end
+
+ before { subject.stub(caller: files) }
+
+ it 'returns a cleaned list of files on the execution stack' do
+ subject.cleaned_caller_files.should_not include('<internal: (irb)')
+ subject.cleaned_caller_files.should have(2).files
+ end
+ end
+end

0 comments on commit a6ae0ba

Please sign in to comment.
Something went wrong with that request. Please try again.