code_reference_finder 0.0.0
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 +7 -0
- data/lib/code_reference_finder.rb +136 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9af7b22c3b5a984cd962a855e4b60a910e748979d869a15a244a386f032bba06
|
4
|
+
data.tar.gz: 6f3125078a4f4d60a005fa392138e7d7eca082a207db5a00fa327c97836cbe93
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c04d79e144283a4163fa7dec0733af9b1686b2c41d8a0048c34fae05c6832c0090127267e15cbe12a38031f7ec244ccb2dae27b12f95bf93a5f2e25e52fb55ea
|
7
|
+
data.tar.gz: c4ff575f231b3db942c1f0d4231416280c77118423a47c358712f56df10517f4917e55abf27689e2f3a73f15b388b4f4798cf8f53f8872270637fe1273be8875
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# This is a source code analyzer for finding files containing specific references.
|
2
|
+
|
3
|
+
class CodeReferenceFinder
|
4
|
+
def initialize(dir:, ext:, target:, ignore:)
|
5
|
+
@dir = dir
|
6
|
+
@ext = ext
|
7
|
+
@target = target
|
8
|
+
@ignore = ignore
|
9
|
+
@results = nil
|
10
|
+
@interesting_paths = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# Performs a parse and returns JSON results.
|
14
|
+
def get_json
|
15
|
+
@interesting_paths = find_interesting_paths()
|
16
|
+
json = parse_interesting_paths(@interesting_paths)
|
17
|
+
json
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the result hash, nil if unparsed.
|
21
|
+
def get_results
|
22
|
+
@results
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the interesting paths array, nil if unparsed.
|
26
|
+
def get_interesting_paths
|
27
|
+
@interesting_paths
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :results, :interesting_paths
|
33
|
+
|
34
|
+
# First pass pre-processing to locate files of interest to parse.
|
35
|
+
def find_interesting_paths
|
36
|
+
require 'find'
|
37
|
+
|
38
|
+
src_paths = []
|
39
|
+
Find.find(@dir) do |path|
|
40
|
+
src_paths << path if path.end_with? @ext
|
41
|
+
end
|
42
|
+
|
43
|
+
search_file_paths = []
|
44
|
+
src_paths.each do |path|
|
45
|
+
File.open(path) do |f|
|
46
|
+
f.each_line do |line|
|
47
|
+
if @target.any? {|s| line.include? s}
|
48
|
+
search_file_paths << path unless search_file_paths.include? path
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
search_file_paths
|
55
|
+
end
|
56
|
+
|
57
|
+
# Where the magic happens.
|
58
|
+
def parse_interesting_paths(interesting_paths)
|
59
|
+
require 'json'
|
60
|
+
|
61
|
+
def is_comment?(line)
|
62
|
+
line.start_with? '*' or line.start_with? '/*' or line.start_with? '//'
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_call?(line, ref)
|
66
|
+
line.include? "#{ref}." or line.include? "(#{ref}" or line.include? "#{ref})"
|
67
|
+
end
|
68
|
+
|
69
|
+
def is_ref_search_match?(line, refs)
|
70
|
+
tokens = line.split(' ')
|
71
|
+
matches = []
|
72
|
+
refs.each {|ref| matches << ref if tokens.include? ref }
|
73
|
+
matches.size > 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_ignorable?(line)
|
77
|
+
@ignore.any? {|s| line.include? s}
|
78
|
+
end
|
79
|
+
|
80
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
81
|
+
|
82
|
+
file_matches = {}
|
83
|
+
refined_target = @target.map {|s| s.split(' ').last}
|
84
|
+
|
85
|
+
# Loop through interesting paths to find targets and references to targets.
|
86
|
+
# Add the results of the parse to the file_matches hash.
|
87
|
+
interesting_paths.each do |path|
|
88
|
+
name = path[path.rindex('/') + 1..].sub(@ext, '').strip
|
89
|
+
line_matches = []
|
90
|
+
ref_searches = []
|
91
|
+
i = 0
|
92
|
+
|
93
|
+
File.open(path) do |f|
|
94
|
+
f.each_line do |line|
|
95
|
+
i += 1
|
96
|
+
next if is_comment?(line.strip!)
|
97
|
+
|
98
|
+
if refined_target.any? {|s| line.include? s} and not is_ignorable?(line)
|
99
|
+
line_matches << "#{i}: #{line}"
|
100
|
+
|
101
|
+
if line.include? ' = '
|
102
|
+
search = line.strip.split('=')[0].split(' ').last
|
103
|
+
ref_searches << search if not ref_searches.include? search
|
104
|
+
end
|
105
|
+
elsif ref_searches.any? {|s| is_call?(line, s)} or is_ref_search_match?(line, ref_searches)
|
106
|
+
line_matches << "#{i}: #{line}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
file_matches[name] = {
|
112
|
+
:path => path,
|
113
|
+
:line_count => i,
|
114
|
+
:ref_count => ref_searches.size,
|
115
|
+
:match_count => line_matches.size,
|
116
|
+
:refs => ref_searches,
|
117
|
+
:matches => line_matches
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
122
|
+
|
123
|
+
# Define our results hash and return it as a JSON string.
|
124
|
+
@results = {
|
125
|
+
:params => {
|
126
|
+
:dir => @dir,
|
127
|
+
:ext => @ext,
|
128
|
+
:target => @target,
|
129
|
+
:ignore => @ignore
|
130
|
+
},
|
131
|
+
:duration => "#{end_time - start_time} seconds",
|
132
|
+
:file_matches => file_matches
|
133
|
+
}
|
134
|
+
JSON.pretty_generate(@results)
|
135
|
+
end
|
136
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: code_reference_finder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Scott Stauffer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A source code analyzer to find targets and their references in very large
|
14
|
+
solutions.
|
15
|
+
email: scott@fuseraft.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/code_reference_finder.rb
|
21
|
+
homepage: https://rubygems.org/gems/code_reference_finder
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubygems_version: 3.3.5
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: A source code analyzer to find targets and their references in very large
|
44
|
+
solutions.
|
45
|
+
test_files: []
|