nodegrep 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f209db3fa387b6bbe388714324c6496e1b0ce06ad2d0e840f0d6b9fa926b02b8
4
+ data.tar.gz: 7a0b15225d3d88ce0fb526c62efe52d0e89b6cd3ef2b182dbf715b076ca17d26
5
+ SHA512:
6
+ metadata.gz: ac74bfa8b5ff5c094021067e27896af6d86388b214baa07815257fed2e529f13a2c3eaeafe417977d623bb86829db9407ff1785b0131e7bf8ee7ed20d53d2b72
7
+ data.tar.gz: d239b23e7279cbbe34a2b006c4e67b93465912c368cc1250ce4372d1f6f6ce2a7cb2d16a03f1d72600d25e9073314b229d37a6eed3e7a3ff58cabab64432a38c
data/bin/nodegrep ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env ruby
2
+ require 'nodegrep'
3
+
4
+ recurse = false
5
+ line_numbers = false
6
+ lazy = false
7
+
8
+ helpmesg = <<~HELP
9
+ nodegrep - find code that matches NodePattern DSL
10
+
11
+ USAGE
12
+
13
+ nodegrep [flags] pattern files
14
+
15
+ Available flags:
16
+
17
+ -l\tLazy evaluation - stop at the first match
18
+ -n\tTurn on line number output
19
+ -r\tRecurse into directories
20
+ HELP
21
+
22
+
23
+ # nodegrep [flags] pattern file(s)
24
+
25
+ # process flags
26
+ arg = ''
27
+
28
+ loop do
29
+ arg = ARGV.shift
30
+ if arg.nil?
31
+ print helpmesg
32
+ exit -1
33
+ end
34
+ break if arg[0] != '-'
35
+ case arg[1]
36
+ when 'l'
37
+ lazy = true
38
+ when 'r'
39
+ recurse = true
40
+ when 'n'
41
+ line_numbers = true
42
+ else
43
+ puts "Error - Illegal flag: -#{arg[1]}".red
44
+ print helpmesg
45
+ exit -1
46
+ end
47
+ end
48
+
49
+ # Presume next arg is the pattern
50
+
51
+ pattern = arg
52
+
53
+ # The rest of the args are filenames
54
+
55
+ if ARGV.length == 0 && !recurse
56
+ puts "Error - no files to process".red
57
+ exit -1
58
+ end
59
+
60
+ files_to_process = []
61
+
62
+ if recurse
63
+ if ARGV.length == 0
64
+ files_to_process = Dir.glob('**/*.rb', base: Dir.getwd)
65
+ elsif ARGV.length == 1
66
+ unless File.directory?(ARGV[0])
67
+ puts "Error - value #{ARGV[0]} is not a directory"
68
+ exit -1
69
+ end
70
+ files_to_process = Dir.glob('**/*.rb', base: ARGV[0]).map{ |f| File.join(ARGV[0], f) }
71
+ else
72
+ puts "Error - cannot recursively process more than one directory"
73
+ exit -1
74
+ end
75
+ else
76
+ files_to_process = ARGV
77
+ end
78
+
79
+ files_to_process.each do |f|
80
+ source = File.read(f)
81
+ begin
82
+ m = NodeGrep::Matcher.new(source)
83
+ rescue NodeGrep::Matcher::SourceParseError
84
+ puts "Parsing error with #{f}, skipping".red
85
+ next
86
+ end
87
+ pres = NodeGrep::Presenter.new(source)
88
+ pres.line_numbers = line_numbers
89
+ matches = m.matching_nodes(pattern)
90
+ puts " *** #{f}".green if matches.length > 0
91
+ matches.each do |match|
92
+ puts pres.get_lines(match.first_line, match.last_line)
93
+ exit if lazy
94
+ end
95
+ end
96
+
@@ -0,0 +1,30 @@
1
+ require 'rubocop'
2
+ require 'rubocop-ast'
3
+
4
+ module NodeGrep
5
+ class Matcher
6
+ class SourceParseError < StandardError; end
7
+
8
+ def initialize(source)
9
+ @parsed_source = RuboCop::ProcessedSource.new(source, RUBY_VERSION.to_f)
10
+ @parsed_source.diagnostics.each do |d|
11
+ raise SourceParseError if d.level == :error
12
+ end
13
+ end
14
+
15
+ def matching_nodes(pattern)
16
+ @matches = []
17
+ @pattern = RuboCop::NodePattern.new(pattern)
18
+ visit_node(@parsed_source.ast)
19
+ @matches
20
+ end
21
+
22
+ private
23
+
24
+ def visit_node(node)
25
+ return unless node.class.to_s.include?('RuboCop::AST')
26
+ @matches << node if @pattern.match(node)
27
+ node.children.each{ |child| visit_node(child) }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ require 'colorize'
2
+
3
+ module NodeGrep
4
+ class Presenter
5
+ class OutOfBounds < StandardError; end
6
+
7
+ attr_accessor :color_output, :line_numbers
8
+
9
+ @color_output = false
10
+ @line_numbers = false
11
+
12
+ def initialize(source)
13
+ @source_lines = source.split("\n").map{ |l| l.gsub("\r", "") }
14
+ end
15
+
16
+ def get_lines(x, y)
17
+ num_lines = @source_lines.length
18
+ raise OutOfBounds if x < 1 || y < 1 || x > y
19
+ raise OutOfBounds if x > num_lines || y > num_lines
20
+ x -= 1
21
+ y -= 1
22
+ formatted_lines = (x..y).each.collect do |i|
23
+ output = ""
24
+ output << "#{i + 1}: " if @line_numbers
25
+ output << @source_lines[i]
26
+ output
27
+ end
28
+ formatted_lines.join("\n")
29
+ end
30
+ end
31
+ end
data/lib/nodegrep.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'nodegrep/matcher'
2
+ require 'nodegrep/presenter'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nodegrep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jon Jenkins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.40'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.40'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.14'
69
+ description:
70
+ email: jjenkins@gitlab.com
71
+ executables:
72
+ - nodegrep
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - bin/nodegrep
77
+ - lib/nodegrep.rb
78
+ - lib/nodegrep/matcher.rb
79
+ - lib/nodegrep/presenter.rb
80
+ homepage: https://gitlab.com/jon_jenkins
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 2.6.0
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubygems_version: 3.0.3.1
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: A utility to match patterns in Ruby code
103
+ test_files: []