zeiger 0.0.2 → 0.0.3

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: 7ca514e457ea27de32736575f07c6aabcd63e097
4
- data.tar.gz: d01654cdb2af19a41953a1726ddf114fafc3db9e
3
+ metadata.gz: 23b194662e74f40eada24a6f9ce7e25efcaa34ac
4
+ data.tar.gz: 5bb3af605cfc175cd66423aed69186124cd54f6e
5
5
  SHA512:
6
- metadata.gz: 0d61f59cd5a5b1d56dee4555bddc4c3b7573c37ebb6f52aa76a09ce6f80bc7f39b2a04db0d9ac463c6cbc439db8b312ac172ae09d4c5c696853fafeb72690c04
7
- data.tar.gz: 5fa8f50cbefcff8298cc2896ff4053ab81d4bc360eb5f2c3dcd94196b8d97e844a6075630fa1b34d5b589ccd1290688ad25dc98c3417c61d73c21a9bc037904b
6
+ metadata.gz: 510a9d31b51b965f131411e08b682f817dd9f2571ba1dba99020696ed360825ba651933d6619d85fedb72fe393f321a496c3b88a4dc868b1a090db82e913da72
7
+ data.tar.gz: 3a5f35825f6c516d7609623829fdaa248f989a446d739f37ef93a2ca6bdaa42022bf67d8e3868b9a3cb9405b9d8e4b5bd0dca41a3fdae5764083e436ec4a85d2
data/.zeiger.yml CHANGED
@@ -1,9 +1,30 @@
1
1
  search:
2
+ - "app/**/*"
2
3
  - "bin/**/*"
3
4
  - "lib/**/*"
4
5
  ignore:
5
- - .gz$
6
- - .png$
7
- - .gif$
8
- - .zip$
9
- - .jpg$
6
+ - "\\.gz$"
7
+ - "\\.png$"
8
+ - "\\.gif$"
9
+ - "\\.zip$"
10
+ - "\\.jpg$"
11
+ stats:
12
+ code:
13
+ - "bin/.*"
14
+ - "lib/.*\\.rb$"
15
+ test:
16
+ - "spec/.*"
17
+ - "test/.*"
18
+ other:
19
+ - ".*\\.yml$"
20
+ comments:
21
+ "\\.yml$":
22
+ - "^\\s*#"
23
+ "\\.rb$":
24
+ - "^\\s*#"
25
+ "\\.nydp$":
26
+ - "^\\s*;"
27
+ "\\.arc$":
28
+ - "^\\s*;"
29
+ "\\.c$":
30
+ - "^\\s*//"
data/README.md CHANGED
@@ -29,13 +29,13 @@ Zeiger will rescan files in the current directory every ten seconds so the index
29
29
 
30
30
  ## Usage
31
31
 
32
- `zeiger server` runs the server and opens a unix filesystem socket called `zeiger-index` in the current directory.
32
+ `zeiger server` runs the server and opens a unix filesystem socket called `/tmp/zeiger-index`
33
33
 
34
34
  `zeiger search "foo"` writes the query to the socket and displays the result
35
35
 
36
36
  `zeiger files "xed"` asks for the list of filenames corresponding to the argument ("xed"). With no argument, return all filenames. Files are sorted by length of filename. This sounds odd, but works nicely with 'completing-read in emacs: you will find the file you want in fewer keystrokes.
37
37
 
38
- By default, Zeiger searches only in these subdirectories : %w{ app bin config lib spec test }, and excludes filenames matching these patterns: %w{ .gz$ .png$ .jpg$ .pdf$ }.
38
+ By default, Zeiger searches only in these subdirectories : `%w{ app bin config lib spec test }`, and excludes filenames matching these patterns: `%w{ .gz$ .png$ .jpg$ .pdf$ }`.
39
39
 
40
40
  To override, create a file called `.zeiger.yml` in your project root with the following format:
41
41
 
data/bin/zeiger CHANGED
@@ -5,11 +5,13 @@ require 'zeiger'
5
5
 
6
6
  pwd = `pwd`.strip
7
7
  command = $*[0]
8
+ query = $*[1]
8
9
 
9
10
  case command
10
11
  when "server" ; Zeiger::Server.new.run *$*
11
- when "search" ; Zeiger::QueryClient.run pwd, *$*
12
- when "files" ; Zeiger::FileListClient.run pwd, *$*
12
+ when "search" ; Zeiger::Client.new.send({ command: :search, pwd: pwd, search: query })
13
+ when "files" ; Zeiger::Client.new.send({ command: :files , pwd: pwd, files: query })
14
+ when "stats" ; Zeiger::Client.new.send({ command: :stats , pwd: pwd })
13
15
  end
14
16
 
15
17
  # define file groups
@@ -1,8 +1,8 @@
1
1
  module Zeiger
2
- class QueryClient
3
- def self.run pwd, command, q, *args
2
+ class Client
3
+ def send data
4
4
  Socket.unix(SOCKET_NAME) { |sock|
5
- s = YAML.dump({ pwd: pwd, search: q })
5
+ s = YAML.dump(data)
6
6
  sock.write([s.bytesize].pack("I"))
7
7
  sock.write(s)
8
8
 
@@ -2,14 +2,17 @@ require 'set'
2
2
 
3
3
  module Zeiger
4
4
  class FileInfo
5
- attr_accessor :dir, :filename, :ngrams
5
+ attr_accessor :index, :filename, :ngrams, :lines, :stats_group, :comment_regexes, :nc_nb_line_count
6
6
 
7
- def initialize dir, filename
8
- @dir, @filename, @ngrams = dir, filename, Set.new
7
+ def initialize index, filename, stats
8
+ @index, @filename, @ngrams, @lines = index, filename, Set.new, []
9
+ @stats_group = stats.stats_group filename
10
+ @comment_regexes = stats.comment_rules(filename)
11
+ @nc_nb_line_count = 0
9
12
  end
10
13
 
11
14
  def local_filename
12
- @_local_filename ||= filename.gsub(/^#{Regexp.escape dir}\//, "")
15
+ @_local_filename ||= filename.gsub(/^#{Regexp.escape index.dir}\//, "")
13
16
  end
14
17
 
15
18
  def match regex
@@ -19,5 +22,14 @@ module Zeiger
19
22
  def add_ngram ngram
20
23
  @ngrams << ngram
21
24
  end
25
+
26
+ def add_line line
27
+ lines << line
28
+ @nc_nb_line_count += 1 unless line.blank? || (comment_regexes.any? { |regex| line.matches? regex })
29
+ end
30
+
31
+ def summary
32
+ "[#{index.name}] #{stats_group}\t#{nc_nb_line_count}/#{lines.count}\t: #{local_filename}"
33
+ end
22
34
  end
23
35
  end
data/lib/zeiger/index.rb CHANGED
@@ -5,17 +5,30 @@ module Zeiger
5
5
  ROOT_FILES = %w{ .zeiger.yml .git .hg Makefile Rakefile Gemfile build.xml }
6
6
  NGRAM_SIZE = 3
7
7
 
8
- attr_accessor :index, :dir, :includes, :ignore, :files, :monitor
8
+ attr_accessor :index, :dir, :name, :includes, :ignore, :files, :config, :monitor, :stats
9
9
 
10
10
  def initialize dir
11
11
  attrs = File.exist?(".zeiger.yml") ? YAML.load(File.read ".zeiger.yml") : { }
12
12
  self.dir = File.expand_path dir
13
+ self.name = File.basename self.dir
14
+ self.config = load_config
13
15
  self.index = Hash.new { |h, k| h[k] = [] }
14
16
  self.files = Hash.new
15
- self.monitor = Monitor.new dir, self
17
+ self.monitor = Monitor.new dir, self, config
18
+ self.stats = Stats.new self, config
16
19
  rescan
17
20
  end
18
21
 
22
+ def load_config
23
+ conf_file = File.join dir, ".zeiger.yml"
24
+ if File.exist?(conf_file)
25
+ puts "reading config from #{conf_file.inspect}"
26
+ YAML.load(File.read conf_file)
27
+ else
28
+ { }
29
+ end
30
+ end
31
+
19
32
  def self.from_path path
20
33
  raise "no path! #{path.inspect}" if path == nil || path.strip == ''
21
34
  return INDICES[path] if INDICES[path]
@@ -35,20 +48,23 @@ module Zeiger
35
48
  end
36
49
 
37
50
  def add_to_index file
38
- info = files[file] = FileInfo.new(dir, file)
51
+ info = files[file] = FileInfo.new(self, file, stats)
39
52
 
40
53
  File.read(file).split(/\n/).each_with_index { |txt, line|
41
- Line.new(info, line + 1, txt).ngrams(NGRAM_SIZE) do |trig, line|
54
+ line = Line.new(info, line + 1, txt).ngrams(NGRAM_SIZE) do |trig, line|
42
55
  index[trig] << line
43
56
  info.add_ngram trig
44
57
  end
45
58
  }
59
+
60
+ puts "#{info.summary} : re-index"
46
61
  end
47
62
 
48
- def rescan ; monitor.build_index ; end
49
- def get_ngram_lines ngrams ; ngrams.map { |ngram| result = index[ngram] || [] }.reduce(&:&) ; end
50
- def exec_query regex, ngrams ; get_ngram_lines(ngrams).select { |line| line.matches? regex } ; end
51
- def sort_by_filename lines ; lines.sort_by { |line| line.file.local_filename } ; end
63
+ def glob pattern ; Dir.glob(File.join(dir, pattern)) ; end
64
+ def rescan ; monitor.build_index ; end
65
+ def get_ngram_lines ngrams ; ngrams.map { |ngram| result = index[ngram] || [] }.reduce(&:&) ; end
66
+ def exec_query regex, ngrams ; get_ngram_lines(ngrams).select { |line| line.matches? regex } ; end
67
+ def sort_by_filename lines ; lines.sort_by { |line| [line.file.local_filename, line.line_number] } ; end
52
68
 
53
69
  def query txt
54
70
  puts "got query #{txt.inspect}"
data/lib/zeiger/line.rb CHANGED
@@ -6,12 +6,14 @@ module Zeiger
6
6
  def initialize file, line_number, content
7
7
  @file, @line_number, @content = file, line_number, content
8
8
  @hash = "#{file.filename}##{line_number}".hash
9
+ file.add_line self
9
10
  end
10
11
 
11
12
  def to_s ; "#{file.local_filename}:#{line_number}:#{content}" ; end
12
- def matches? regex ; content.match regex ; end
13
+ def blank? ; content.strip == '' ; end
14
+ def matches? regex ; content.match regex ; end
13
15
  def ngram_list size ; @ngrams ||= content.ngrams(size) ; end
14
- def ngrams size ; ngram_list(size).each { |ngram| yield ngram, self } ; end
15
- def == other ; self.file == other.file && self.line_number == other.line_number ; end
16
+ def ngrams size ; ngram_list(size).each { |ngram| yield ngram, self } ; end
17
+ def == other ; self.file == other.file && self.line_number == other.line_number ; end
16
18
  end
17
19
  end
@@ -2,23 +2,12 @@ module Zeiger
2
2
  class Monitor
3
3
  attr_accessor :dir, :index, :stat, :includes, :ignore
4
4
 
5
- def initialize dir, index
5
+ def initialize dir, index, attrs
6
6
  @dir, @index, @stat = dir, index, Hash.new
7
- attrs = load_config
8
7
  @includes = attrs["search"] || %w{ app/**/* bin/**/* config/**/* lib/**/* spec/**/* test/**/* }
9
8
  @ignore = attrs["ignore"] || %w{ .gz$ .png$ .jpg$ .pdf$ }
10
9
  end
11
10
 
12
- def load_config
13
- conf_file = File.join dir, ".zeiger.yml"
14
- if File.exist?(conf_file)
15
- puts "reading config from #{conf_file.inspect}"
16
- YAML.load(File.read conf_file)
17
- else
18
- { }
19
- end
20
- end
21
-
22
11
  def ignore? filename
23
12
  ignore.any? { |ig| filename.match ig }
24
13
  end
@@ -31,12 +20,11 @@ module Zeiger
31
20
  started = Time.now
32
21
  files = Set.new
33
22
  includes.each do |inc|
34
- Dir.glob(File.join(dir, inc)).sort.each do |file|
23
+ index.glob(inc).sort.each do |file|
35
24
  if File.file?(file) && !ignore?(file)
36
25
  files << file
37
26
  mtime = File.stat(file).mtime
38
27
  if !uptodate?(file, mtime)
39
- puts "re-indexing #{file}"
40
28
  index.remove_from_index file
41
29
  index.add_to_index file
42
30
  stat[file] = mtime
@@ -44,7 +32,13 @@ module Zeiger
44
32
  end
45
33
  end
46
34
  end
47
- (Set.new(stat.keys) - files).each { |f| index.remove_from_index f }
35
+ (Set.new(stat.keys) - files).each { |f|
36
+ info = index.files[f]
37
+ index.remove_from_index f
38
+ stat.delete f
39
+ help = info ? info.summary : "[#{index.name}] #{f}"
40
+ puts "#{help} : deleted"
41
+ }
48
42
  finished = Time.now
49
43
  puts "ngrams : #{index.index.length}"
50
44
  puts "files : #{index.files.length}"
data/lib/zeiger/server.rb CHANGED
@@ -10,7 +10,7 @@ module Zeiger
10
10
  while true do
11
11
  indices = Zeiger::INDICES.values
12
12
  indices.each do |index|
13
- puts "scanning #{index.dir}"
13
+ puts "scanning #{index.name} at #{index.dir}"
14
14
  index.rescan
15
15
  end
16
16
  sleep 10
@@ -22,7 +22,6 @@ module Zeiger
22
22
  end
23
23
 
24
24
  Socket.unix_server_loop(SOCKET_NAME) { |sock, client|
25
- puts "query thread: server loop"
26
25
  begin
27
26
  length = sock.read(4).unpack("I")[0]
28
27
  query = sock.read(length)
@@ -30,11 +29,14 @@ module Zeiger
30
29
  puts incoming.to_yaml
31
30
 
32
31
  index = Index.from_path incoming[:pwd]
33
- puts "querying index at #{index.dir}"
32
+ puts "querying index #{index.name}"
34
33
 
35
- if incoming[:search]
34
+ case incoming[:command]
35
+ when :search
36
36
  index.query(incoming[:search]).each { |res| sock.puts res.to_s }
37
- elsif incoming.key? :files
37
+ when :stats
38
+ sock.puts index.stats.stats.to_yaml
39
+ when :files
38
40
  index.file_list(incoming[:files]).each { |f| sock.puts f.local_filename }
39
41
  end
40
42
 
@@ -0,0 +1,33 @@
1
+ module Zeiger
2
+ class Stats
3
+ attr_accessor :index, :group_cfg, :comment_cfg
4
+
5
+ def initialize index, config
6
+ @index = index
7
+ @group_cfg = config["stats"]
8
+ @comment_cfg = compile_comment_cfg config["comments"]
9
+ end
10
+
11
+ def compile_comment_cfg cfg
12
+ (cfg || { }).each_with_object({ }) do |(file_pattern, regex_list), result|
13
+ result[Regexp.compile(file_pattern)] = regex_list.map { |r| Regexp.compile r }
14
+ end
15
+ end
16
+
17
+ def stats_group filename
18
+ (group_cfg || []).each { |group, regexes| return group if regexes.any? { |r| filename.match r } }
19
+ "undefined"
20
+ end
21
+
22
+ def comment_rules filename
23
+ file_type = comment_cfg.keys.detect { |rxp| filename.match rxp }
24
+ comment_cfg[file_type] || []
25
+ end
26
+
27
+ def stats
28
+ index.files.values.each_with_object(Hash.new { |h,k| h[k] = 0 }) do |file, results|
29
+ results[file.stats_group] += file.nc_nb_line_count
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Zeiger
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/zeiger.rb CHANGED
@@ -1,25 +1,22 @@
1
1
  require "set"
2
2
  require 'yaml'
3
- require 'zeiger/query_client'
4
- require 'zeiger/file_list_client'
3
+ require 'zeiger/client'
5
4
  require 'zeiger/server'
6
5
  require "zeiger/version"
7
6
  require 'zeiger/monitor'
7
+ require 'zeiger/stats'
8
8
  require 'zeiger/file_info'
9
9
  require 'zeiger/index'
10
10
  require 'zeiger/line'
11
11
 
12
12
  class String
13
13
  def ngrams size
14
- padding = " " * (size - 1)
15
- txt = self
16
- ngrams = Hash.new { |h,k| h[k] = 0 }
17
- regex = Regexp.compile("." * size)
14
+ s = size - 1
18
15
 
19
16
  result = []
20
17
 
21
- (txt.length - 2).times do |i|
22
- result << txt[i..(i + 2)]
18
+ (length - s).times do |i|
19
+ result << self[i..(i + s)]
23
20
  end
24
21
 
25
22
  result
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zeiger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - conanite
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-23 00:00:00.000000000 Z
11
+ date: 2017-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -55,13 +55,13 @@ files:
55
55
  - Rakefile
56
56
  - bin/zeiger
57
57
  - lib/zeiger.rb
58
+ - lib/zeiger/client.rb
58
59
  - lib/zeiger/file_info.rb
59
- - lib/zeiger/file_list_client.rb
60
60
  - lib/zeiger/index.rb
61
61
  - lib/zeiger/line.rb
62
62
  - lib/zeiger/monitor.rb
63
- - lib/zeiger/query_client.rb
64
63
  - lib/zeiger/server.rb
64
+ - lib/zeiger/stats.rb
65
65
  - lib/zeiger/version.rb
66
66
  - zeiger.gemspec
67
67
  homepage: https://github.com/conanite/zeiger
@@ -1,15 +0,0 @@
1
- module Zeiger
2
- class FileListClient
3
- def self.run pwd, command, q=nil, *args
4
- Socket.unix(SOCKET_NAME) { |sock|
5
- s = YAML.dump({ pwd: pwd, files: q })
6
- sock.write([s.bytesize].pack("I"))
7
- sock.write(s)
8
-
9
- while !sock.eof?
10
- puts sock.readline
11
- end
12
- }
13
- end
14
- end
15
- end