starscope 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf0545d7e2a35d02175c24c5ad16941d6fa61237
4
- data.tar.gz: ff40e8a9c02faa7fc77d48c83b99b2fbc3e1ec2c
3
+ metadata.gz: da191b58f08b524eb31cda50bf5194e3b691e4e4
4
+ data.tar.gz: eaa0415c40b4428a741d162b6ce632b8a985a07d
5
5
  SHA512:
6
- metadata.gz: e77b085891ca912792487ef07a6aeaaabc7ec5a94193879b62877f1729c2f205265d30c2eee3f12ba2272b69181f68025e55ed84767b12b506fc448aea83c9c8
7
- data.tar.gz: bf3c86d110ec7c87e2d0393b3e06f8e87b4bf62ba860a4183c857d8ad082a3a047acccdf5d9453000a8762f7b404d59cbdbe766837c66ab5e41c527827396142
6
+ metadata.gz: ee659c9708a121d3c26dfc5a733fa90960bc71c6bbd5e19e47cc14278e45dbab63e7cc35a4b827b12db78b83be0f0951fef6015d5983dfa58ba450d29f4a5cc4
7
+ data.tar.gz: 73a5d16b4a4a21d8b4d4e2dc1eff507fb439445294868d809f76963e7264575c0a9a94b67a15ad9fb181ce63d590b7f86c5cf5b69583e21b698765945fcac2fb
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .starscope.db
4
4
  .bundle
5
5
  .config
6
+ Gemfile.lock
6
7
  coverage
7
8
  InstalledFiles
8
9
  lib/bundler/man
@@ -34,9 +34,6 @@ Style/ClassAndModuleChildren:
34
34
  Style/Documentation:
35
35
  Enabled: false
36
36
 
37
- Style/HashSyntax:
38
- EnforcedStyle: hash_rockets
39
-
40
37
  Style/Next:
41
38
  Exclude:
42
39
  - 'test/fixtures/sample_ruby.rb'
@@ -2,7 +2,6 @@ language: ruby
2
2
  sudo: false
3
3
 
4
4
  rvm:
5
- - 1.8.7
6
5
  - 1.9.3
7
6
  - 2.0
8
7
  - 2.1
@@ -1,7 +1,23 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- v1.4.1 (trunk)
4
+ v1.5.0 (trunk)
5
+ --------------------
6
+
7
+ New Features:
8
+ * Javascript support, including basic ES6/ES7 and JSX (via Babel).
9
+ * Implemented `--force-update` flag to rescan all files even if they apparently
10
+ haven't changed (#139).
11
+ * Added support for a shared configuration file in `~/starscope.json` (#140).
12
+ This is primarily useful for commonly excluded files (e.g. `cscope.out`).
13
+
14
+ Bug Fixes:
15
+ * Fixed a really weird corruption in certain rare cscope export cases (#129).
16
+
17
+ Misc:
18
+ * Drop support for ruby 1.8.7, it was getting annoying and is long unsupported.
19
+
20
+ v1.4.1 (2015-09-12)
5
21
  --------------------
6
22
 
7
23
  Misc:
data/README.md CHANGED
@@ -6,9 +6,9 @@ Starscope
6
6
  [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html)
7
7
 
8
8
  Starscope is a code indexer, search and navigation tool for
9
- [Ruby](https://www.ruby-lang.org/) and [Golang](https://golang.org/), with a
10
- design intended to make it easy to add
11
- [support for other languages](doc/LANGUAGE_SUPPORT.md).
9
+ [Ruby](https://www.ruby-lang.org/), [Golang](https://golang.org/), and
10
+ [JavaScript](https://en.wikipedia.org/wiki/JavaScript) with a design intended
11
+ to make it easy to add [support for other languages](doc/LANGUAGE_SUPPORT.md).
12
12
 
13
13
  Inspired by the extremely popular [Ctags](https://en.wikipedia.org/wiki/Ctags)
14
14
  and [Cscope](http://cscope.sourceforge.net/) utilities, Starscope can answer a
@@ -19,9 +19,9 @@ lot of questions about your code. It can tell you:
19
19
  - where symbols are used
20
20
  - where files and libraries are imported or required
21
21
 
22
- While Ctags already supports Ruby and Go, it can only tell you where things are
23
- defined. Cscope can answer a lot more of your questions, but it is limited to
24
- just the C language family. Starscope was written to combine the power of
22
+ While Ctags already supports many languages, it can only tell you where things
23
+ are defined. Cscope can answer a lot more of your questions, but it is limited
24
+ to just the C language family. Starscope was written to combine the power of
25
25
  Cscope with the flexibility of Ctags, bringing full code indexing to as many
26
26
  developers as possible.
27
27
 
data/Rakefile CHANGED
@@ -6,4 +6,4 @@ Rake::TestTask.new do |t|
6
6
  end
7
7
 
8
8
  desc 'Run tests'
9
- task :default => :test
9
+ task default: :test
@@ -3,18 +3,21 @@
3
3
  lib = File.expand_path('../../lib', __FILE__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
+ require 'oj'
6
7
  require 'optparse'
7
8
  require 'readline'
8
9
  require 'starscope'
9
10
 
10
11
  DEFAULT_DB = '.starscope.db'
11
-
12
- options = { :read => true,
13
- :write => true,
14
- :update => true,
15
- :output => :normal,
16
- :export => [],
17
- :db => DEFAULT_DB
12
+ CONFIG_FILE = File.join(Dir.home, '.starscope.json')
13
+ GLOBAL_CONFIG = File.exist?(CONFIG_FILE) ? Oj.load_file(CONFIG_FILE, symbol_keys: true) : {}
14
+
15
+ options = { read: true,
16
+ write: true,
17
+ update: true,
18
+ output: :normal,
19
+ export: [],
20
+ db: DEFAULT_DB
18
21
  }
19
22
 
20
23
  # Options Parsing
@@ -68,6 +71,9 @@ END
68
71
  opts.on('--no-update', "Don't update the DB") do
69
72
  options[:update] = false
70
73
  end
74
+ opts.on('--force-update', 'Rebuild the DB by rescanning all files') do
75
+ options[:forceUpdate] = true
76
+ end
71
77
 
72
78
  opts.separator "\nMisc"
73
79
  opts.on('-v', '--version', 'Print the version number') do
@@ -100,7 +106,7 @@ end.parse!
100
106
  def print_summary(db)
101
107
  tables = db.tables
102
108
  puts 'No tables' if tables.empty?
103
- tables.sort { |a, b| a.to_s <=> b.to_s }.each do |table|
109
+ tables.sort.each do |table|
104
110
  printf("%-9s %6d records\n", table, db.records(table).length)
105
111
  end
106
112
  end
@@ -186,7 +192,7 @@ rescue Starscope::Exportable::UnknownExportFormatError
186
192
  end
187
193
 
188
194
  output = Starscope::Output.new(options[:output])
189
- db = Starscope::DB.new(output)
195
+ db = Starscope::DB.new(output, GLOBAL_CONFIG)
190
196
 
191
197
  db_exists = File.exist?(options[:db])
192
198
 
@@ -203,6 +209,11 @@ if options[:exclude]
203
209
  new_data = true
204
210
  end
205
211
 
212
+ if options[:forceUpdate]
213
+ db.drop_all
214
+ options[:update] = true
215
+ end
216
+
206
217
  if !ARGV.empty?
207
218
  # paths specified, add them
208
219
  db.add_paths(ARGV)
@@ -6,6 +6,8 @@ Already Supported
6
6
 
7
7
  * [Ruby](https://www.ruby-lang.org/)
8
8
  * [Golang](https://golang.org/)
9
+ * [JavaScript](https://en.wikipedia.org/wiki/JavaScript)
10
+ (including ES6/ES7 and JSX via [Babel](https://babeljs.io/))
9
11
 
10
12
  How to Add Another Language
11
13
  ---------------------------
@@ -19,10 +19,11 @@ Anyone who has done much programming in C (or C++) on a Unix-based OS has come
19
19
  across the fantastic [Cscope](http://cscope.sourceforge.net/) tool. Sadly, it
20
20
  only works for C (and sort of works for C++).
21
21
 
22
- Starscope is a similar tool for [Ruby](https://www.ruby-lang.org/) and
23
- [Golang](https://golang.org/), with a design intended to make it easy to add
24
- [support for other languages](LANGUAGE_SUPPORT.md) within the same framework
25
- (thus the name Starscope, i.e. \*scope).
22
+ Starscope is a similar tool for [Ruby](https://www.ruby-lang.org/),
23
+ [Golang](https://golang.org/), and
24
+ [JavaScript](https://en.wikipedia.org/wiki/JavaScript), with a design intended
25
+ to make it easy to add [support for other languages](LANGUAGE_SUPPORT.md)
26
+ within the same framework (thus the name Starscope, i.e. \*scope).
26
27
 
27
28
  Installation
28
29
  ------------
@@ -79,7 +80,9 @@ to use another file, specify one with `-f` or `--file`.
79
80
 
80
81
  The default behaviour is always to read the database (if it exists), update it,
81
82
  and write out the updated version. You can control this behaviour by passing any
82
- of the `--no-read`, `--no-write` and `--no-update` flags.
83
+ of the `--no-read`, `--no-write` and `--no-update` flags. If you pass the
84
+ `--force-update` flag then all files and directories will be re-scanned, not
85
+ just the ones that have changed.
83
86
 
84
87
  To get a summary of the current database contents, pass the `-s` or `--summary`
85
88
  flag.
@@ -106,6 +109,15 @@ Excluded patterns are also remembered, and can be added at any time. If an
106
109
  existing file in the database matches a newly added exclusion rule, it will be
107
110
  removed.
108
111
 
112
+ For commonly excluded files you can create a `~/.starscope.json` file with
113
+ contents like:
114
+ ```json
115
+ {
116
+ "excludes": ["foo", "bar"]
117
+ }
118
+ ```
119
+ Patterns listed there will be excluded from all starscope databases by default.
120
+
109
121
  Queries
110
122
  -------
111
123
 
@@ -1,4 +1,3 @@
1
- require 'backports'
2
1
  require 'date'
3
2
  require 'oj'
4
3
  require 'set'
@@ -31,11 +30,12 @@ class Starscope::DB
31
30
  class NoTableError < StandardError; end
32
31
  class UnknownDBFormatError < StandardError; end
33
32
 
34
- def initialize(output)
33
+ def initialize(output, config = {})
35
34
  @output = output
36
- @meta = { :paths => [], :files => {}, :excludes => [],
37
- :langs => LANGS, :version => Starscope::VERSION }
35
+ @meta = { paths: [], files: {}, excludes: [],
36
+ langs: LANGS, version: Starscope::VERSION }
38
37
  @tables = {}
38
+ @config = config
39
39
  end
40
40
 
41
41
  # returns true iff the database was already in the most recent format
@@ -69,6 +69,7 @@ class Starscope::DB
69
69
  paths = paths.map { |p| self.class.normalize_fnmatch(p) }
70
70
  @meta[:excludes] += paths
71
71
  @meta[:excludes].uniq!
72
+ @all_excludes = nil # clear cache
72
73
 
73
74
  excluded = @meta[:files].keys.select { |name| matches_exclude?(name, paths) }
74
75
  remove_files(excluded)
@@ -77,6 +78,7 @@ class Starscope::DB
77
78
  def add_paths(paths)
78
79
  @output.extra("Adding files in paths #{paths}...")
79
80
  @meta[:excludes] -= paths.map { |p| self.class.normalize_fnmatch(p) }
81
+ @all_excludes = nil # clear cache
80
82
  paths = paths.map { |p| self.class.normalize_glob(p) }
81
83
  @meta[:paths] += paths
82
84
  @meta[:paths].uniq!
@@ -136,6 +138,11 @@ class Starscope::DB
136
138
  @meta[key]
137
139
  end
138
140
 
141
+ def drop_all
142
+ @meta[:files] = {}
143
+ @tables = {}
144
+ end
145
+
139
146
  private
140
147
 
141
148
  def open_db(filename)
@@ -209,7 +216,11 @@ class Starscope::DB
209
216
  end
210
217
  end
211
218
 
212
- def matches_exclude?(file, patterns = @meta[:excludes])
219
+ def all_excludes
220
+ @all_excludes ||= @meta[:excludes] + (@config[:excludes] || []).map { |x| self.class.normalize_fnmatch(x) }
221
+ end
222
+
223
+ def matches_exclude?(file, patterns = all_excludes)
213
224
  patterns.map { |p| File.fnmatch(p, file) }.any?
214
225
  end
215
226
 
@@ -238,7 +249,7 @@ class Starscope::DB
238
249
  end
239
250
 
240
251
  def parse_file(file)
241
- @meta[:files][file] = { :last_updated => File.mtime(file).to_i }
252
+ @meta[:files][file] = { last_updated: File.mtime(file).to_i }
242
253
 
243
254
  EXTRACTORS.each do |extractor|
244
255
  begin
@@ -295,7 +306,7 @@ class Starscope::DB
295
306
 
296
307
  def file_changed(name)
297
308
  file_meta = @meta[:files][name]
298
- if !File.exist?(name) || !File.file?(name)
309
+ if matches_exclude?(name) || !File.exist?(name) || !File.file?(name)
299
310
  :deleted
300
311
  elsif (file_meta[:last_updated] < File.mtime(name).to_i) ||
301
312
  language_out_of_date(file_meta[:lang]) ||
@@ -228,15 +228,16 @@ END
228
228
  def valid_index?(line, index, key)
229
229
  # index is valid if the key exists at it, and the prev/next chars are not word characters
230
230
  ((line[index, key.length] == key) &&
231
- (index == 0 || line[index - 1] !~ /\w/) &&
232
- (index + key.length == line.length || line[index + key.length] !~ /\w/))
231
+ (index == 0 || line[index - 1] !~ /[[:word:]]/) &&
232
+ (index + key.length == line.length || line[index + key.length] !~ /[[:word:]]/))
233
233
  end
234
234
 
235
235
  def cscope_plaintext(line, start, stop)
236
236
  ret = line.slice(start, stop - start)
237
237
  ret.lstrip! if start == 0
238
238
  ret.rstrip! if stop == line.length
239
- ret.gsub(/\s+/, ' ')
239
+ ret.gsub!(/\s+/, ' ')
240
+ ret.empty? ? ' ' : ret
240
241
  rescue ArgumentError
241
242
  # invalid utf-8 byte sequence in the line, oh well
242
243
  line
@@ -18,18 +18,18 @@ module Starscope::Lang
18
18
  if multiline
19
19
  term = line.index(ERB_END)
20
20
  if term
21
- yield FRAGMENT, :Ruby, :frag => line[0...term], :line_no => line_no
21
+ yield FRAGMENT, :Ruby, frag: line[0...term], line_no: line_no
22
22
  line = line[term + 1..-1]
23
23
  multiline = false
24
24
  else
25
- yield FRAGMENT, :Ruby, :frag => line, :line_no => line_no
25
+ yield FRAGMENT, :Ruby, frag: line, line_no: line_no
26
26
  end
27
27
  end
28
28
 
29
29
  next if multiline
30
30
 
31
31
  line.scan(/#{ERB_START}(.*?)#{ERB_END}/) do |match|
32
- yield FRAGMENT, :Ruby, :frag => match[0], :line_no => line_no
32
+ yield FRAGMENT, :Ruby, frag: match[0], line_no: line_no
33
33
  end
34
34
 
35
35
  line.gsub!(/<%.*?%>/, '')
@@ -37,7 +37,7 @@ module Starscope::Lang
37
37
  match = /#{ERB_START}(.*)$/.match(line)
38
38
  next unless match
39
39
 
40
- yield FRAGMENT, :Ruby, :frag => match[1], :line_no => line_no
40
+ yield FRAGMENT, :Ruby, frag: match[1], line_no: line_no
41
41
  multiline = true
42
42
  end
43
43
  end
@@ -41,10 +41,10 @@ module Starscope::Lang
41
41
  if stack[-1] != :import && !line.start_with?('import')
42
42
  # strip string literals like "foo" unless they're part of an import
43
43
  pos = 0
44
- while (match = STRING_LITERAL.match(line[pos..-1]))
44
+ while (match = STRING_LITERAL.match(line, pos))
45
45
  eos = find_end_of_string(line, match.begin(0))
46
46
  line = line[0..match.begin(0)] + line[eos..-1]
47
- pos += match.begin(0) + 2
47
+ pos = match.begin(0) + 2
48
48
  end
49
49
  end
50
50
 
@@ -62,7 +62,7 @@ module Starscope::Lang
62
62
  when END_OF_BLOCK
63
63
  end_block(line_no, scope, stack, &block)
64
64
  when /(\w+)\(.*\)\s+/
65
- yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
65
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
66
66
  end
67
67
  when :def
68
68
  case line
@@ -80,12 +80,12 @@ module Starscope::Lang
80
80
  stack.pop
81
81
  when /"(.+)"/
82
82
  name = Regexp.last_match(1).split('/')
83
- yield :imports, name, :line_no => line_no
83
+ yield :imports, name, line_no: line_no
84
84
  end
85
85
  when :func
86
86
  case line
87
87
  when /^\}/
88
- yield :end, '}', :line_no => line_no, :type => :func
88
+ yield :end, '}', line_no: line_no, type: :func
89
89
  stack.pop
90
90
  else
91
91
  parse_new_line(line, line_no, scope, stack, &block)
@@ -104,38 +104,38 @@ module Starscope::Lang
104
104
  def self.parse_new_line(line, line_no, scope, stack, &block)
105
105
  case line
106
106
  when /^func\s+(\w+)\(/
107
- yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no, :type => :func
107
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :func
108
108
  stack.push(:func)
109
109
  when /^func\s+\(\w+\s+\*?(\w+)\)\s*(\w+)\(/
110
- yield :defs, scope + [Regexp.last_match(1), Regexp.last_match(2)], :line_no => line_no, :type => :func
110
+ yield :defs, scope + [Regexp.last_match(1), Regexp.last_match(2)], line_no: line_no, type: :func
111
111
  stack.push(:func)
112
112
  when /^package\s+(\w+)/
113
113
  scope.push(Regexp.last_match(1))
114
- yield :defs, scope, :line_no => line_no, :type => :package
114
+ yield :defs, scope, line_no: line_no, type: :package
115
115
  when /^type\s+(\w+)\s+struct\s*\{/
116
116
  scope.push(Regexp.last_match(1))
117
117
  stack.push(:struct)
118
- yield :defs, scope, :line_no => line_no, :type => :class
118
+ yield :defs, scope, line_no: line_no, type: :class
119
119
  when /^type\s+(\w+)\s+interface\s*\{/
120
120
  scope.push(Regexp.last_match(1))
121
121
  stack.push(:interface)
122
- yield :defs, scope, :line_no => line_no, :type => :class
122
+ yield :defs, scope, line_no: line_no, type: :class
123
123
  when /^type\s+(\w+)/
124
- yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no, :type => :type
124
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :type
125
125
  when /^import\s+"(.+)"/
126
126
  name = Regexp.last_match(1).split('/')
127
- yield :imports, name, :line_no => line_no
127
+ yield :imports, name, line_no: line_no
128
128
  when /^import\s+\(/
129
129
  stack.push(:import)
130
130
  when /^var\s+\(/
131
131
  stack.push(:def)
132
132
  when /^var\s+(\w+)\s/
133
- yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
133
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
134
134
  parse_call(line, line_no, scope, &block)
135
135
  when /^const\s+\(/
136
136
  stack.push(:def)
137
137
  when /^const\s+(\w+)\s/
138
- yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
138
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
139
139
  parse_call(line, line_no, scope, &block)
140
140
  when /^\s+(.*?) :?=[^=]/
141
141
  Regexp.last_match(1).split(' ').each do |var|
@@ -143,9 +143,9 @@ module Starscope::Lang
143
143
  name = var.delete(',').split('.')
144
144
  next if name[0] == '_' # assigning to _ is a discard in golang
145
145
  if name.length == 1
146
- yield :assigns, scope + [name[0]], :line_no => line_no
146
+ yield :assigns, scope + [name[0]], line_no: line_no
147
147
  else
148
- yield :assigns, name, :line_no => line_no
148
+ yield :assigns, name, line_no: line_no
149
149
  end
150
150
  end
151
151
  parse_call(line, line_no, scope, &block)
@@ -160,12 +160,12 @@ module Starscope::Lang
160
160
  if name.length == 1
161
161
  next if name[0] == 'func'
162
162
  if BUILTIN_FUNCS.include?(name[0])
163
- yield :calls, name[0], :line_no => line_no
163
+ yield :calls, name[0], line_no: line_no
164
164
  else
165
- yield :calls, scope + [name[0]], :line_no => line_no
165
+ yield :calls, scope + [name[0]], line_no: line_no
166
166
  end
167
167
  else
168
- yield :calls, name, :line_no => line_no
168
+ yield :calls, name, line_no: line_no
169
169
  end
170
170
  end
171
171
  end
@@ -176,13 +176,13 @@ module Starscope::Lang
176
176
  return unless line =~ /^\s*[[:alpha:]_]/
177
177
 
178
178
  line.split.each do |var|
179
- yield :defs, scope + [var.delete(',')], :line_no => line_no
179
+ yield :defs, scope + [var.delete(',')], line_no: line_no
180
180
  break unless var.end_with?(',')
181
181
  end
182
182
  end
183
183
 
184
184
  def self.end_block(line_no, scope, stack)
185
- yield :end, scope + ['}'], :line_no => line_no, :type => :class
185
+ yield :end, scope + ['}'], line_no: line_no, type: :class
186
186
  stack.pop
187
187
  scope.pop
188
188
  end
@@ -192,9 +192,9 @@ module Starscope::Lang
192
192
  (start + 1...line.length).each do |i|
193
193
  if escape
194
194
  escape = false
195
- elsif line[i].chr == '\\'
195
+ elsif line[i] == '\\'
196
196
  escape = true
197
- elsif line[i].chr == '"'
197
+ elsif line[i] == '"'
198
198
  return i
199
199
  end
200
200
  end