lex-detect 0.1.7 → 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 +7 -0
- data/CLAUDE.md +2 -2
- data/lib/legion/extensions/detect/formatters/markdown_pr.rb +61 -0
- data/lib/legion/extensions/detect/formatters/sarif.rb +82 -0
- data/lib/legion/extensions/detect/version.rb +1 -1
- data/lib/legion/extensions/detect.rb +11 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e40e042cb6111ce0d3708ed3de574e32baf92839704e2a22ed4c239bcaf4907
|
|
4
|
+
data.tar.gz: 4fdd6b3f2388a5aeb8a5a862e57cc29d57aa239793dbccdcabbdc1967267a031
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d8a294a962b08b21d08d26b9189ab01e7194a244e04299b2094e3eecfd5b00f40cebc56d438ea71b5ed2a47aab10bb77bf465eb8b71eff5821fdb5e11cd9f55
|
|
7
|
+
data.tar.gz: 634257c97700a444f7a846ef249d69d718e5cf2d0202793bd38ba156bb48fae025410d98e7aeba56a8735647334d34c2f4bfd7cbdf53fc2c8870e50bf55297ce
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-03-22
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- SARIF 2.1.0 formatter (`Formatters::Sarif`) for GitHub Code Scanning integration
|
|
7
|
+
- Markdown PR comment formatter (`Formatters::MarkdownPr`) for GitHub PR annotations
|
|
8
|
+
- `format_results(format:, detections:)` public API method supporting `:sarif`, `:markdown`, and `:json` output formats
|
|
9
|
+
|
|
3
10
|
## [0.1.7] - 2026-03-22
|
|
4
11
|
|
|
5
12
|
### Fixed
|
data/CLAUDE.md
CHANGED
|
@@ -10,7 +10,7 @@ Legion Extension that scans the local environment and recommends which `lex-*` e
|
|
|
10
10
|
|
|
11
11
|
**GitHub**: https://github.com/LegionIO/lex-detect
|
|
12
12
|
**License**: MIT
|
|
13
|
-
**Version**: 0.
|
|
13
|
+
**Version**: 0.2.0
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
@@ -57,7 +57,7 @@ Legion::Extensions::Detect.catalog # raw CATALOG constant
|
|
|
57
57
|
|
|
58
58
|
## Testing
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
54 specs across 9 spec files.
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
bundle install
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Detect
|
|
6
|
+
module Formatters
|
|
7
|
+
module MarkdownPr
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def format(detections)
|
|
11
|
+
missing = collect_missing(detections)
|
|
12
|
+
installed = collect_installed(detections)
|
|
13
|
+
|
|
14
|
+
lines = ["## Legion Detect Findings\n"]
|
|
15
|
+
|
|
16
|
+
if missing.any?
|
|
17
|
+
lines << "### Missing Extensions (#{missing.size})\n"
|
|
18
|
+
missing.each do |m|
|
|
19
|
+
lines << "- **#{m[:name]}**: `#{m[:extension]}` not installed"
|
|
20
|
+
lines << " Detected by: #{m[:signals].join(', ')}"
|
|
21
|
+
lines << " Install: `gem install #{m[:extension]}`\n"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if installed.any?
|
|
26
|
+
lines << "### Installed (#{installed.size})\n"
|
|
27
|
+
installed.each do |i|
|
|
28
|
+
lines << "- #{i[:name]}: `#{i[:extension]}` :white_check_mark:"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
lines << "No extensions detected.\n" if missing.empty? && installed.empty?
|
|
33
|
+
|
|
34
|
+
lines << "\n---\n*Generated by legion-detect v#{VERSION}*"
|
|
35
|
+
lines.join("\n")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def collect_missing(detections)
|
|
39
|
+
detections.flat_map do |d|
|
|
40
|
+
d[:extensions].filter_map do |ext|
|
|
41
|
+
next if d[:installed][ext]
|
|
42
|
+
|
|
43
|
+
{ name: d[:name], extension: ext, signals: d[:matched_signals] }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def collect_installed(detections)
|
|
49
|
+
detections.flat_map do |d|
|
|
50
|
+
d[:extensions].filter_map do |ext|
|
|
51
|
+
next unless d[:installed][ext]
|
|
52
|
+
|
|
53
|
+
{ name: d[:name], extension: ext }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Detect
|
|
8
|
+
module Formatters
|
|
9
|
+
module Sarif
|
|
10
|
+
SCHEMA = 'https://json.schemastore.org/sarif-2.1.0.json'
|
|
11
|
+
SARIF_VERSION = '2.1.0'
|
|
12
|
+
|
|
13
|
+
SEVERITY_MAP = {
|
|
14
|
+
missing: 'warning',
|
|
15
|
+
installed: 'note'
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
module_function
|
|
19
|
+
|
|
20
|
+
def format(detections)
|
|
21
|
+
rules = build_rules(detections)
|
|
22
|
+
results = build_results(detections)
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
'$schema' => SCHEMA,
|
|
26
|
+
'version' => SARIF_VERSION,
|
|
27
|
+
'runs' => [{
|
|
28
|
+
'tool' => {
|
|
29
|
+
'driver' => {
|
|
30
|
+
'name' => 'legion-detect',
|
|
31
|
+
'version' => VERSION,
|
|
32
|
+
'informationUri' => 'https://github.com/LegionIO/lex-detect',
|
|
33
|
+
'rules' => rules
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
'results' => results
|
|
37
|
+
}]
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_json(detections)
|
|
42
|
+
::JSON.pretty_generate(format(detections))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def build_rules(detections)
|
|
46
|
+
rules = detections.flat_map do |detection|
|
|
47
|
+
detection[:extensions].map do |ext|
|
|
48
|
+
{
|
|
49
|
+
'id' => "detect/#{ext}",
|
|
50
|
+
'name' => detection[:name],
|
|
51
|
+
'shortDescription' => { 'text' => "#{detection[:name]} detected — #{ext} recommended" },
|
|
52
|
+
'defaultConfiguration' => { 'level' => 'warning' }
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
rules.uniq { |r| r['id'] }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def build_results(detections)
|
|
60
|
+
detections.flat_map do |detection|
|
|
61
|
+
detection[:extensions].filter_map do |ext|
|
|
62
|
+
next if detection[:installed][ext]
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
'ruleId' => "detect/#{ext}",
|
|
66
|
+
'level' => 'warning',
|
|
67
|
+
'message' => {
|
|
68
|
+
'text' => "#{detection[:name]} detected (#{detection[:matched_signals].join(', ')}) but #{ext} is not installed"
|
|
69
|
+
},
|
|
70
|
+
'properties' => {
|
|
71
|
+
'matched_signals' => detection[:matched_signals],
|
|
72
|
+
'detection_name' => detection[:name]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -4,6 +4,8 @@ require 'legion/extensions/detect/version'
|
|
|
4
4
|
require 'legion/extensions/detect/catalog'
|
|
5
5
|
require 'legion/extensions/detect/scanner'
|
|
6
6
|
require 'legion/extensions/detect/installer'
|
|
7
|
+
require 'legion/extensions/detect/formatters/sarif'
|
|
8
|
+
require 'legion/extensions/detect/formatters/markdown_pr'
|
|
7
9
|
require_relative 'detect/runners/task_observer'
|
|
8
10
|
require_relative 'detect/runners/cancel_task'
|
|
9
11
|
|
|
@@ -41,6 +43,15 @@ module Legion
|
|
|
41
43
|
def catalog
|
|
42
44
|
CATALOG
|
|
43
45
|
end
|
|
46
|
+
|
|
47
|
+
def format_results(format: :json, detections: nil)
|
|
48
|
+
results = detections || scan
|
|
49
|
+
case format.to_sym
|
|
50
|
+
when :sarif then Formatters::Sarif.to_json(results)
|
|
51
|
+
when :markdown then Formatters::MarkdownPr.format(results)
|
|
52
|
+
else results
|
|
53
|
+
end
|
|
54
|
+
end
|
|
44
55
|
end
|
|
45
56
|
|
|
46
57
|
require_relative 'detect/actors/full_scan' if defined?(Legion::Extensions::Actors::Once)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-detect
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -31,6 +31,8 @@ files:
|
|
|
31
31
|
- lib/legion/extensions/detect/actors/full_scan.rb
|
|
32
32
|
- lib/legion/extensions/detect/actors/observer_tick.rb
|
|
33
33
|
- lib/legion/extensions/detect/catalog.rb
|
|
34
|
+
- lib/legion/extensions/detect/formatters/markdown_pr.rb
|
|
35
|
+
- lib/legion/extensions/detect/formatters/sarif.rb
|
|
34
36
|
- lib/legion/extensions/detect/installer.rb
|
|
35
37
|
- lib/legion/extensions/detect/local_migrations/20260319000001_create_detect_results.rb
|
|
36
38
|
- lib/legion/extensions/detect/local_migrations/20260320000001_create_observer_events.rb
|