callsite 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'callsite'
2
+ Callsite.activate_kernel_require_methods
3
+ Callsite.activate_kernel_dir_methods
4
+ Callsite.activate_string_methods
5
+ Callsite.activate_file_methods
6
+ Callsite.activate_module_methods
@@ -0,0 +1,7 @@
1
+ require 'callsite'
2
+ Callsite.activate_loadpath_methods
3
+ Callsite.activate_kernel_require_methods
4
+ Callsite.activate_kernel_dir_methods
5
+ Callsite.activate_string_methods
6
+ Callsite.activate_file_methods
7
+ Callsite.activate_module_methods
@@ -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,2 @@
1
+ $test2 = 1
2
+ require_next "test2"
@@ -0,0 +1 @@
1
+ $state2 = true
@@ -0,0 +1 @@
1
+ $test2 = 2 if $test2 == 1
@@ -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