starscope 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -2
- data/Gemfile.lock +5 -1
- data/README.md +5 -7
- data/Rakefile +1 -1
- data/bin/starscope +56 -48
- data/doc/DB_FORMAT.md +4 -4
- data/doc/LANGUAGE_SUPPORT.md +8 -4
- data/doc/USER_GUIDE.md +36 -9
- data/lib/starscope/db.rb +150 -265
- data/lib/starscope/export.rb +256 -0
- data/lib/starscope/langs/coffeescript.rb +2 -1
- data/lib/starscope/langs/go.rb +20 -2
- data/lib/starscope/langs/ruby.rb +60 -71
- data/lib/starscope/matcher.rb +1 -1
- data/lib/starscope/output.rb +9 -7
- data/lib/starscope/version.rb +2 -2
- data/starscope.gemspec +2 -1
- data/test/fixtures/db_added_files.json +8 -0
- data/test/fixtures/db_old_extractor.json +15 -0
- data/test/fixtures/db_out_of_date.json +15 -0
- data/test/fixtures/db_removed_files.json +12 -0
- data/test/fixtures/db_up_to_date.json +15 -0
- data/test/fixtures/sample_ruby.rb +21 -21
- data/test/functional/starscope_test.rb +57 -0
- data/test/test_helper.rb +1 -0
- data/test/unit/db_test.rb +141 -0
- data/test/unit/export_test.rb +34 -0
- data/test/unit/langs/golang_test.rb +98 -0
- data/test/unit/langs/ruby_test.rb +66 -0
- data/test/unit/{test_matcher.rb → matcher_test.rb} +6 -6
- data/test/unit/output_test.rb +29 -0
- metadata +41 -15
- data/lib/starscope/record.rb +0 -98
- data/test/functional/test_starscope.rb +0 -35
- data/test/unit/test_db.rb +0 -136
- data/test/unit/test_golang.rb +0 -80
- data/test/unit/test_record.rb +0 -35
- data/test/unit/test_ruby.rb +0 -60
data/lib/starscope/matcher.rb
CHANGED
data/lib/starscope/output.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'ruby-progressbar'
|
2
2
|
|
3
|
-
class
|
3
|
+
class Starscope::Output
|
4
4
|
|
5
5
|
PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
|
6
6
|
|
7
|
-
def initialize(level)
|
7
|
+
def initialize(level, out=STDOUT)
|
8
|
+
@out = out
|
8
9
|
@level = level
|
9
10
|
@pbar = nil
|
10
11
|
end
|
@@ -12,7 +13,8 @@ class StarScope::Output
|
|
12
13
|
def new_pbar(title, num_items)
|
13
14
|
if @level != :quiet
|
14
15
|
@pbar = ProgressBar.create(:title => title, :total => num_items,
|
15
|
-
:format => PBAR_FORMAT, :length => 80
|
16
|
+
:format => PBAR_FORMAT, :length => 80,
|
17
|
+
:out => @out)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -25,12 +27,12 @@ class StarScope::Output
|
|
25
27
|
@pbar = nil
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
29
|
-
return
|
30
|
+
def extra(msg)
|
31
|
+
return unless @level == :verbose
|
30
32
|
output(msg)
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
35
|
+
def normal(msg)
|
34
36
|
return if @level == :quiet
|
35
37
|
output(msg)
|
36
38
|
end
|
@@ -41,7 +43,7 @@ class StarScope::Output
|
|
41
43
|
if @pbar
|
42
44
|
@pbar.log(msg)
|
43
45
|
else
|
44
|
-
puts msg
|
46
|
+
@out.puts msg
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
data/lib/starscope/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "1.
|
1
|
+
module Starscope
|
2
|
+
VERSION = "1.2.0"
|
3
3
|
end
|
data/starscope.gemspec
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path('../lib/starscope/version.rb', __FILE__)
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = 'starscope'
|
5
|
-
gem.version =
|
5
|
+
gem.version = Starscope::VERSION
|
6
6
|
gem.summary = "A code indexer and analyzer"
|
7
7
|
gem.description = "A tool like the venerable cscope, but for ruby, golang and other languages"
|
8
8
|
gem.authors = ["Evan Huus"]
|
@@ -22,4 +22,5 @@ Gem::Specification.new do |gem|
|
|
22
22
|
gem.add_development_dependency 'rake'
|
23
23
|
gem.add_development_dependency 'pry'
|
24
24
|
gem.add_development_dependency 'minitest'
|
25
|
+
gem.add_development_dependency 'mocha'
|
25
26
|
end
|
@@ -2,11 +2,11 @@ require 'date'
|
|
2
2
|
require 'zlib'
|
3
3
|
|
4
4
|
LANGS = [
|
5
|
-
|
6
|
-
|
5
|
+
Starscope::Lang::Go,
|
6
|
+
Starscope::Lang::Ruby
|
7
7
|
]
|
8
8
|
|
9
|
-
class
|
9
|
+
class Starscope::DB
|
10
10
|
|
11
11
|
PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
|
12
12
|
|
@@ -20,21 +20,21 @@ class StarScope::DB
|
|
20
20
|
self.foo = :bar
|
21
21
|
end
|
22
22
|
|
23
|
-
def load(
|
24
|
-
File.open(
|
25
|
-
Zlib::GzipReader.wrap(file) do |
|
26
|
-
format =
|
23
|
+
def load(filename)
|
24
|
+
File.open(filename, 'r') do |file|
|
25
|
+
Zlib::GzipReader.wrap(file) do |stream|
|
26
|
+
format = stream.gets.to_i
|
27
27
|
if format == DB_FORMAT
|
28
|
-
@paths = Oj.load(
|
29
|
-
@files = Oj.load(
|
30
|
-
@tables = Oj.load(
|
28
|
+
@paths = Oj.load(stream.gets)
|
29
|
+
@files = Oj.load(stream.gets)
|
30
|
+
@tables = Oj.load(stream.gets, :symbol_keys => true)
|
31
31
|
elsif format <= 2
|
32
32
|
# Old format (pre-json), so read the directories segment then rebuild
|
33
|
-
len =
|
34
|
-
add_paths(Marshal::load(
|
33
|
+
len = stream.gets.to_i
|
34
|
+
add_paths(Marshal::load(stream.read(len)))
|
35
35
|
elsif format < DB_FORMAT
|
36
36
|
# Old format, so read the directories segment then rebuild
|
37
|
-
add_paths(Oj.load(
|
37
|
+
add_paths(Oj.load(stream.gets))
|
38
38
|
elsif format > DB_FORMAT
|
39
39
|
raise UnknownDBFormatError
|
40
40
|
end
|
@@ -42,13 +42,13 @@ class StarScope::DB
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def save(
|
46
|
-
File.open(
|
47
|
-
Zlib::GzipWriter.wrap(file) do |
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
def save(filename)
|
46
|
+
File.open(filename, 'w') do |file|
|
47
|
+
Zlib::GzipWriter.wrap(file) do |stream|
|
48
|
+
stream.puts DB_FORMAT
|
49
|
+
stream.puts Oj.dump @paths
|
50
|
+
stream.puts Oj.dump @files
|
51
|
+
stream.puts Oj.dump @tables
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -134,7 +134,7 @@ class StarScope::DB
|
|
134
134
|
key = key.to_sym
|
135
135
|
@tables[tbl] ||= {}
|
136
136
|
@tables[tbl][key] ||= []
|
137
|
-
@tables[tbl][key] <<
|
137
|
+
@tables[tbl][key] << Starscope::Datum.build(file, key, args)
|
138
138
|
end
|
139
139
|
end
|
140
140
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "starscope executable script" do
|
4
|
+
|
5
|
+
BASE = "bundle exec bin/starscope --quiet"
|
6
|
+
EXTRACT = "#{BASE} --no-read --no-write #{FIXTURES}"
|
7
|
+
|
8
|
+
it "must not produce help wider than 80 characters" do
|
9
|
+
`#{BASE} -h`.each_line do |line|
|
10
|
+
line.length.must_be :<=, 80
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must produce the right version" do
|
15
|
+
`#{BASE} -v`.chomp.must_equal Starscope::VERSION
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must produce a valid database summary" do
|
19
|
+
lines = `#{EXTRACT} -s`.lines.to_a
|
20
|
+
lines.length.must_equal 6
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must produce a valid database dump" do
|
24
|
+
lines = `#{EXTRACT} -d requires`.lines.to_a
|
25
|
+
lines[1].split.first.must_equal 'date'
|
26
|
+
lines[2].split.first.must_equal 'zlib'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "must correctly query the database" do
|
30
|
+
`#{EXTRACT} -q calls,add_file`.each_line do |line|
|
31
|
+
line.split[0..2].must_equal ["Starscope", "DB", "add_file"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "must correctly export to cscope" do
|
36
|
+
file = Tempfile.new('starscope_test')
|
37
|
+
begin
|
38
|
+
`#{EXTRACT} -e cscope,#{file.path()}`
|
39
|
+
$?.exitstatus.must_equal 0
|
40
|
+
ensure
|
41
|
+
file.close
|
42
|
+
file.unlink
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Must correctly export to ctags" do
|
47
|
+
file = Tempfile.new('starscope_test')
|
48
|
+
begin
|
49
|
+
`#{EXTRACT} -e ctags,#{file.path()}`
|
50
|
+
$?.exitstatus.must_equal 0
|
51
|
+
ensure
|
52
|
+
file.close
|
53
|
+
file.unlink
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe Starscope::DB do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@db = Starscope::DB.new(Starscope::Output.new(:quiet))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must raise on invalid tables" do
|
11
|
+
proc {
|
12
|
+
@db.records(:foo)
|
13
|
+
}.must_raise Starscope::DB::NoTableError
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must add paths" do
|
17
|
+
paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
|
18
|
+
@db.add_paths(paths)
|
19
|
+
|
20
|
+
@db.metadata(:paths).must_equal paths
|
21
|
+
validate(@db)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "must add excludes" do
|
25
|
+
paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
|
26
|
+
@db.add_paths(paths)
|
27
|
+
@db.add_excludes(["#{FIXTURES}/**"])
|
28
|
+
|
29
|
+
files = @db.metadata(:files).keys
|
30
|
+
files.wont_include RUBY_SAMPLE
|
31
|
+
files.wont_include GOLANG_SAMPLE
|
32
|
+
@db.records(:defs).must_be_empty
|
33
|
+
@db.records(:end).must_be_empty
|
34
|
+
end
|
35
|
+
|
36
|
+
it "must pick up new files in old paths" do
|
37
|
+
@db.load("#{FIXTURES}/db_added_files.json")
|
38
|
+
@db.update
|
39
|
+
|
40
|
+
validate(@db)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "must remove old files in existing paths" do
|
44
|
+
@db.load("#{FIXTURES}/db_removed_files.json")
|
45
|
+
@db.update
|
46
|
+
@db.metadata(:files).keys.wont_include "#{FIXTURES}/foo"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "must update stale existing files when extractor hasn't changed" do
|
50
|
+
@db.load("#{FIXTURES}/db_out_of_date.json")
|
51
|
+
@db.metadata(:langs)[:Go].must_be :>=, LANGS[:Go]
|
52
|
+
|
53
|
+
cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
|
54
|
+
File.expects(:mtime).twice.returns(cur_mtime + 1)
|
55
|
+
@db.update
|
56
|
+
|
57
|
+
file = @db.metadata(:files)[GOLANG_SAMPLE]
|
58
|
+
file[:last_updated].must_equal cur_mtime + 1
|
59
|
+
file[:lang].must_equal :Go
|
60
|
+
file[:lines].wont_be_empty
|
61
|
+
@db.records(:defs).wont_be_empty
|
62
|
+
@db.records(:calls).wont_be_empty
|
63
|
+
end
|
64
|
+
|
65
|
+
it "must update unchanged existing files with old extractor versions" do
|
66
|
+
@db.load("#{FIXTURES}/db_old_extractor.json")
|
67
|
+
|
68
|
+
cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
|
69
|
+
File.expects(:mtime).twice.returns(cur_mtime)
|
70
|
+
@db.update
|
71
|
+
|
72
|
+
file = @db.metadata(:files)[GOLANG_SAMPLE]
|
73
|
+
file[:last_updated].must_equal cur_mtime
|
74
|
+
file[:lang].must_equal :Go
|
75
|
+
file[:lines].wont_be_empty
|
76
|
+
@db.records(:defs).wont_be_empty
|
77
|
+
@db.records(:calls).wont_be_empty
|
78
|
+
end
|
79
|
+
|
80
|
+
it "must not update file with up-to-date time and extractor" do
|
81
|
+
@db.load("#{FIXTURES}/db_up_to_date.json")
|
82
|
+
@db.update
|
83
|
+
|
84
|
+
file = @db.metadata(:files)[GOLANG_SAMPLE]
|
85
|
+
file[:last_updated].must_equal 10000000000
|
86
|
+
@db.tables.must_be_empty
|
87
|
+
end
|
88
|
+
|
89
|
+
it "must load an old DB file" do
|
90
|
+
@db.load("#{FIXTURES}/db_old.json.gz")
|
91
|
+
@db.metadata(:paths).must_equal ["#{FIXTURES}/**/*"]
|
92
|
+
validate(@db)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "must round-trip a database" do
|
96
|
+
file = Tempfile.new('starscope_test')
|
97
|
+
begin
|
98
|
+
@db.add_paths([FIXTURES])
|
99
|
+
@db.save(file.path)
|
100
|
+
tmp = Starscope::DB.new(Starscope::Output.new(:quiet))
|
101
|
+
tmp.load(file.path)
|
102
|
+
validate(tmp)
|
103
|
+
ensure
|
104
|
+
file.close
|
105
|
+
file.unlink
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "must run queries" do
|
110
|
+
@db.add_paths([FIXTURES])
|
111
|
+
@db.query(:calls, "abc").must_equal []
|
112
|
+
@db.query(:defs, "xyz").must_equal []
|
113
|
+
@db.query(:calls, "add_file").length.must_equal 3
|
114
|
+
end
|
115
|
+
|
116
|
+
it "must symbolize compound name" do
|
117
|
+
rec = Starscope::DB.normalize_record(:foo, ["a", :b], {})
|
118
|
+
rec[:name].must_equal [:a, :b]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "must symbolize and array-wrap simple name" do
|
122
|
+
rec = Starscope::DB.normalize_record(:foo, "a", {})
|
123
|
+
rec[:name].must_equal [:a]
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def validate(db)
|
129
|
+
files = db.metadata(:files)
|
130
|
+
files.keys.must_include GOLANG_SAMPLE
|
131
|
+
files.keys.must_include RUBY_SAMPLE
|
132
|
+
files[GOLANG_SAMPLE][:last_updated].must_equal File.mtime(GOLANG_SAMPLE).to_i
|
133
|
+
files[RUBY_SAMPLE][:last_updated].must_equal File.mtime(RUBY_SAMPLE).to_i
|
134
|
+
|
135
|
+
db.records(:defs).wont_be_empty
|
136
|
+
db.records(:calls).wont_be_empty
|
137
|
+
db.records(:imports).wont_be_empty
|
138
|
+
db.records(:requires).wont_be_empty
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Starscope::Export do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@db = Starscope::DB.new(Starscope::Output.new(:quiet))
|
7
|
+
@db.add_paths([FIXTURES])
|
8
|
+
@buf = StringIO.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must export to ctags" do
|
12
|
+
@db.export_to(:ctags, @buf)
|
13
|
+
@buf.rewind
|
14
|
+
lines = @buf.lines.to_a
|
15
|
+
lines.must_include "NoTableError\t#{FIXTURES}/sample_ruby.rb\t/^ class NoTableError < StandardError; end$/;\"\tkind:c\tlanguage:Ruby\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must export to cscope" do
|
19
|
+
@db.export_to(:cscope, @buf)
|
20
|
+
@buf.rewind
|
21
|
+
lines = @buf.lines.to_a
|
22
|
+
|
23
|
+
lines.must_include "\t@#{FIXTURES}/sample_golang.go\n"
|
24
|
+
lines.must_include "\tgSunday\n"
|
25
|
+
lines.must_include "\t`add_file\n"
|
26
|
+
lines.must_include "\t}}\n"
|
27
|
+
lines.must_include "13 class \n"
|
28
|
+
|
29
|
+
lines.wont_include "= [\n"
|
30
|
+
lines.wont_include "4 LANGS = [\n"
|
31
|
+
lines.wont_include "116 tmpdb[entry[:file]][entry[:line_no]] ||= []\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|