callsite 0.0.1
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/README.rdoc +66 -0
- data/Rakefile +37 -0
- data/VERSION +1 -0
- data/lib/callsite.rb +105 -0
- data/lib/dirge.rb +6 -0
- data/lib/load_path_find.rb +7 -0
- data/lib/loaders/kernel_dir.rb +17 -0
- data/lib/loaders/kernel_require.rb +18 -0
- data/lib/loaders/load_path.rb +26 -0
- data/spec/data/dir1/test.rb +1 -0
- data/spec/data/dir1/test2.rb +2 -0
- data/spec/data/dir2/test.rb +1 -0
- data/spec/data/dir2/test2.rb +1 -0
- data/spec/dirge_spec.rb +33 -0
- data/spec/load_path_find_spec.rb +62 -0
- data/spec/test:2test/test.rb +1 -0
- metadata +76 -0
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= Callsite
|
2
|
+
|
3
|
+
Caller/backtrace parser with some useful utilities for manipulating the load path, and doing other relative things.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
The primary thing you can do is parse a caller line(s).
|
8
|
+
|
9
|
+
pp Callsite.parse(caller)
|
10
|
+
|
11
|
+
Gives back
|
12
|
+
|
13
|
+
=> [#<struct Callsite::Line
|
14
|
+
filename="/opt/local/lib/ruby/1.8/irb/workspace.rb",
|
15
|
+
line=52,
|
16
|
+
method="irb_binding">,
|
17
|
+
#<struct Callsite::Line filename="", line=0, method=nil>]
|
18
|
+
|
19
|
+
This is also suitable for parsing a backtrace, to get detailed information about it.
|
20
|
+
|
21
|
+
There are also five methods which patch existing objects to give you powerful usage of the caller.
|
22
|
+
|
23
|
+
=== Callsite.activate_string_methods
|
24
|
+
|
25
|
+
This gives you the ~@ method on +String+, which takes any string, and gives you a relative version of it, treating it as a file path. For example,
|
26
|
+
|
27
|
+
~'lib/callsite.rb'
|
28
|
+
|
29
|
+
Gives you (on my laptop)
|
30
|
+
|
31
|
+
=> "/Users/joshua/Development/callsite/lib/callsite.rb"
|
32
|
+
|
33
|
+
=== Callsite.activate_file_methods
|
34
|
+
|
35
|
+
This adds the +File.relative+ method. File.relative(file_path) has the same effect as ~file_path.
|
36
|
+
|
37
|
+
=== Callsite.activate_module_methods
|
38
|
+
|
39
|
+
This adds +autoload_relative+ onto Module. This allows you to do the following.
|
40
|
+
|
41
|
+
module MyModule
|
42
|
+
autoload_relative :Whatever, "lib/whatever"
|
43
|
+
end
|
44
|
+
|
45
|
+
In this case, lib/whatever will be treated as a relative path from the definition of the module.
|
46
|
+
|
47
|
+
=== Callsite.activate_kernel_dir_methods
|
48
|
+
|
49
|
+
This adds the __DIR_REL__ and optionally __DIR__ and require_relative methods to Kernel. __DIR__ or __DIR_REL__ will give you your current directory, much like
|
50
|
+
__FILE__ gives you the current __FILE__ you're in. +require_relative+ is like +require+ .. only, it's relative.
|
51
|
+
|
52
|
+
=== Callsite.activate_kernel_require_methods
|
53
|
+
|
54
|
+
This adds a couple of weird methods to Kernel, require_next and require_all. There search your current $LOAD_PATH, and require the next file (ingoring the current one you're in on the load_path) or require all files of a given name.
|
55
|
+
|
56
|
+
=== Callsite.activate_load_path_methods
|
57
|
+
|
58
|
+
This adds some super useful methods to $LOAD_PATH. There are find_file (finds a single file on your load path), find_all_files (finds all of em), add_current (adds to the end of the load path your current dir) and add_current! (adds it to the beginning).
|
59
|
+
|
60
|
+
== I lied
|
61
|
+
|
62
|
+
I said there were 5, I meant 6. There are 5 lights.
|
63
|
+
|
64
|
+
== This deprecates +dirge+ and +load_path_find+
|
65
|
+
|
66
|
+
Once you have this installed, you can use require 'dirge' and require 'load_path_find' to get exactly the functionality you had before.
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |s|
|
4
|
+
s.name = "callsite"
|
5
|
+
s.description = s.summary = "Caller/backtrace parser with some useful utilities for manipulating the load path, and doing other relative things."
|
6
|
+
s.email = "joshbuddy@gmail.com"
|
7
|
+
s.homepage = "http://github.com/joshbuddy/callsite"
|
8
|
+
s.authors = ["Joshua Hull"]
|
9
|
+
s.files = FileList["[A-Z]*", "{lib}/**/*"]
|
10
|
+
end
|
11
|
+
Jeweler::GemcutterTasks.new
|
12
|
+
rescue LoadError
|
13
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'spec'
|
17
|
+
require 'spec/rake/spectask'
|
18
|
+
task :spec => ['spec:dirge', 'spec:load_path_find']
|
19
|
+
namespace(:spec) do
|
20
|
+
Spec::Rake::SpecTask.new(:dirge) do |t|
|
21
|
+
t.spec_opts ||= []
|
22
|
+
t.spec_opts << "-rubygems"
|
23
|
+
t.spec_opts << '-rlib/dirge'
|
24
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
25
|
+
t.spec_files = FileList['spec/**/dirge_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:load_path_find) do |t|
|
29
|
+
t.spec_opts ||= []
|
30
|
+
t.spec_opts << "-rubygems"
|
31
|
+
t.spec_opts << '-rlib/load_path_find'
|
32
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
33
|
+
t.spec_files = FileList['spec/**/load_path_find_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/callsite.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
2
|
+
|
3
|
+
module Callsite
|
4
|
+
UnparsableCallLine = Class.new(RuntimeError)
|
5
|
+
Line = Struct.new(:filename, :line, :method)
|
6
|
+
|
7
|
+
def self.__DIR_REL__(called_from = nil)
|
8
|
+
called_from ||= caller.first
|
9
|
+
caller_path = parse(called_from).filename
|
10
|
+
caller_path = '.' if caller_path == ''
|
11
|
+
File.expand_path(File.dirname(caller_path))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse(input)
|
15
|
+
if input.is_a?(Array)
|
16
|
+
block_given? ?
|
17
|
+
input.each{|line| yield parse(line)} :
|
18
|
+
input.map{|line| parse(line)}
|
19
|
+
else
|
20
|
+
if match = input.match(/^(.*?)(:(\d+))(:in `(.*)')?$/)
|
21
|
+
Line.new(match[1], match[3].to_i, match[5])
|
22
|
+
else
|
23
|
+
raise UnparsableCallLine.new("unable to parse #{input}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.activate_string_methods
|
29
|
+
activate_kernel_dir_methods
|
30
|
+
::String.send(:include, StringMethods)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.activate_file_methods
|
34
|
+
activate_kernel_dir_methods
|
35
|
+
::File.send(:extend, FileMethods)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.activate_module_methods
|
39
|
+
activate_kernel_dir_methods
|
40
|
+
::Module.send(:include, ModuleMethods)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.activate_kernel_dir_methods
|
44
|
+
require 'loaders/kernel_dir'
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.activate_kernel_require_methods
|
48
|
+
activate_loadpath_methods
|
49
|
+
require 'loaders/kernel_require'
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.activate_loadpath_methods
|
53
|
+
activate_kernel_dir_methods
|
54
|
+
require 'loaders/load_path'
|
55
|
+
end
|
56
|
+
|
57
|
+
module StringMethods
|
58
|
+
unless method_defined?(:~@)
|
59
|
+
def ~@
|
60
|
+
File.expand_path(File.join(Kernel.__DIR_REL__(caller.first), self))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module FileMethods
|
66
|
+
def relative(path)
|
67
|
+
File.expand_path(File.join(Kernel.__DIR_REL__(caller.first), path))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module ModuleMethods
|
72
|
+
unless method_defined?(:autoload_relative)
|
73
|
+
def autoload_relative(name, filename)
|
74
|
+
autoload name, File.join(Kernel.__DIR_REL__(caller.first), filename)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module LoadPathMethods
|
80
|
+
def find_file(file)
|
81
|
+
find_all_files(file){|f| return f}
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_all_files(file, ext = nil)
|
86
|
+
file += ext if ext and File.extname(file) != ext
|
87
|
+
inject([]){|ary, path|
|
88
|
+
target = File.expand_path(file, path)
|
89
|
+
if File.readable?(target)
|
90
|
+
ary << target
|
91
|
+
yield target if block_given?
|
92
|
+
end
|
93
|
+
ary
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_current
|
98
|
+
self << __DIR_REL__(caller.first)
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_current!
|
102
|
+
self.unshift(__DIR_REL__(caller.first))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/dirge.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Kernel
|
2
|
+
def __DIR_REL__(called_from = nil)
|
3
|
+
parsed_line = Callsite.parse(called_from || caller.first)
|
4
|
+
parsed_line && File.expand_path(File.dirname(parsed_line.filename))
|
5
|
+
end
|
6
|
+
|
7
|
+
unless method_defined?(:__DIR__)
|
8
|
+
alias_method :__DIR__, :__DIR_REL__
|
9
|
+
end
|
10
|
+
|
11
|
+
unless method_defined?(:require_relative)
|
12
|
+
def require_relative(path)
|
13
|
+
require File.join(__DIR_REL__(caller.first), path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Kernel
|
2
|
+
def require_all(req)
|
3
|
+
$LOAD_PATH.find_all_files(req, ".rb") { |file| require file }
|
4
|
+
end
|
5
|
+
|
6
|
+
def require_next(req)
|
7
|
+
found, current = false, File.expand_path(caller.first[/^[^:]+/])
|
8
|
+
$LOAD_PATH.find_all_files(req, ".rb") do |file|
|
9
|
+
if found
|
10
|
+
$LOADED_FEATURES << req
|
11
|
+
return require(file)
|
12
|
+
else
|
13
|
+
found = current == file
|
14
|
+
end
|
15
|
+
end
|
16
|
+
require req
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.instance_eval do
|
2
|
+
def find_file(file)
|
3
|
+
find_all_files(file){|f| return f}
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_all_files(file, ext = nil)
|
8
|
+
file += ext if ext and File.extname(file) != ext
|
9
|
+
inject([]){|ary, path|
|
10
|
+
target = File.expand_path(file, path)
|
11
|
+
if File.readable?(target)
|
12
|
+
ary << target
|
13
|
+
yield target if block_given?
|
14
|
+
end
|
15
|
+
ary
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_current
|
20
|
+
self << __DIR_REL__(caller.first)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_current!
|
24
|
+
self.unshift(__DIR_REL__(caller.first))
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
$state1 = true
|
@@ -0,0 +1 @@
|
|
1
|
+
$state2 = true
|
@@ -0,0 +1 @@
|
|
1
|
+
$test2 = 2 if $test2 == 1
|
data/spec/dirge_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
describe 'Dirge' do
|
2
|
+
it "should resolve a path through String#~" do
|
3
|
+
(~'test:2test/test').should == File.expand_path(File.join(File.dirname(__FILE__), 'test:2test', 'test'))
|
4
|
+
end
|
5
|
+
|
6
|
+
it "should resolve a path through File#relative" do
|
7
|
+
File.relative('test:2test/test').should == File.expand_path(File.join(File.dirname(__FILE__), 'test:2test', 'test'))
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should require a relative path' do
|
11
|
+
proc {
|
12
|
+
require_relative 'test:2test/test'
|
13
|
+
}.should raise_error(RuntimeError, 'okay okay, you included me')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should autoload a relative path' do
|
17
|
+
proc {
|
18
|
+
mod = Module.new do
|
19
|
+
autoload_relative :TestingTime, 'test:2test/test'
|
20
|
+
end
|
21
|
+
mod::TestingTime
|
22
|
+
}.should raise_error(RuntimeError, 'okay okay, you included me')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should define __DIR__" do
|
26
|
+
__DIR__.should == File.expand_path(File.dirname(__FILE__))
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should define __DIR__ with a custom caller" do
|
30
|
+
__DIR__('testing/test.rb:3').should == File.expand_path('testing')
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'lib/load_path_find'
|
2
|
+
|
3
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'data', 'dir1'))
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'data', 'dir2'))
|
5
|
+
|
6
|
+
describe 'load path find' do
|
7
|
+
it "should find a file on the load path" do
|
8
|
+
target = File.join('file1')
|
9
|
+
$:.find_file(target)[-target.size, target.size].should == target
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should find a directory on the load path" do
|
13
|
+
target = "data/dir1"
|
14
|
+
$:.find_file("../dir1")[-target.size, target.size].should == target
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should find the first file when its ambigious" do
|
18
|
+
target = File.join('file1')
|
19
|
+
expected_target = File.join('dir1', 'file1')
|
20
|
+
$:.find_file(target)[-expected_target.size, expected_target.size].should == expected_target
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should find all files that match" do
|
24
|
+
target = File.join('file1')
|
25
|
+
expected_target = File.join('dir1', 'file1')
|
26
|
+
$:.find_all_files(target).should == [
|
27
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'data', 'dir1', 'file1')),
|
28
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'data', 'dir2', 'file1'))
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should yield all files that match if a block is given" do
|
33
|
+
target = File.join('file1')
|
34
|
+
mock = Object.new
|
35
|
+
mock.should_receive(:hello).exactly(2).times
|
36
|
+
$:.find_all_files(target) { mock.hello }
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should add the current path" do
|
40
|
+
$LOAD_PATH.add_current
|
41
|
+
$LOAD_PATH.last.should == __DIR__
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should add the current path to the start" do
|
45
|
+
$LOAD_PATH.add_current!
|
46
|
+
$LOAD_PATH.first.should == __DIR__
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should require_all" do
|
50
|
+
$state1.should be_nil
|
51
|
+
$state2.should be_nil
|
52
|
+
require_all('test')
|
53
|
+
$state1.should be_true
|
54
|
+
$state2.should be_true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should require_next" do
|
58
|
+
require 'test2'
|
59
|
+
$test2.should == 2
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
raise 'okay okay, you included me'
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: callsite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Joshua Hull
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-20 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Caller/backtrace parser with some useful utilities for manipulating the load path, and doing other relative things.
|
22
|
+
email: joshbuddy@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.rdoc
|
29
|
+
files:
|
30
|
+
- README.rdoc
|
31
|
+
- Rakefile
|
32
|
+
- VERSION
|
33
|
+
- lib/callsite.rb
|
34
|
+
- lib/dirge.rb
|
35
|
+
- lib/load_path_find.rb
|
36
|
+
- lib/loaders/kernel_dir.rb
|
37
|
+
- lib/loaders/kernel_require.rb
|
38
|
+
- lib/loaders/load_path.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/joshbuddy/callsite
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.6
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Caller/backtrace parser with some useful utilities for manipulating the load path, and doing other relative things.
|
69
|
+
test_files:
|
70
|
+
- spec/data/dir1/test.rb
|
71
|
+
- spec/data/dir1/test2.rb
|
72
|
+
- spec/data/dir2/test.rb
|
73
|
+
- spec/data/dir2/test2.rb
|
74
|
+
- spec/dirge_spec.rb
|
75
|
+
- spec/load_path_find_spec.rb
|
76
|
+
- spec/test:2test/test.rb
|