starscope 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,20 @@
1
- require "parser/current"
1
+ require 'parser/current'
2
2
 
3
3
  module Starscope::Lang
4
4
  module Ruby
5
5
  VERSION = 2
6
6
 
7
7
  def self.match_file(name)
8
- return true if name.end_with?(".rb") || name.end_with?(".rake")
8
+ return true if name.end_with?('.rb') || name.end_with?('.rake')
9
9
  File.open(name) do |f|
10
10
  head = f.read(2)
11
- return false if head.nil? || !head.start_with?("#!")
12
- return f.readline.include?("ruby")
11
+ return false if head.nil? || !head.start_with?('#!')
12
+ return f.readline.include?('ruby')
13
13
  end
14
14
  end
15
15
 
16
- def self.extract(file, &block)
17
- ast = Parser::CurrentRuby.parse_file(file)
16
+ def self.extract(path, contents, &block)
17
+ ast = Parser::CurrentRuby.parse(contents)
18
18
  extract_tree(ast, [], &block) unless ast.nil?
19
19
  end
20
20
 
@@ -29,7 +29,7 @@ module Starscope::Lang
29
29
  scope += new_scope
30
30
  end
31
31
 
32
- tree.children.each {|node| extract_tree(node, scope, &block) if node.is_a? AST::Node}
32
+ tree.children.each { |node| extract_tree(node, scope, &block) if node.is_a? AST::Node }
33
33
 
34
34
  scope.pop(new_scope.count)
35
35
  end
@@ -45,8 +45,8 @@ module Starscope::Lang
45
45
  if name.last.to_s =~ /\w+=$/
46
46
  name[-1] = name.last.to_s.chop.to_sym
47
47
  yield :assigns, name, :line_no => loc.line, :col => loc.column
48
- elsif node.children[0].nil? and node.children[1] == :require and node.children[2].type == :str
49
- yield :requires, node.children[2].children[0].split("/"),
48
+ elsif node.children[0].nil? && node.children[1] == :require && node.children[2].type == :str
49
+ yield :requires, node.children[2].children[0].split('/'),
50
50
  :line_no => loc.line, :col => loc.column
51
51
  end
52
52
 
@@ -83,7 +83,7 @@ module Starscope::Lang
83
83
  when :sym
84
84
  # handle `:foo` vs `foo: 1`
85
85
  col = if loc.begin
86
- loc.begin.column+1
86
+ loc.begin.column + 1
87
87
  else
88
88
  loc.expression.column
89
89
  end
@@ -1,10 +1,9 @@
1
1
  require 'ruby-progressbar'
2
2
 
3
3
  class Starscope::Output
4
-
5
4
  PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
6
5
 
7
- def initialize(level, out=STDOUT)
6
+ def initialize(level, out = STDOUT)
8
7
  @out = out
9
8
  @level = level
10
9
  @pbar = nil
@@ -13,8 +12,8 @@ class Starscope::Output
13
12
  def new_pbar(title, num_items)
14
13
  if @level != :quiet
15
14
  @pbar = ProgressBar.create(:title => title, :total => num_items,
16
- :format => PBAR_FORMAT, :length => 80,
17
- :out => @out)
15
+ :format => PBAR_FORMAT, :length => 80,
16
+ :out => @out)
18
17
  end
19
18
  end
20
19
 
@@ -46,5 +45,4 @@ class Starscope::Output
46
45
  @out.puts msg
47
46
  end
48
47
  end
49
-
50
48
  end
@@ -1,10 +1,9 @@
1
1
  require 'starscope/matcher'
2
2
 
3
3
  module Starscope::Queryable
4
-
5
- def query(tables, value, filters={})
4
+ def query(tables, value, filters = {})
6
5
  tables = [tables] if tables.is_a?(Symbol)
7
- tables.each { |t| raise Starscope::DB::NoTableError, "Table '#{t}' not found" unless @tables[t] }
6
+ tables.each { |t| fail Starscope::DB::NoTableError, "Table '#{t}' not found" unless @tables[t] }
8
7
  input = Enumerator.new do |y|
9
8
  tables.each do |t|
10
9
  @tables[t].each do |elem|
@@ -20,9 +19,9 @@ module Starscope::Queryable
20
19
 
21
20
  def run_query(query, input, filters)
22
21
  query = Starscope::Matcher.new(query)
23
- filters.each {|k,v| filters[k] = Starscope::Matcher.new(v)}
22
+ filters.each { |k, v| filters[k] = Starscope::Matcher.new(v) }
24
23
 
25
- results = input.select {|x| filter(x, filters)}.group_by {|x| match(x, query)}
24
+ results = input.select { |x| filter(x, filters) }.group_by { |x| match(x, query) }
26
25
 
27
26
  Starscope::Matcher::MATCH_TYPES.each do |type|
28
27
  next if results[type].nil? || results[type].empty?
@@ -40,7 +39,7 @@ module Starscope::Queryable
40
39
  end
41
40
 
42
41
  def match(record, query)
43
- name = record[:name].map {|x| x.to_s}.join('::')
42
+ name = record[:name].map(&:to_s).join('::')
44
43
 
45
44
  query.match(name)
46
45
  end
@@ -1,3 +1,3 @@
1
1
  module Starscope
2
- VERSION = "1.3.3"
2
+ VERSION = '1.4.0'
3
3
  end
@@ -3,20 +3,20 @@ require File.expand_path('../lib/starscope/version.rb', __FILE__)
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'starscope'
5
5
  gem.version = Starscope::VERSION
6
- gem.summary = "A code indexer and analyzer"
7
- gem.description = "A tool like the venerable cscope, but for ruby, golang and other languages"
8
- gem.authors = ["Evan Huus"]
6
+ gem.summary = 'A code indexer and analyzer'
7
+ gem.description = 'A tool like the venerable cscope, but for ruby, golang and other languages'
8
+ gem.authors = ['Evan Huus']
9
9
  gem.homepage = 'https://github.com/eapache/starscope'
10
10
  gem.email = 'eapache@gmail.com'
11
11
  gem.license = 'MIT'
12
12
  gem.files = `git ls-files`.split("\n")
13
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
14
14
  gem.test_files = `git ls-files -- test/*`.split("\n")
15
- gem.require_paths = ["lib"]
15
+ gem.require_paths = ['lib']
16
16
  gem.required_ruby_version = '>= 1.8.7'
17
17
 
18
18
  gem.add_dependency 'oj', '~> 2.9'
19
- gem.add_dependency 'parser', '~> 2.2.0.3'
19
+ gem.add_dependency 'parser', '~> 2.2.2'
20
20
  gem.add_dependency 'ruby-progressbar', '~> 1.5'
21
21
  gem.add_dependency 'backports', '~> 3.6'
22
22
  gem.add_development_dependency 'bundler', '~> 1.5'
@@ -0,0 +1,15 @@
1
+ 5
2
+ {
3
+ ":paths": [],
4
+ ":excludes": [],
5
+ ":langs": {
6
+ ":NoSuchLanguage": 0
7
+ },
8
+ ":files": {
9
+ "test/fixtures/sample_golang.go": {
10
+ ":last_updated": 10000000000,
11
+ ":lang": ":NoSuchLanguage"
12
+ }
13
+ }
14
+ }
15
+ {}
@@ -0,0 +1,17 @@
1
+ 5
2
+ {
3
+ ":paths": [],
4
+ ":excludes": [],
5
+ ":langs": {
6
+ ":Go": 1234,
7
+ ":Ruby": 0
8
+ },
9
+ ":files": {
10
+ "test/fixtures/sample_golang.go": {
11
+ ":last_updated": 10000000000,
12
+ ":lang": ":Go",
13
+ ":sublangs": [":Ruby"]
14
+ }
15
+ }
16
+ }
17
+ {}
@@ -0,0 +1,14 @@
1
+ <% if foo %>
2
+ malsgkjalsgkjaslfk
3
+ <% elsif bar %>
4
+ lkajlfaksjflaksjf
5
+ <% end %>
6
+
7
+
8
+ <%- case x
9
+ when :bar -%> <%= magic %> <% when :baz
10
+ when :foo %>
11
+ x and :bar
12
+ <% end %>
13
+
14
+ <%= foo %>, <%=== bar -%>, <%= baz %>
@@ -7,7 +7,6 @@ LANGS = [
7
7
  ]
8
8
 
9
9
  class Starscope::DB
10
-
11
10
  PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
12
11
 
13
12
  class NoTableError < StandardError; end
@@ -31,12 +30,12 @@ class Starscope::DB
31
30
  elsif format <= 2
32
31
  # Old format (pre-json), so read the directories segment then rebuild
33
32
  len = stream.gets.to_i
34
- add_paths(Marshal::load(stream.read(len)))
33
+ add_paths(Marshal.load(stream.read(len)))
35
34
  elsif format < DB_FORMAT
36
35
  # Old format, so read the directories segment then rebuild
37
36
  add_paths(Oj.load(stream.gets))
38
37
  elsif format > DB_FORMAT
39
- raise UnknownDBFormatError
38
+ fail UnknownDBFormatError
40
39
  end
41
40
  end
42
41
  end
@@ -57,10 +56,10 @@ class Starscope::DB
57
56
  paths -= @paths
58
57
  return if paths.empty?
59
58
  @paths += paths
60
- files = paths.map {|p| self.class.files_from_path(p)}.flatten
59
+ files = paths.map { |p| self.class.files_from_path(p) }.flatten
61
60
  return if files.empty?
62
61
  if @progress
63
- pbar = ProgressBar.create(:title => "Building", :total => files.length, :format => PBAR_FORMAT, :length => 80)
62
+ pbar = ProgressBar.create(:title => 'Building', :total => files.length, :format => PBAR_FORMAT, :length => 80)
64
63
  end
65
64
  files.each do |f|
66
65
  add_file(f)
@@ -69,9 +68,9 @@ class Starscope::DB
69
68
  end
70
69
 
71
70
  def update
72
- new_files = (@paths.map {|p| self.class.files_from_path(p)}.flatten) - @files.keys
71
+ new_files = (@paths.map { |p| self.class.files_from_path(p) }.flatten) - @files.keys
73
72
  if @progress
74
- pbar = ProgressBar.create(:title => "Updating", :total => new_files.length + @files.length, :format => PBAR_FORMAT, :length => 80)
73
+ pbar = ProgressBar.create(:title => 'Updating', :total => new_files.length + @files.length, :format => PBAR_FORMAT, :length => 80)
75
74
  end
76
75
  changed = @files.keys.map do |f|
77
76
  changed = update_file(f)
@@ -101,13 +100,13 @@ class Starscope::DB
101
100
  if File.file?(path)
102
101
  [path]
103
102
  elsif File.directory?(path)
104
- Dir[File.join(path, "**", "*")].select {|p| File.file?(p)}
103
+ Dir[File.join(path, '**', '*')].select { |p| File.file?(p) }
105
104
  else
106
105
  []
107
106
  end
108
107
  end
109
108
 
110
- def db_by_line()
109
+ def db_by_line
111
110
  tmpdb = {}
112
111
  @tables.each do |tbl, vals|
113
112
  vals.each do |key, val|
@@ -115,21 +114,21 @@ class Starscope::DB
115
114
  if entry[:line_no]
116
115
  tmpdb[entry[:file]] ||= {}
117
116
  tmpdb[entry[:file]][entry[:line_no]] ||= []
118
- tmpdb[entry[:file]][entry[:line_no]] << {:tbl => tbl, :key => key, :entry => entry}
117
+ tmpdb[entry[:file]][entry[:line_no]] << { :tbl => tbl, :key => key, :entry => entry }
119
118
  end
120
119
  end
121
120
  end
122
121
  end
123
- return tmpdb
122
+ tmpdb
124
123
  end
125
124
 
126
125
  def add_file(file)
127
- return if not File.file? file
126
+ return unless File.file? file
128
127
 
129
128
  @files[file] = File.mtime(file).to_s
130
129
 
131
130
  LANGS.each do |lang|
132
- next if not lang.match_file file
131
+ next unless lang.match_file file
133
132
  lang.extract file do |tbl, key, args|
134
133
  key = key.to_sym
135
134
  @tables[tbl] ||= {}
@@ -143,13 +142,13 @@ class Starscope::DB
143
142
  @files.delete(file)
144
143
  @tables.each do |name, tbl|
145
144
  tbl.each do |key, val|
146
- val.delete_if {|dat| dat[:file] == file}
145
+ val.delete_if { |dat| dat[:file] == file }
147
146
  end
148
147
  end
149
148
  end
150
149
 
151
150
  def update_file(file)
152
- if not File.exists?(file) or not File.file?(file)
151
+ if !File.exist?(file) || !File.file?(file)
153
152
  remove_file(file)
154
153
  true
155
154
  elsif DateTime.parse(@files[file]).to_time < File.mtime(file)
@@ -160,5 +159,4 @@ class Starscope::DB
160
159
  false
161
160
  end
162
161
  end
163
-
164
162
  end
@@ -1,38 +1,37 @@
1
1
  require File.expand_path('../../test_helper', __FILE__)
2
2
 
3
- describe "starscope executable script" do
4
-
5
- BASE = "bundle exec bin/starscope --quiet"
3
+ describe 'starscope executable script' do
4
+ BASE = 'bundle exec bin/starscope --quiet'
6
5
  EXTRACT = "#{BASE} --no-read --no-write #{FIXTURES}"
7
6
 
8
- it "must not produce help wider than 80 characters" do
7
+ it 'must not produce help wider than 80 characters' do
9
8
  `#{BASE} -h`.each_line do |line|
10
9
  line.length.must_be :<=, 80
11
10
  end
12
11
  end
13
12
 
14
- it "must produce the right version" do
13
+ it 'must produce the right version' do
15
14
  `#{BASE} -v`.chomp.must_equal Starscope::VERSION
16
15
  end
17
16
 
18
- it "must produce a valid database summary" do
17
+ it 'must produce a valid database summary' do
19
18
  lines = `#{EXTRACT} -s`.lines.to_a
20
19
  lines.length.must_equal 8
21
20
  end
22
21
 
23
- it "must produce a valid database dump" do
22
+ it 'must produce a valid database dump' do
24
23
  lines = `#{EXTRACT} -d requires`.lines.to_a
25
24
  lines[1].split.first.must_equal 'date'
26
25
  lines[2].split.first.must_equal 'zlib'
27
26
  end
28
27
 
29
- it "must correctly query the database" do
28
+ it 'must correctly query the database' do
30
29
  `#{EXTRACT} -q calls,add_file`.each_line do |line|
31
- line.split[0..2].must_equal ["Starscope", "DB", "add_file"]
30
+ line.split[0..2].must_equal %w(Starscope DB add_file)
32
31
  end
33
32
 
34
33
  `#{EXTRACT} -q lang:ruby,calls,add_file`.each_line do |line|
35
- line.split[0..2].must_equal ["Starscope", "DB", "add_file"]
34
+ line.split[0..2].must_equal %w(Starscope DB add_file)
36
35
  end
37
36
 
38
37
  `#{EXTRACT} -q lang:go,calls,add_file`.each_line do |line|
@@ -40,10 +39,10 @@ describe "starscope executable script" do
40
39
  end
41
40
  end
42
41
 
43
- it "must correctly export to cscope" do
42
+ it 'must correctly export to cscope' do
44
43
  file = Tempfile.new('starscope_test')
45
44
  begin
46
- `#{EXTRACT} -e cscope,#{file.path()}`
45
+ `#{EXTRACT} -e cscope,#{file.path}`
47
46
  $?.exitstatus.must_equal 0
48
47
  ensure
49
48
  file.close
@@ -51,15 +50,14 @@ describe "starscope executable script" do
51
50
  end
52
51
  end
53
52
 
54
- it "must correctly export to ctags" do
53
+ it 'must correctly export to ctags' do
55
54
  file = Tempfile.new('starscope_test')
56
55
  begin
57
- `#{EXTRACT} -e ctags,#{file.path()}`
56
+ `#{EXTRACT} -e ctags,#{file.path}`
58
57
  $?.exitstatus.must_equal 0
59
58
  ensure
60
59
  file.close
61
60
  file.unlink
62
61
  end
63
62
  end
64
-
65
63
  end
@@ -3,8 +3,9 @@ require 'minitest/pride'
3
3
  require 'mocha/mini_test'
4
4
  require File.expand_path('../../lib/starscope.rb', __FILE__)
5
5
 
6
- FIXTURES="test/fixtures"
6
+ FIXTURES = 'test/fixtures'
7
7
 
8
8
  GOLANG_SAMPLE = "#{FIXTURES}/sample_golang.go"
9
9
  RUBY_SAMPLE = "#{FIXTURES}/sample_ruby.rb"
10
+ ERB_SAMPLE = "#{FIXTURES}/sample_erb.erb"
10
11
  EMPTY_FILE = "#{FIXTURES}/empty"
@@ -2,18 +2,15 @@ require File.expand_path('../../test_helper', __FILE__)
2
2
  require 'tempfile'
3
3
 
4
4
  describe Starscope::DB do
5
-
6
5
  before do
7
6
  @db = Starscope::DB.new(Starscope::Output.new(:quiet))
8
7
  end
9
8
 
10
- it "must raise on invalid tables" do
11
- proc {
12
- @db.records(:foo)
13
- }.must_raise Starscope::DB::NoTableError
9
+ it 'must raise on invalid tables' do
10
+ proc { @db.records(:foo) }.must_raise Starscope::DB::NoTableError
14
11
  end
15
12
 
16
- it "must add paths" do
13
+ it 'must add paths' do
17
14
  paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
18
15
  @db.add_paths(paths)
19
16
 
@@ -21,7 +18,7 @@ describe Starscope::DB do
21
18
  validate(@db)
22
19
  end
23
20
 
24
- it "must add excludes" do
21
+ it 'must add excludes' do
25
22
  paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
26
23
  @db.add_paths(paths)
27
24
  @db.add_excludes(["#{FIXTURES}/**"])
@@ -33,14 +30,14 @@ describe Starscope::DB do
33
30
  @db.records(:end).must_be_empty
34
31
  end
35
32
 
36
- it "must pick up new files in old paths" do
33
+ it 'must pick up new files in old paths' do
37
34
  @db.load("#{FIXTURES}/db_added_files.json")
38
35
  @db.update
39
36
 
40
37
  validate(@db)
41
38
  end
42
39
 
43
- it "must remove old files in existing paths" do
40
+ it 'must remove old files in existing paths' do
44
41
  @db.load("#{FIXTURES}/db_removed_files.json")
45
42
  @db.update
46
43
  @db.metadata(:files).keys.wont_include "#{FIXTURES}/foo"
@@ -62,7 +59,7 @@ describe Starscope::DB do
62
59
  @db.records(:calls).wont_be_empty
63
60
  end
64
61
 
65
- it "must update unchanged existing files with old extractor versions" do
62
+ it 'must update unchanged existing files with old extractor versions' do
66
63
  @db.load("#{FIXTURES}/db_old_extractor.json")
67
64
 
68
65
  cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
@@ -77,22 +74,53 @@ describe Starscope::DB do
77
74
  @db.records(:calls).wont_be_empty
78
75
  end
79
76
 
80
- it "must not update file with up-to-date time and extractor" do
77
+ it 'must update unchanged existing files with old sublang extractor versions' do
78
+ @db.load("#{FIXTURES}/db_old_subextractor.json")
79
+
80
+ cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
81
+ File.expects(:mtime).twice.returns(cur_mtime)
82
+ @db.update
83
+
84
+ file = @db.metadata(:files)[GOLANG_SAMPLE]
85
+ file[:last_updated].must_equal cur_mtime
86
+ file[:lang].must_equal :Go
87
+ file[:sublangs].must_be_empty
88
+ file[:lines].wont_be_empty
89
+ @db.records(:defs).wont_be_empty
90
+ @db.records(:calls).wont_be_empty
91
+ end
92
+
93
+ it 'must update unchanged existing files when the extractor has been removed' do
94
+ @db.load("#{FIXTURES}/db_missing_language.json")
95
+
96
+ cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
97
+ File.expects(:mtime).twice.returns(cur_mtime)
98
+ @db.update
99
+
100
+ file = @db.metadata(:files)[GOLANG_SAMPLE]
101
+ file[:last_updated].must_equal cur_mtime
102
+ file[:lang].must_equal :Go
103
+ file[:lines].wont_be_empty
104
+ @db.records(:defs).wont_be_empty
105
+ @db.records(:calls).wont_be_empty
106
+ end
107
+
108
+ it 'must not update file with up-to-date time and extractor' do
81
109
  @db.load("#{FIXTURES}/db_up_to_date.json")
82
110
  @db.update
83
111
 
84
112
  file = @db.metadata(:files)[GOLANG_SAMPLE]
85
- file[:last_updated].must_equal 10000000000
113
+ file[:last_updated].must_equal 10_000_000_000
86
114
  @db.tables.must_be_empty
87
115
  end
88
116
 
89
- it "must load an old DB file" do
117
+ it 'must load an old DB file' do
90
118
  @db.load("#{FIXTURES}/db_old.json.gz")
91
119
  @db.metadata(:paths).must_equal ["#{FIXTURES}/**/*"]
92
120
  validate(@db)
93
121
  end
94
122
 
95
- it "must round-trip a database" do
123
+ it 'must round-trip a database' do
96
124
  file = Tempfile.new('starscope_test')
97
125
  begin
98
126
  @db.add_paths([FIXTURES])
@@ -106,34 +134,34 @@ describe Starscope::DB do
106
134
  end
107
135
  end
108
136
 
109
- it "must run queries" do
137
+ it 'must run queries' do
110
138
  @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
139
+ @db.query(:calls, 'abc').must_equal []
140
+ @db.query(:defs, 'xyz').must_equal []
141
+ @db.query(:calls, 'add_file').length.must_equal 3
114
142
  end
115
143
 
116
- it "must run queries on multiple tables" do
144
+ it 'must run queries on multiple tables' do
117
145
  @db.add_paths([FIXTURES])
118
- ret = @db.query([:calls, :defs], "foo")
119
- ret.length.must_equal 1
146
+ ret = @db.query([:calls, :defs], 'foo')
147
+ ret.length.must_equal 3
120
148
  ret.first[:name].last.must_equal :foo
121
149
  end
122
150
 
123
- it "must symbolize compound name" do
124
- rec = Starscope::DB.normalize_record(:foo, ["a", :b], {})
151
+ it 'must symbolize compound name' do
152
+ rec = Starscope::DB.normalize_record(:foo, ['a', :b], {})
125
153
  rec[:name].must_equal [:a, :b]
126
154
  end
127
155
 
128
- it "must symbolize and array-wrap simple name" do
129
- rec = Starscope::DB.normalize_record(:foo, "a", {})
156
+ it 'must symbolize and array-wrap simple name' do
157
+ rec = Starscope::DB.normalize_record(:foo, 'a', {})
130
158
  rec[:name].must_equal [:a]
131
159
  end
132
160
 
133
- it "must store extractor metadata returned from the `extract` call" do
161
+ it 'must store extractor metadata returned from the `extract` call' do
134
162
  extractor = mock('extractor')
135
163
  extractor.expects(:match_file).with(GOLANG_SAMPLE).returns(true)
136
- extractor.expects(:extract).with(GOLANG_SAMPLE).returns({:a => 1})
164
+ extractor.expects(:extract).with(GOLANG_SAMPLE, File.read(GOLANG_SAMPLE)).returns(:a => 1)
137
165
  extractor.expects(:name).returns('Foo')
138
166
  EXTRACTORS.stubs(:each).yields(extractor)
139
167
 
@@ -156,5 +184,4 @@ describe Starscope::DB do
156
184
  db.records(:imports).wont_be_empty
157
185
  db.records(:requires).wont_be_empty
158
186
  end
159
-
160
187
  end