txray 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +108 -27
- data/Rakefile +1 -0
- data/doc/monitor.png +0 -0
- data/doc/monitor.svg +229 -0
- data/lib/generators/txray/install_generator.rb +28 -0
- data/lib/generators/txray/templates/txray.yml +37 -0
- data/lib/txray/cli.rb +3 -0
- data/lib/txray/config.rb +28 -1
- data/lib/txray/monitor.rb +25 -1
- data/lib/txray/reporters/github.rb +71 -5
- data/lib/txray/reporters/live.rb +157 -69
- data/lib/txray/reporters/text.rb +65 -16
- data/lib/txray/reporters.rb +4 -0
- data/lib/txray/runtime.rb +47 -20
- data/lib/txray/scanner.rb +14 -1
- data/lib/txray/source_file.rb +56 -10
- data/lib/txray/version.rb +1 -1
- metadata +5 -1
data/lib/txray/scanner.rb
CHANGED
|
@@ -43,11 +43,24 @@ module Txray
|
|
|
43
43
|
def files
|
|
44
44
|
roots = @paths.empty? ? @config.includes : @paths
|
|
45
45
|
verify(roots) unless @paths.empty?
|
|
46
|
-
roots.flat_map { |root| expand(root).reject { |path| excluded?(path, root) } }
|
|
46
|
+
roots.flat_map { |root| expand(root).reject { |path| excluded?(path, root) } }
|
|
47
|
+
.map { |path| relative(path) }.uniq.sort
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
private
|
|
50
51
|
|
|
52
|
+
def relative(path)
|
|
53
|
+
absolute = resolve(path)
|
|
54
|
+
root = "#{Dir.pwd}#{File::SEPARATOR}"
|
|
55
|
+
absolute.start_with?(root) ? absolute.delete_prefix(root) : path
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def resolve(path)
|
|
59
|
+
File.realpath(path)
|
|
60
|
+
rescue StandardError
|
|
61
|
+
File.expand_path(path)
|
|
62
|
+
end
|
|
63
|
+
|
|
51
64
|
def verify(roots)
|
|
52
65
|
missing = roots.reject { |root| File.exist?(root) }
|
|
53
66
|
raise Error, "no such file or directory: #{missing.join(", ")}" if missing.any?
|
data/lib/txray/source_file.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Txray
|
|
4
4
|
class SourceFile
|
|
5
|
-
DIRECTIVE =
|
|
5
|
+
DIRECTIVE = /\A#\s*txray:(?<action>disable|enable)\b(?<rules>[\w,\s-]*)/
|
|
6
6
|
|
|
7
7
|
attr_reader :path, :root
|
|
8
8
|
|
|
@@ -11,33 +11,79 @@ module Txray
|
|
|
11
11
|
result = Prism.parse(code)
|
|
12
12
|
return nil if result.failure?
|
|
13
13
|
|
|
14
|
-
new(path: path, root: result.value, comments: result.comments)
|
|
14
|
+
new(path: path, root: result.value, comments: result.comments, code: code)
|
|
15
15
|
rescue StandardError
|
|
16
16
|
nil
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def initialize(path:, root:, comments: [])
|
|
19
|
+
def initialize(path:, root:, comments: [], code: "")
|
|
20
20
|
@path = path
|
|
21
21
|
@root = root
|
|
22
|
-
@
|
|
22
|
+
@lines = code.lines
|
|
23
|
+
@inline = {}
|
|
24
|
+
@regions = []
|
|
25
|
+
index(comments)
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def disabled?(line, rule_id)
|
|
26
|
-
|
|
29
|
+
return true if covers?(@inline[line], rule_id)
|
|
30
|
+
|
|
31
|
+
@regions.any? { |region| line.between?(region[:from], region[:to]) && covers?(region[:rules], rule_id) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def covers?(rules, rule_id)
|
|
27
37
|
return false if rules.nil?
|
|
28
38
|
|
|
29
39
|
rules.empty? || rules.include?(rule_id)
|
|
30
40
|
end
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
def index(comments)
|
|
43
|
+
open = {}
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
match = DIRECTIVE.match(comment.slice)
|
|
45
|
+
comments.each do |comment|
|
|
46
|
+
match = DIRECTIVE.match(comment.slice.to_s.strip)
|
|
37
47
|
next unless match
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
apply(match, comment, open)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
open.each { |key, from| @regions << region(key, from, Float::INFINITY) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def apply(match, comment, open)
|
|
56
|
+
rules = named_rules(match[:rules])
|
|
57
|
+
line = comment.location.start_line
|
|
58
|
+
|
|
59
|
+
if trailing?(comment)
|
|
60
|
+
@inline[line] = rules if match[:action] == "disable"
|
|
61
|
+
elsif match[:action] == "disable"
|
|
62
|
+
(rules.empty? ? [ :all ] : rules).each { |key| open[key] ||= line }
|
|
63
|
+
else
|
|
64
|
+
close(open, rules, line)
|
|
40
65
|
end
|
|
41
66
|
end
|
|
67
|
+
|
|
68
|
+
def close(open, rules, line)
|
|
69
|
+
keys = rules.empty? ? open.keys.dup : rules
|
|
70
|
+
keys.each do |key|
|
|
71
|
+
from = open.delete(key)
|
|
72
|
+
@regions << region(key, from, line) if from
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def region(key, from, to)
|
|
77
|
+
{ from: from, to: to, rules: key == :all ? [] : [ key ] }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def named_rules(text)
|
|
81
|
+
text.to_s.split(/[,\s]+/).reject { |rule| rule.empty? || rule == "all" }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def trailing?(comment)
|
|
85
|
+
prefix = @lines[comment.location.start_line - 1].to_s[0, comment.location.start_column].to_s
|
|
86
|
+
!prefix.strip.empty?
|
|
87
|
+
end
|
|
42
88
|
end
|
|
43
89
|
end
|
data/lib/txray/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: txray
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Theo Wecker
|
|
@@ -40,7 +40,11 @@ files:
|
|
|
40
40
|
- LICENSE.txt
|
|
41
41
|
- README.md
|
|
42
42
|
- Rakefile
|
|
43
|
+
- doc/monitor.png
|
|
44
|
+
- doc/monitor.svg
|
|
43
45
|
- exe/txray
|
|
46
|
+
- lib/generators/txray/install_generator.rb
|
|
47
|
+
- lib/generators/txray/templates/txray.yml
|
|
44
48
|
- lib/txray.rb
|
|
45
49
|
- lib/txray/analyzer.rb
|
|
46
50
|
- lib/txray/catalog.rb
|