rgr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4b6902568d4e4f4c69e9d5e5cbef2a254f5d82c9
4
+ data.tar.gz: 20ad9a28fd50452d9b5b8cd455d26311df93a77d
5
+ SHA512:
6
+ metadata.gz: 19ded3ab4811baeb36e2b0667f21d90f28d2c4a27e690e3abc9390bd93c375735ebf389543fc4dc2eb411ceaabdd40b6d78e606fd46720eabf4010d9ed91cd8e
7
+ data.tar.gz: 27744f5225974a0a8ce71c55571d954e6c1fc9d93a4fa0af4dd2ff7f9840c8be4d16b4931fd043964fc3ed222627237082afc12e3a674d94059197162af3d01f
data/bin/rgr ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require "rgr"
3
+
4
+ search_query = ARGV.shift or abort "Usage: rgr <search_query> <files...>"
5
+
6
+ reporter = Rgr.reporter.new
7
+
8
+ files =
9
+ if ARGV.any?
10
+ ARGV
11
+ else
12
+ Dir["**/*.rb"]
13
+ end
14
+
15
+ Rgr.search(search_query, files).each do |file, matches|
16
+ reporter.report_file_matches(file, matches)
17
+ end
@@ -0,0 +1,32 @@
1
+ require "coderay"
2
+
3
+ module Rgr
4
+ class ColouredReporter
5
+ attr_reader :output
6
+
7
+ def initialize(output = $stdout)
8
+ @output = output
9
+ end
10
+
11
+ def report_file_matches(file, matches)
12
+ output.puts "\e[32;1m#{file}\e[0m"
13
+
14
+ line_number_places = line_number_places(matches)
15
+
16
+ matches.each do |match|
17
+ expr = match.expression
18
+ highlighted_source = highlight_source(expr.source)
19
+ printf "\e[33;1m%#{line_number_places}d\e[0m: %s\n", expr.line, highlighted_source
20
+ end
21
+ end
22
+
23
+ def line_number_places(matches)
24
+ highest_line_number = matches.map { |match| match.expression.line }.max
25
+ highest_line_number.to_s.length
26
+ end
27
+
28
+ def highlight_source(source)
29
+ CodeRay.scan(source, :ruby).terminal
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ module Rgr
2
+ class PlainReporter
3
+ attr_reader :output
4
+
5
+ def initialize(output = $stdout)
6
+ @output = output
7
+ end
8
+
9
+ def report_file_matches(file, matches)
10
+ matches.each do |match|
11
+ puts "#{match.expression}: #{match.expression.source}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ require "parser"
2
+ require "parser/current"
3
+
4
+ module Rgr
5
+ class Searcher
6
+ attr_reader :search_ast
7
+
8
+ def initialize(search)
9
+ @search_ast = parser_class.parse(search)
10
+ end
11
+
12
+ def search_file(file)
13
+ if ast = parse_file(file)
14
+ search_node_rec(ast, search_ast)
15
+ else
16
+ []
17
+ end
18
+ end
19
+
20
+ private
21
+ def parse_file(file)
22
+ parser.parse(Parser::Source::Buffer.new(file).read)
23
+ rescue => e
24
+ $stderr.puts "Error parsing `#{file}':"
25
+ $stderr.puts e.message
26
+ end
27
+
28
+ def parser_class
29
+ Parser::CurrentRuby
30
+ end
31
+
32
+ def parser
33
+ @parser ||= parser_class.new
34
+ @parser.reset
35
+ @parser
36
+ end
37
+
38
+ def search_node_rec(node, search, results = [])
39
+ node.to_a.grep(Parser::AST::Node).each do |child|
40
+ search_node_rec(child, search, results)
41
+ end
42
+
43
+ if match?(node, search)
44
+ results << node.loc
45
+ end
46
+
47
+ results
48
+ end
49
+
50
+ def match?(node, search)
51
+ return true if wildcard?(search)
52
+
53
+ if node.type == search.type
54
+ node.to_a.zip(search.to_a).all? { |n, s|
55
+ if n.is_a?(Parser::AST::Node) && s.is_a?(Parser::AST::Node)
56
+ match?(n, s)
57
+ else
58
+ n == s
59
+ end
60
+ }
61
+ end
62
+ end
63
+
64
+ def wildcard?(search_node)
65
+ search_node.type == :send && search_node.to_a == [nil, :_]
66
+ end
67
+ end
68
+ end
data/lib/rgr.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "rgr/searcher"
2
+ require "rgr/coloured_reporter"
3
+ require "rgr/plain_reporter"
4
+
5
+ module Rgr
6
+ def self.search(search_term, files)
7
+ searcher = Searcher.new(search_term)
8
+
9
+ files.lazy.map { |file|
10
+ [file, searcher.search_file(file)]
11
+ }.select { |file, matches|
12
+ matches.any?
13
+ }
14
+ end
15
+
16
+ def self.reporter
17
+ if $stdout.tty?
18
+ ColouredReporter
19
+ else
20
+ PlainReporter
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rgr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Charlie Somerville
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coderay
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ description: Grep tool for large Ruby codebases
42
+ email: charlie@charliesomerville.com
43
+ executables:
44
+ - rgr
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - bin/rgr
49
+ - lib/rgr.rb
50
+ - lib/rgr/coloured_reporter.rb
51
+ - lib/rgr/plain_reporter.rb
52
+ - lib/rgr/searcher.rb
53
+ homepage: https://github.com/charliesome/rgr
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.2.0
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Ruby Grep
77
+ test_files: []
78
+ has_rdoc: