starscope 1.1.2 → 1.2.0
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.
- 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
|