ruby_scope 0.1.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.markdown +45 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/bin/ruby_scope +5 -0
- data/lib/ruby_scope.rb +20 -0
- data/lib/ruby_scope/cli.rb +115 -0
- data/lib/ruby_scope/scanner.rb +92 -0
- data/lib/ruby_scope/sexp_cache.rb +45 -0
- data/test/integration/console_test.rb +51 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/cli_test.rb +41 -0
- data/test/unit/scanner_test.rb +33 -0
- data/test/unit/sexp_cache_test.rb +42 -0
- metadata +109 -0
data/README.markdown
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
RubyScope
|
2
|
+
---------
|
3
|
+
Ruby colored binoculars for your code.
|
4
|
+
|
5
|
+
Usage: ruby_scope [options] path
|
6
|
+
|
7
|
+
Queries:
|
8
|
+
--def NAME Find the definition of instance method NAME
|
9
|
+
--class-def NAME Find the definition of class method NAME
|
10
|
+
--call NAME Find method calls of NAME
|
11
|
+
--class NAME Find definition of NAME
|
12
|
+
--variable NAME Find references to variable NAME
|
13
|
+
--assign NAME Find assignments to NAME
|
14
|
+
--any NAME Find any reference to NAME (class, variable, number)
|
15
|
+
--custom SEXP_PATH Searches for a custom SexpPath
|
16
|
+
|
17
|
+
Options:
|
18
|
+
-R Recursively search folders
|
19
|
+
--no-cache Do not use a cache
|
20
|
+
--cache PATH Use the cache at PATH (defaults to current dir)
|
21
|
+
-v, --verbose Verbose output
|
22
|
+
-h, --help Show this message
|
23
|
+
|
24
|
+
Find all the places `run` or `save` are called in your secret project:
|
25
|
+
|
26
|
+
ruby_scope -R --method 'run' --method 'save' ~/SecretProject
|
27
|
+
|
28
|
+
Where do I assign values to `a`:
|
29
|
+
|
30
|
+
ruby_scope -R --assign 'a' ~/SecretProject
|
31
|
+
|
32
|
+
Of course regular expressions are fair game:
|
33
|
+
|
34
|
+
ruby_scope -R --def '/^test/' ~/SecretProject
|
35
|
+
|
36
|
+
Wicked hacker? Go crazy and write your own SexpPath queries:
|
37
|
+
|
38
|
+
ruby_scope --custom 's(:call, s(:ivar, atom), :save, _)'
|
39
|
+
|
40
|
+
That finds all the saves on instance variables by the way.
|
41
|
+
|
42
|
+
Depends on RubyParser, SexpProcessor, and SexpPath, no gem yet.
|
43
|
+
|
44
|
+
Adam Sanderson
|
45
|
+
netghost@gmail.com
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = "ruby_scope"
|
10
|
+
s.summary = "Ruby colored binoluars for your code."
|
11
|
+
s.description = <<-DESC
|
12
|
+
A ruby hacker's search tool. Quickly interrogate your code, seek out
|
13
|
+
classes, methods, variable assignments, and more.
|
14
|
+
DESC
|
15
|
+
s.email = "netghost@gmail.com"
|
16
|
+
s.homepage = "http://github.com/adamsanderson/ruby_scope"
|
17
|
+
s.authors = ["Adam Sanderson"]
|
18
|
+
s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
|
19
|
+
|
20
|
+
s.add_dependency 'sexp_processor', '~> 3.0'
|
21
|
+
s.add_dependency 'ruby_parser', '~> 2.0'
|
22
|
+
s.add_dependency 'sexp_path', '>= 0.4'
|
23
|
+
|
24
|
+
# Testing
|
25
|
+
s.test_files = FileList["test/**/*_test.rb"]
|
26
|
+
s.add_development_dependency 'mocha', '>= 0.9.8'
|
27
|
+
end
|
28
|
+
|
29
|
+
rescue LoadError
|
30
|
+
puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install jeweler"
|
31
|
+
end
|
32
|
+
|
33
|
+
Rake::RDocTask.new do |t|
|
34
|
+
#t.main = "README.rdoc"
|
35
|
+
t.rdoc_files.include("lib/**/*.rb")
|
36
|
+
end
|
37
|
+
|
38
|
+
Rake::TestTask.new do |t|
|
39
|
+
t.test_files = FileList['test/**/*_test.rb']
|
40
|
+
t.verbose = false
|
41
|
+
end
|
42
|
+
|
43
|
+
namespace :test do
|
44
|
+
['unit', 'integration'].each do |type|
|
45
|
+
Rake::TestTask.new(type) do |t|
|
46
|
+
t.test_files = FileList["test/#{type}/**/*_test.rb"]
|
47
|
+
t.verbose = false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :default => :test
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/bin/ruby_scope
ADDED
data/lib/ruby_scope.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ruby_parser'
|
3
|
+
require 'sexp_path'
|
4
|
+
require 'unified_ruby'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
# RubyScope is a command line tool designed to help you scan ruby code lexically.
|
8
|
+
# See the README for more information.
|
9
|
+
module RubyScope
|
10
|
+
end
|
11
|
+
|
12
|
+
# Load RubyScope
|
13
|
+
root = File.dirname(__FILE__)+'/ruby_scope/'
|
14
|
+
%w[
|
15
|
+
scanner
|
16
|
+
sexp_cache
|
17
|
+
cli
|
18
|
+
].each do |file|
|
19
|
+
require root+file
|
20
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class RubyScope::CLI
|
2
|
+
attr_reader :paths
|
3
|
+
attr_reader :cache_path
|
4
|
+
attr_reader :scanner
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
args = args.clone
|
8
|
+
@scanner = RubyScope::Scanner.new
|
9
|
+
@cache_path = FileUtils.pwd
|
10
|
+
|
11
|
+
opts = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: ruby_scope [options] queries path"
|
13
|
+
|
14
|
+
opts.separator ""
|
15
|
+
opts.separator "Queries:"
|
16
|
+
|
17
|
+
opts.on("--def NAME", "Find the definition of instance method NAME") do |name|
|
18
|
+
@scanner.add_query("s(:defn, #{v name}, _, _)")
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("--class-def NAME", "Find the definition of class method NAME") do |name|
|
22
|
+
@scanner.add_query("s(:defs, _, #{v name}, _, _)")
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("--call NAME", "Find method calls of NAME") do |name|
|
26
|
+
@scanner.add_query("s(:call, _, #{v name}, _)")
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("--class NAME", "Find definition of NAME") do |name|
|
30
|
+
@scanner.add_query("s(:class, #{v name}, _, _)")
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("--variable NAME", "Find references to variable NAME") do |name|
|
34
|
+
tag = instance_variable?(name) ? 'ivar' : 'lvar'
|
35
|
+
@scanner.add_query("s(:#{tag}, #{v name})")
|
36
|
+
end
|
37
|
+
|
38
|
+
# Finds block arguments, variable assignments, method arguments (in that order)
|
39
|
+
opts.on("--assign NAME", "Find assignments to NAME") do |name|
|
40
|
+
tag = instance_variable?(name) ? 'iasgn' : 'lasgn'
|
41
|
+
@scanner.add_query("s(:#{tag}, #{v name}) | s(:#{tag}, #{v name}, _) | (t(:args) & SexpPath::Matcher::Block.new{|s| s[1..-1].any?{|a| a == #{v name}}} )")
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("--any NAME", "Find any reference to NAME (class, variable, number)") do |name|
|
45
|
+
@scanner.add_query("include(#{v name})")
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("--custom SEXP_PATH", "Search for a custom SexpPath") do |sexp|
|
49
|
+
@scanner.add_query(sexp)
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.separator ""
|
53
|
+
opts.separator "Options:"
|
54
|
+
opts.on("-R", "Recursively search folders") do
|
55
|
+
@recurse = true
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on("--no-cache", "Do not use a cache") do
|
59
|
+
@cache_path = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on("--cache PATH", "Use the cache at PATH (defaults to current dir)", "Beware, the cache can get rather large") do |path|
|
63
|
+
@cache_path = path if path
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on("-v", "--verbose", "Verbose output") do
|
67
|
+
@scanner.verbose = true
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
71
|
+
puts opts
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
end
|
75
|
+
opts.parse!(args)
|
76
|
+
|
77
|
+
@paths = args
|
78
|
+
|
79
|
+
if @paths.empty?
|
80
|
+
puts opts
|
81
|
+
exit 1
|
82
|
+
end
|
83
|
+
|
84
|
+
@paths = expand_paths(@paths) if @recurse
|
85
|
+
@scanner.cache = RubyScope::SexpCache.new(@cache_path) if @cache_path
|
86
|
+
end
|
87
|
+
|
88
|
+
def run
|
89
|
+
@paths.each do |path|
|
90
|
+
@scanner.scan path
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
def expand_paths(paths)
|
96
|
+
paths.inject([]){|p,v| File.directory?(v) ? p.concat(Dir[File.join(v,'**/*.rb')]) : p << v; p }
|
97
|
+
end
|
98
|
+
|
99
|
+
# Inserts the appropriate type of value given name.
|
100
|
+
# For instance:
|
101
|
+
# v('/cake/') #=> /cake/ # regular expression match
|
102
|
+
# v('apple') #=> :apple # atom match
|
103
|
+
def v(name)
|
104
|
+
if name =~ /^\/.+\/$/ # regular expression matching regular expression... WIN!
|
105
|
+
"m(#{name})"
|
106
|
+
else
|
107
|
+
":#{name}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def instance_variable?(name)
|
112
|
+
name[0..0] == '@'
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class RubyScope::Scanner
|
2
|
+
attr_accessor :verbose
|
3
|
+
attr_accessor :cache
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@query = nil
|
7
|
+
@verbose = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_query(pattern)
|
11
|
+
# Generate the pattern, we use a little instance_eval trickery here.
|
12
|
+
sexp = case pattern
|
13
|
+
when String then SexpPath::SexpQueryBuilder.instance_eval(pattern)
|
14
|
+
when Sexp then pattern
|
15
|
+
else raise ArgumentError, "Expected a String or Sexp"
|
16
|
+
end
|
17
|
+
|
18
|
+
if @query
|
19
|
+
@query = @query | sexp
|
20
|
+
else
|
21
|
+
@query = sexp
|
22
|
+
end
|
23
|
+
@query
|
24
|
+
|
25
|
+
rescue Exception=>ex
|
26
|
+
puts "Invalid Pattern: '#{pattern}'"
|
27
|
+
puts "Trace:"
|
28
|
+
puts ex
|
29
|
+
puts ex.backtrace
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def query
|
34
|
+
@query.clone if @query
|
35
|
+
end
|
36
|
+
|
37
|
+
def scan(path)
|
38
|
+
@path = path
|
39
|
+
begin
|
40
|
+
report_file path
|
41
|
+
|
42
|
+
# Reset our cached code and split lines
|
43
|
+
@code,@lines = nil,nil
|
44
|
+
|
45
|
+
# Load the code and parse it with RubyParser
|
46
|
+
# If we're caching pull from the cache, otherwise parse the code
|
47
|
+
sexp = @cache[path] if @cache
|
48
|
+
if !sexp
|
49
|
+
sexp = RubyParser.new.parse(code, @path)
|
50
|
+
@cache[path] = sexp if @cache
|
51
|
+
end
|
52
|
+
|
53
|
+
if sexp
|
54
|
+
# Search it with the given pattern, printing any results
|
55
|
+
sexp.search_each(@query) do |matching_sexp|
|
56
|
+
report_match matching_sexp
|
57
|
+
end
|
58
|
+
end
|
59
|
+
rescue StandardError => ex
|
60
|
+
report_exception ex
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
def report_file(path)
|
66
|
+
puts @path if @verbose
|
67
|
+
end
|
68
|
+
|
69
|
+
def report_match(match)
|
70
|
+
if !@lines
|
71
|
+
puts @path unless @verbose
|
72
|
+
@lines = code.split("\n")
|
73
|
+
end
|
74
|
+
line_number = match.sexp.line - 1
|
75
|
+
puts "%4i: %s" % [match.sexp.line, @lines[line_number].strip]
|
76
|
+
end
|
77
|
+
|
78
|
+
def report_exception(ex)
|
79
|
+
debug "Problem processing '#{@path}'"
|
80
|
+
debug ex.message.strip
|
81
|
+
debug ex.backtrace.map{|line| " #{line}"}.join("\n")
|
82
|
+
end
|
83
|
+
|
84
|
+
def code
|
85
|
+
@code ||= File.read(@path)
|
86
|
+
end
|
87
|
+
|
88
|
+
def debug(msg)
|
89
|
+
STDERR.print(msg.to_s.chomp + "\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'dbm'
|
2
|
+
class RubyScope::SexpCache
|
3
|
+
DB = DBM
|
4
|
+
CacheEntry = Struct.new(:last_modified, :sexp)
|
5
|
+
|
6
|
+
def initialize(root)
|
7
|
+
@root = root
|
8
|
+
end
|
9
|
+
|
10
|
+
def [] path
|
11
|
+
with_cache do |cache|
|
12
|
+
entry = cache[path]
|
13
|
+
entry = Marshal.load(entry) if entry
|
14
|
+
|
15
|
+
if entry && entry.last_modified == last_modified(path)
|
16
|
+
entry.sexp
|
17
|
+
else
|
18
|
+
cache.delete path
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def []= path,value
|
25
|
+
with_cache do |cache|
|
26
|
+
entry = CacheEntry.new(last_modified(path), value)
|
27
|
+
cache[path] = Marshal.dump(entry)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def cache_path
|
32
|
+
@cache_path ||= File.join(@root,'.ruby_scope.cache')
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
def with_cache
|
37
|
+
DB.open(cache_path, 0666) do |cache|
|
38
|
+
yield cache
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def last_modified(path)
|
43
|
+
File.mtime(path)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
# Self referential testing!
|
4
|
+
# These are awesome, absurd, and abusive.
|
5
|
+
# Make sure that the app actually does what we say it does.
|
6
|
+
class ConsoleTest < Test::Unit::TestCase
|
7
|
+
ROOT = File.dirname(__FILE__) + '/../../'
|
8
|
+
|
9
|
+
def test_finding_this_test
|
10
|
+
res = rs "--def '/^test/'"
|
11
|
+
assert_success
|
12
|
+
assert res['test_finding_this_test'], "Should have found this test"
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_finding_assignment
|
16
|
+
self_referential_line_number = __LINE__
|
17
|
+
|
18
|
+
res = rs "--assign self_referential_line_number"
|
19
|
+
assert_success
|
20
|
+
assert res.split("\n").last =~ /(\d+)\:\s+self_referential_line_number = __LINE__/
|
21
|
+
assert_equal self_referential_line_number, $1.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_reading_the_help_and_making_queries
|
25
|
+
help = rs "--help"
|
26
|
+
assert help =~ /Queries:(.+)\s+Options:/m, "Should have a queries section"
|
27
|
+
queries = $1
|
28
|
+
queries.split("\n").each do |query|
|
29
|
+
next if query =~ /^\s*$/
|
30
|
+
assert query =~ /(--\S+)\s+(\S+)?/, "Each query should be a long flag with an optional parameter\n#{query.inspect}"
|
31
|
+
flag, param_type = $1,$2
|
32
|
+
param = case param_type
|
33
|
+
when 'NAME' then "a"
|
34
|
+
when 'SEXP_PATH' then "'s()'"
|
35
|
+
else nil
|
36
|
+
end
|
37
|
+
|
38
|
+
res = rs "#{flag} #{param}"
|
39
|
+
assert_success res
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def rs(args)
|
45
|
+
`#{ROOT}bin/ruby_scope --no-cache #{args} #{__FILE__}`
|
46
|
+
end
|
47
|
+
|
48
|
+
def assert_success(msg=nil)
|
49
|
+
assert $?.success?, msg||"Exited with status #{$?.exitstatus}"
|
50
|
+
end
|
51
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class CLITest < Test::Unit::TestCase
|
4
|
+
def test_configuring_scanner
|
5
|
+
query = scanner_with('--def','cats','.').query
|
6
|
+
assert query, "Should have generated a query"
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_configuring_scanner_with_regex
|
10
|
+
query = scanner_with('--def','/cats/','.').query
|
11
|
+
assert query, "Should have generated a query"
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_disabling_cache
|
15
|
+
c = cli_with('--no-cache', '.')
|
16
|
+
assert !c.cache_path
|
17
|
+
assert !c.scanner.cache
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_default_cache_behavior
|
21
|
+
c = cli_with('.')
|
22
|
+
assert c.cache_path
|
23
|
+
assert c.scanner.cache
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_custom_cache_path
|
27
|
+
path = File.dirname(__FILE__) + '../lib'
|
28
|
+
c = cli_with('--cache', path, '.')
|
29
|
+
assert_equal path, c.cache_path
|
30
|
+
assert c.scanner.cache
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def cli_with(*args)
|
35
|
+
RubyScope::CLI.new(args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def scanner_with(*args)
|
39
|
+
cli_with(*args).scanner
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class ScannerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@scanner = RubyScope::Scanner.new
|
6
|
+
@scanner.cache = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_scanning_cache_hit_with_no_match
|
10
|
+
path = 'cached_sample.rb'
|
11
|
+
@scanner.cache[path] = s(:a)
|
12
|
+
@scanner.add_query( s(:b) )
|
13
|
+
|
14
|
+
# Should have no hit
|
15
|
+
@scanner.expects(:report_match).never
|
16
|
+
# Should not try to read the file since it is cached
|
17
|
+
@scanner.expects(:code).never
|
18
|
+
|
19
|
+
@scanner.scan(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_scanning_cache_hit_with_match
|
23
|
+
path = 'cached_sample.rb'
|
24
|
+
@scanner.cache[path] = s(:a)
|
25
|
+
@scanner.add_query( s(:a) )
|
26
|
+
|
27
|
+
# Should report a match
|
28
|
+
@scanner.expects(:report_match)
|
29
|
+
|
30
|
+
@scanner.scan(path)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class SexpCacheTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@path = File.dirname(__FILE__)
|
6
|
+
@cache = RubyScope::SexpCache.new(@path)
|
7
|
+
@cache.stubs(:last_modified).returns('ok')
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
File.delete(@cache.cache_path) if File.exists? @cache.cache_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_misses
|
15
|
+
assert_equal nil, @cache['missing']
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_writing_and_reading
|
19
|
+
key,value = 'a',s(:code)
|
20
|
+
|
21
|
+
@cache[key] = value
|
22
|
+
assert_equal value, @cache[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_expired_reads
|
26
|
+
key,value = 'a',s(:code)
|
27
|
+
|
28
|
+
@cache[key] = value
|
29
|
+
# now invalidate the key
|
30
|
+
@cache.stubs(:last_modified).returns('old')
|
31
|
+
|
32
|
+
assert_equal nil, @cache[key]
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_over_writing_and_reading
|
36
|
+
key,value1,value2 = 'a',s(:code),s(:new_code)
|
37
|
+
|
38
|
+
@cache[key] = value1
|
39
|
+
@cache[key] = value2
|
40
|
+
assert_equal value2, @cache[key]
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_scope
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Sanderson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-04-17 00:00:00 -07:00
|
13
|
+
default_executable: ruby_scope
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sexp_processor
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "3.0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ruby_parser
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "2.0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: sexp_path
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0.4"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: mocha
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.9.8
|
54
|
+
version:
|
55
|
+
description: " A ruby hacker's search tool. Quickly interrogate your code, seek out \n classes, methods, variable assignments, and more.\n"
|
56
|
+
email: netghost@gmail.com
|
57
|
+
executables:
|
58
|
+
- ruby_scope
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.markdown
|
63
|
+
files:
|
64
|
+
- README.markdown
|
65
|
+
- Rakefile
|
66
|
+
- VERSION
|
67
|
+
- bin/ruby_scope
|
68
|
+
- lib/ruby_scope.rb
|
69
|
+
- lib/ruby_scope/cli.rb
|
70
|
+
- lib/ruby_scope/scanner.rb
|
71
|
+
- lib/ruby_scope/sexp_cache.rb
|
72
|
+
- test/integration/console_test.rb
|
73
|
+
- test/test_helper.rb
|
74
|
+
- test/unit/cli_test.rb
|
75
|
+
- test/unit/scanner_test.rb
|
76
|
+
- test/unit/sexp_cache_test.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://github.com/adamsanderson/ruby_scope
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.3.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Ruby colored binoluars for your code.
|
105
|
+
test_files:
|
106
|
+
- test/integration/console_test.rb
|
107
|
+
- test/unit/cli_test.rb
|
108
|
+
- test/unit/scanner_test.rb
|
109
|
+
- test/unit/sexp_cache_test.rb
|