tng 0.5.0 → 0.5.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 +4 -4
- data/README.md +24 -0
- data/bin/tng +247 -9
- data/binaries/go-ui-darwin-amd64 +0 -0
- data/binaries/go-ui-darwin-arm64 +0 -0
- data/binaries/go-ui-linux-amd64 +0 -0
- data/binaries/go-ui-linux-arm64 +0 -0
- data/binaries/tng-darwin-arm64.bundle +0 -0
- data/binaries/tng-darwin-x86_64.bundle +0 -0
- data/binaries/tng-linux-arm64.so +0 -0
- data/binaries/tng-linux-x86_64.so +0 -0
- data/binaries/tng.bundle +0 -0
- data/lib/tng/ui/go_ui_session.rb +13 -1
- data/lib/tng/ui/json_session.rb +5 -0
- data/lib/tng/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d34efac07c952da91c1d7247d8a3ee215bc9978af6cfcb12ca54d7b4977f599c
|
|
4
|
+
data.tar.gz: 6818c82d0d8d0694eb3f9d347478514574a34ed2d5b5e2dc2139e8de312d74b3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57f305b07faa097c6ff48b96cbca21b2cde388bc372d134d48ac8fbbc03dc808af60fdb1cd03482527812ccf52cf9b6f0ef0ecac00b4f33c3b6c7080ccc69618
|
|
7
|
+
data.tar.gz: 9529a0f62366e87fd7b6e44c120f53f1019037e9683c3271af184bae8015d4dbae211365b0dcf3b12ed81228840370173118256ffb28f3a8cf2125f8c9d91417
|
data/README.md
CHANGED
|
@@ -144,6 +144,25 @@ bundle exec tng -f order.rb -m calculate_total -t
|
|
|
144
144
|
- Method call chains
|
|
145
145
|
- Mermaid diagram generation
|
|
146
146
|
|
|
147
|
+
#### Impact Audit
|
|
148
|
+
|
|
149
|
+
Compare a method against its committed (`HEAD`) version and surface blast radius:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Run impact audit for a method
|
|
153
|
+
bundle exec tng --file app/services/payment_service.rb --method process_payment --impact
|
|
154
|
+
|
|
155
|
+
# JSON output for automation/CI
|
|
156
|
+
bundle exec tng --file app/services/payment_service.rb --method process_payment --impact --json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Impact Signals:**
|
|
160
|
+
- Added/removed required parameters
|
|
161
|
+
- Parameter kind/requirement changes
|
|
162
|
+
- Return type changes
|
|
163
|
+
- Variable type drift (inferred)
|
|
164
|
+
- Impacted call sites (files/lines)
|
|
165
|
+
|
|
147
166
|
#### Clone Detection
|
|
148
167
|
|
|
149
168
|
Find duplicate code with 3 levels of detection:
|
|
@@ -196,6 +215,7 @@ Get machine-readable output for CI/CD integration:
|
|
|
196
215
|
bundle exec tng --file app/models/user.rb --clones --json
|
|
197
216
|
bundle exec tng --file app/services/payment.rb --deadcode --json
|
|
198
217
|
bundle exec tng --file app/controllers/api_controller.rb --trace --json
|
|
218
|
+
bundle exec tng --file app/services/payment.rb --method process_payment --impact --json
|
|
199
219
|
```
|
|
200
220
|
|
|
201
221
|
## Advanced Features
|
|
@@ -298,6 +318,7 @@ Path 3: !discount_code.present? → calculate_tax → total
|
|
|
298
318
|
| `--method` | `-m` | Method name to analyze |
|
|
299
319
|
| `--audit` | `-a` | Run audit mode |
|
|
300
320
|
| `--trace` | `-t` | Run symbolic trace mode |
|
|
321
|
+
| `--impact` | | Run impact audit mode |
|
|
301
322
|
| `--clones` | `-c` | Run clone detection |
|
|
302
323
|
| `--deadcode` | `-d` | Run dead code detection |
|
|
303
324
|
| `--level` | `-l` | Clone detection level (1, 2, 3, or all) |
|
|
@@ -316,6 +337,9 @@ bundle exec tng -f payment_service.rb -m process -a
|
|
|
316
337
|
# Symbolic trace
|
|
317
338
|
bundle exec tng -f order.rb -m calculate_total -t
|
|
318
339
|
|
|
340
|
+
# Impact audit
|
|
341
|
+
bundle exec tng -f payment_service.rb -m process --impact
|
|
342
|
+
|
|
319
343
|
# Clone detection (all levels)
|
|
320
344
|
bundle exec tng -f pricing_service.rb -c
|
|
321
345
|
|
data/bin/tng
CHANGED
|
@@ -56,6 +56,9 @@ class CLI
|
|
|
56
56
|
example "X-Ray Visualization:", ""
|
|
57
57
|
example " bundle exec tng app/services/payment_processor.rb process_payment --xray", ""
|
|
58
58
|
example " bundle exec tng --file=users_controller.rb --method=create --xray --json", ""
|
|
59
|
+
example ""
|
|
60
|
+
example "Impact Audit:", ""
|
|
61
|
+
example " bundle exec tng --file=app/services/payment_service.rb --method=process --impact", ""
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
option :file do
|
|
@@ -82,6 +85,11 @@ class CLI
|
|
|
82
85
|
desc "Run in dead code detection mode (unreachable code, unused variables)"
|
|
83
86
|
end
|
|
84
87
|
|
|
88
|
+
flag :all do
|
|
89
|
+
long "--all"
|
|
90
|
+
desc "Run dead code detection across the entire repo (respects .gitignore)"
|
|
91
|
+
end
|
|
92
|
+
|
|
85
93
|
option :level do
|
|
86
94
|
short "-l"
|
|
87
95
|
long "--level=LEVEL"
|
|
@@ -99,6 +107,11 @@ class CLI
|
|
|
99
107
|
desc "Generate and visualize a symbolic trace"
|
|
100
108
|
end
|
|
101
109
|
|
|
110
|
+
flag :impact do
|
|
111
|
+
long "--impact"
|
|
112
|
+
desc "Run impact audit (compare against Git HEAD)"
|
|
113
|
+
end
|
|
114
|
+
|
|
102
115
|
flag :xray do
|
|
103
116
|
long "--xray"
|
|
104
117
|
desc "Generate X-Ray visualization (Mermaid flowchart)"
|
|
@@ -157,6 +170,8 @@ class CLI
|
|
|
157
170
|
|
|
158
171
|
if params[:fix]
|
|
159
172
|
handle_fix_command
|
|
173
|
+
elsif params[:impact] && params[:file]
|
|
174
|
+
run_direct_impact
|
|
160
175
|
elsif params[:trace] && params[:file]
|
|
161
176
|
run_direct_trace
|
|
162
177
|
elsif params[:deadcode] && params[:file]
|
|
@@ -201,6 +216,8 @@ class CLI
|
|
|
201
216
|
normalized << "--audit"
|
|
202
217
|
when /^(?:--)?(trace)$/
|
|
203
218
|
normalized << "--trace"
|
|
219
|
+
when /^(?:--)?(impact)$/
|
|
220
|
+
normalized << "--impact"
|
|
204
221
|
when /^(?:--)?(xray)$/
|
|
205
222
|
normalized << "--xray"
|
|
206
223
|
when /^(?:--)?(json|j)$/
|
|
@@ -211,6 +228,8 @@ class CLI
|
|
|
211
228
|
normalized << "--clones"
|
|
212
229
|
when /^(?:--)?(deadcode|d)$/
|
|
213
230
|
normalized << "--deadcode"
|
|
231
|
+
when /^(?:--)?(all)$/
|
|
232
|
+
normalized << "--all"
|
|
214
233
|
when /^(?:--)?(level|l)=(.+)$/
|
|
215
234
|
normalized << "--level=#{::Regexp.last_match(2)}"
|
|
216
235
|
when /^(help|h)=(.+)$/
|
|
@@ -270,6 +289,8 @@ class CLI
|
|
|
270
289
|
handle_audit_method
|
|
271
290
|
when "trace"
|
|
272
291
|
handle_trace_method
|
|
292
|
+
when "impact"
|
|
293
|
+
handle_impact_method
|
|
273
294
|
when "xray"
|
|
274
295
|
handle_xray_method
|
|
275
296
|
when "clones"
|
|
@@ -542,6 +563,11 @@ class CLI
|
|
|
542
563
|
|
|
543
564
|
def run_dead_code_detection
|
|
544
565
|
file_path = params[:file]
|
|
566
|
+
if params[:all] || file_path.nil?
|
|
567
|
+
run_dead_code_detection_repo
|
|
568
|
+
return
|
|
569
|
+
end
|
|
570
|
+
|
|
545
571
|
unless File.exist?(file_path)
|
|
546
572
|
puts @pastel.red("Error: File '#{file_path}' not found.")
|
|
547
573
|
return
|
|
@@ -564,6 +590,114 @@ class CLI
|
|
|
564
590
|
end
|
|
565
591
|
end
|
|
566
592
|
|
|
593
|
+
def run_dead_code_detection_repo
|
|
594
|
+
project_root = Dir.pwd
|
|
595
|
+
files = deadcode_repo_files(project_root)
|
|
596
|
+
|
|
597
|
+
if files.empty?
|
|
598
|
+
puts @pastel.yellow("No files found for dead code analysis.")
|
|
599
|
+
return
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
aggregate = []
|
|
603
|
+
total = files.length
|
|
604
|
+
start = Time.now
|
|
605
|
+
|
|
606
|
+
def render_deadcode_bar(current, total_count)
|
|
607
|
+
width = 20
|
|
608
|
+
ratio = total_count == 0 ? 1.0 : current.to_f / total_count.to_f
|
|
609
|
+
filled = (ratio * width).round
|
|
610
|
+
bar = "#" * filled + "-" * (width - filled)
|
|
611
|
+
percent = (ratio * 100).round
|
|
612
|
+
"Scanning project... [#{bar}] #{percent}%"
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
if params[:json]
|
|
616
|
+
# Suppress progress output in JSON mode
|
|
617
|
+
else
|
|
618
|
+
print render_deadcode_bar(0, total)
|
|
619
|
+
$stdout.flush
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
files.each_with_index do |file, idx|
|
|
623
|
+
rel = file.sub(%r{\A#{Regexp.escape(project_root)}/?}, "")
|
|
624
|
+
begin
|
|
625
|
+
result_json = Tng.detect_dead_code(file, true)
|
|
626
|
+
parsed = JSON.parse(result_json)
|
|
627
|
+
issues = parsed["dead_code"] || []
|
|
628
|
+
issues.each do |issue|
|
|
629
|
+
aggregate << {
|
|
630
|
+
"type" => issue["type"] || "unknown",
|
|
631
|
+
"line" => issue["line"] || 0,
|
|
632
|
+
"message" => issue["message"] || "",
|
|
633
|
+
"code" => issue["code"] || "",
|
|
634
|
+
"file" => rel
|
|
635
|
+
}
|
|
636
|
+
end
|
|
637
|
+
rescue => e
|
|
638
|
+
aggregate << {
|
|
639
|
+
"type" => "analysis_error",
|
|
640
|
+
"line" => 0,
|
|
641
|
+
"message" => "Failed to analyze: #{e.message}",
|
|
642
|
+
"code" => "",
|
|
643
|
+
"file" => rel
|
|
644
|
+
}
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
if !params[:json] && (idx % 10 == 0 || idx == total - 1)
|
|
648
|
+
print "\r" + render_deadcode_bar(idx + 1, total)
|
|
649
|
+
$stdout.flush
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
print "\n" unless params[:json]
|
|
654
|
+
|
|
655
|
+
result_payload = {
|
|
656
|
+
"file" => project_root,
|
|
657
|
+
"dead_code" => aggregate.map { |i|
|
|
658
|
+
{
|
|
659
|
+
"type" => i["type"],
|
|
660
|
+
"line" => i["line"],
|
|
661
|
+
"message" => "[#{i["file"]}] #{i["message"]}",
|
|
662
|
+
"code" => i["code"],
|
|
663
|
+
"file" => i["file"]
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if params[:json]
|
|
669
|
+
@go_ui.show_dead_code_results(project_root, result_payload.to_json)
|
|
670
|
+
else
|
|
671
|
+
if aggregate.empty?
|
|
672
|
+
puts "No dead code detected."
|
|
673
|
+
elapsed = Time.now - start
|
|
674
|
+
puts format("Summary: Found 0 dead items in %.2fs.", elapsed)
|
|
675
|
+
return
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
puts "Found dead code:"
|
|
679
|
+
aggregate.each do |issue|
|
|
680
|
+
snippet = issue["code"].to_s.strip
|
|
681
|
+
snippet = snippet.empty? ? "" : " (#{snippet})"
|
|
682
|
+
puts "- #{issue["file"]}:#{issue["line"]}#{snippet}"
|
|
683
|
+
end
|
|
684
|
+
elapsed = Time.now - start
|
|
685
|
+
puts format("Summary: Found %d dead items in %.2fs.", aggregate.length, elapsed)
|
|
686
|
+
puts "[Tip] Run 'tng audit' to fix logic bugs in the remaining code."
|
|
687
|
+
end
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
def deadcode_repo_files(root)
|
|
691
|
+
begin
|
|
692
|
+
files_json = Tng.list_deadcode_files(root)
|
|
693
|
+
files = JSON.parse(files_json)
|
|
694
|
+
return files.select { |f| File.file?(f) }
|
|
695
|
+
rescue => e
|
|
696
|
+
puts @pastel.red("Error listing repo files: #{e.message}")
|
|
697
|
+
[]
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
567
701
|
# Placeholder methods for other component types
|
|
568
702
|
def audit_model_method
|
|
569
703
|
models = nil
|
|
@@ -1318,6 +1452,21 @@ class CLI
|
|
|
1318
1452
|
end
|
|
1319
1453
|
end
|
|
1320
1454
|
|
|
1455
|
+
def handle_impact_method
|
|
1456
|
+
choice = @go_ui.show_test_type_menu("impact")
|
|
1457
|
+
|
|
1458
|
+
case choice
|
|
1459
|
+
when "controller"
|
|
1460
|
+
impact_controller_method
|
|
1461
|
+
when "model"
|
|
1462
|
+
impact_model_method
|
|
1463
|
+
when "service"
|
|
1464
|
+
impact_service_method
|
|
1465
|
+
when "other"
|
|
1466
|
+
impact_other_method
|
|
1467
|
+
end
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1321
1470
|
def handle_xray_method
|
|
1322
1471
|
choice = @go_ui.show_test_type_menu("xray")
|
|
1323
1472
|
|
|
@@ -1357,6 +1506,30 @@ class CLI
|
|
|
1357
1506
|
end
|
|
1358
1507
|
end
|
|
1359
1508
|
|
|
1509
|
+
def impact_controller_method
|
|
1510
|
+
select_controller_and_method("Impact Audit") do |controller, method_info|
|
|
1511
|
+
run_impact_for_method(controller, method_info)
|
|
1512
|
+
end
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
def impact_model_method
|
|
1516
|
+
select_model_and_method("Impact Audit") do |model, method_info|
|
|
1517
|
+
run_impact_for_method(model, method_info)
|
|
1518
|
+
end
|
|
1519
|
+
end
|
|
1520
|
+
|
|
1521
|
+
def impact_service_method
|
|
1522
|
+
select_service_and_method("Impact Audit") do |service, method_info|
|
|
1523
|
+
run_impact_for_method(service, method_info)
|
|
1524
|
+
end
|
|
1525
|
+
end
|
|
1526
|
+
|
|
1527
|
+
def impact_other_method
|
|
1528
|
+
select_other_and_method("Impact Audit") do |file, method_info|
|
|
1529
|
+
run_impact_for_method(file, method_info)
|
|
1530
|
+
end
|
|
1531
|
+
end
|
|
1532
|
+
|
|
1360
1533
|
def xray_controller_method
|
|
1361
1534
|
select_controller_and_method("X-Ray") do |controller, method_info|
|
|
1362
1535
|
run_xray_for_method(controller, method_info)
|
|
@@ -1413,6 +1586,39 @@ class CLI
|
|
|
1413
1586
|
end
|
|
1414
1587
|
end
|
|
1415
1588
|
|
|
1589
|
+
def run_impact_for_method(file_info, method_info)
|
|
1590
|
+
result_path = nil
|
|
1591
|
+
|
|
1592
|
+
@go_ui.show_spinner("Running impact audit for #{method_info[:name]}...") do
|
|
1593
|
+
begin
|
|
1594
|
+
project_root = Dir.pwd
|
|
1595
|
+
path = File.expand_path(file_info[:path])
|
|
1596
|
+
|
|
1597
|
+
class_name = file_info[:name]
|
|
1598
|
+
impact_json = Tng::Analyzer::Context.analyze_impact(
|
|
1599
|
+
project_root,
|
|
1600
|
+
path,
|
|
1601
|
+
method_info[:name],
|
|
1602
|
+
class_name
|
|
1603
|
+
)
|
|
1604
|
+
|
|
1605
|
+
f = Tempfile.new(['impact', '.json'])
|
|
1606
|
+
f.write(JSON.generate(impact_json))
|
|
1607
|
+
f.close
|
|
1608
|
+
result_path = f.path
|
|
1609
|
+
|
|
1610
|
+
{ success: true, message: "Impact audit completed" }
|
|
1611
|
+
rescue => e
|
|
1612
|
+
{ success: false, message: e.message }
|
|
1613
|
+
end
|
|
1614
|
+
end
|
|
1615
|
+
|
|
1616
|
+
if result_path
|
|
1617
|
+
@go_ui.show_impact_results(result_path)
|
|
1618
|
+
File.unlink(result_path) if File.exist?(result_path)
|
|
1619
|
+
end
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1416
1622
|
def run_direct_trace
|
|
1417
1623
|
file_path = params[:file]
|
|
1418
1624
|
method_name = params[:method]
|
|
@@ -1428,12 +1634,37 @@ class CLI
|
|
|
1428
1634
|
return
|
|
1429
1635
|
end
|
|
1430
1636
|
|
|
1431
|
-
|
|
1637
|
+
relative_path = full_path.gsub("#{Dir.pwd}/", "")
|
|
1638
|
+
namespaced_name = relative_path.sub(/\.rb\z/, "").split("/").map(&:camelize).join("::")
|
|
1639
|
+
file_info = { path: full_path, name: namespaced_name }
|
|
1432
1640
|
method_info = { name: method_name }
|
|
1433
1641
|
|
|
1434
1642
|
run_trace_for_method(file_info, method_info)
|
|
1435
1643
|
end
|
|
1436
1644
|
|
|
1645
|
+
def run_direct_impact
|
|
1646
|
+
file_path = params[:file]
|
|
1647
|
+
method_name = params[:method]
|
|
1648
|
+
|
|
1649
|
+
unless method_name
|
|
1650
|
+
puts @pastel.decorate("Please specify a method name with --method or -m", Tng::UI::Theme.color(:error))
|
|
1651
|
+
return
|
|
1652
|
+
end
|
|
1653
|
+
|
|
1654
|
+
full_path = File.expand_path(file_path)
|
|
1655
|
+
unless File.exist?(full_path)
|
|
1656
|
+
puts @pastel.decorate("File not found: #{full_path}", Tng::UI::Theme.color(:error))
|
|
1657
|
+
return
|
|
1658
|
+
end
|
|
1659
|
+
|
|
1660
|
+
relative_path = full_path.gsub("#{Dir.pwd}/", "")
|
|
1661
|
+
namespaced_name = relative_path.sub(/\.rb\z/, "").split("/").map(&:camelize).join("::")
|
|
1662
|
+
file_info = { path: full_path, name: namespaced_name }
|
|
1663
|
+
method_info = { name: method_name }
|
|
1664
|
+
|
|
1665
|
+
run_impact_for_method(file_info, method_info)
|
|
1666
|
+
end
|
|
1667
|
+
|
|
1437
1668
|
def run_direct_xray
|
|
1438
1669
|
return unless check_configuration
|
|
1439
1670
|
|
|
@@ -1453,7 +1684,9 @@ class CLI
|
|
|
1453
1684
|
return
|
|
1454
1685
|
end
|
|
1455
1686
|
|
|
1456
|
-
|
|
1687
|
+
relative_path = full_path.gsub("#{Dir.pwd}/", "")
|
|
1688
|
+
namespaced_name = relative_path.sub(/\.rb\z/, "").split("/").map(&:camelize).join("::")
|
|
1689
|
+
file_info = { path: full_path, name: namespaced_name }
|
|
1457
1690
|
method_info = { name: method_name }
|
|
1458
1691
|
|
|
1459
1692
|
run_xray_for_method(file_info, method_info)
|
|
@@ -1634,15 +1867,20 @@ class CLI
|
|
|
1634
1867
|
choice = files.find { |f| f[:name] == selected }
|
|
1635
1868
|
next unless choice
|
|
1636
1869
|
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1870
|
+
methods = extract_other_methods(choice)
|
|
1871
|
+
if methods.empty?
|
|
1872
|
+
@go_ui.show_no_items("methods in #{choice[:name]}")
|
|
1873
|
+
next
|
|
1874
|
+
end
|
|
1641
1875
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1876
|
+
m_items = methods.map { |m| { name: m[:name], path: choice[:name] } }
|
|
1877
|
+
m_selected = @go_ui.show_list_view("Select Method to #{action_name}", m_items)
|
|
1878
|
+
next if m_selected == "back"
|
|
1644
1879
|
|
|
1645
|
-
|
|
1880
|
+
m_choice = methods.find { |m| m[:name] == m_selected }
|
|
1881
|
+
next unless m_choice
|
|
1882
|
+
|
|
1883
|
+
yield(choice, m_choice)
|
|
1646
1884
|
end
|
|
1647
1885
|
end
|
|
1648
1886
|
|
data/binaries/go-ui-darwin-amd64
CHANGED
|
Binary file
|
data/binaries/go-ui-darwin-arm64
CHANGED
|
Binary file
|
data/binaries/go-ui-linux-amd64
CHANGED
|
Binary file
|
data/binaries/go-ui-linux-arm64
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/binaries/tng-linux-arm64.so
CHANGED
|
Binary file
|
|
Binary file
|
data/binaries/tng.bundle
CHANGED
|
Binary file
|
data/lib/tng/ui/go_ui_session.rb
CHANGED
|
@@ -256,6 +256,14 @@ module Tng
|
|
|
256
256
|
puts "Trace results error: #{e.message}"
|
|
257
257
|
end
|
|
258
258
|
|
|
259
|
+
# Show impact audit results
|
|
260
|
+
# @param impact_file_path [String] Path to JSON impact file
|
|
261
|
+
def show_impact_results(impact_file_path)
|
|
262
|
+
system(@binary_path, "ruby-impact-results", "--file", impact_file_path)
|
|
263
|
+
rescue StandardError => e
|
|
264
|
+
puts "Impact results error: #{e.message}"
|
|
265
|
+
end
|
|
266
|
+
|
|
259
267
|
# Show X-Ray visualization results
|
|
260
268
|
# @param xray_result [Hash] X-Ray result with mermaid_code
|
|
261
269
|
# @param method_info [Hash] Optional method info for context
|
|
@@ -316,7 +324,8 @@ module Tng
|
|
|
316
324
|
type: issue["type"],
|
|
317
325
|
line: issue["line"],
|
|
318
326
|
message: issue["message"],
|
|
319
|
-
code: issue["code"]
|
|
327
|
+
code: issue["code"],
|
|
328
|
+
file: issue["file"]
|
|
320
329
|
}
|
|
321
330
|
end
|
|
322
331
|
}
|
|
@@ -406,6 +415,7 @@ module Tng
|
|
|
406
415
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD", desc: "Direct test generation" },
|
|
407
416
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --audit", desc: "Direct audit mode" },
|
|
408
417
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --trace", desc: "Symbolic trace mode" },
|
|
418
|
+
{ cmd: "bundle exec tng --file=FILE --method=METHOD --impact", desc: "Impact audit mode" },
|
|
409
419
|
{ cmd: "bundle exec tng --file=FILE --clones", desc: "Check for code duplicates" },
|
|
410
420
|
{ cmd: "bundle exec tng --file=FILE --deadcode", desc: "Run dead code detection" },
|
|
411
421
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --xray", desc: "X-Ray visualization" }
|
|
@@ -416,6 +426,7 @@ module Tng
|
|
|
416
426
|
"Per-method test generation",
|
|
417
427
|
"Code audit for issues & behaviors",
|
|
418
428
|
"Symbolic execution traces",
|
|
429
|
+
"Impact audit against Git HEAD",
|
|
419
430
|
"Duplicate code detection (Clones)",
|
|
420
431
|
"Dead code detection (Rust-powered)",
|
|
421
432
|
"X-Ray Logic Flow Visualization",
|
|
@@ -427,6 +438,7 @@ module Tng
|
|
|
427
438
|
{ flag: "--method=NAME", desc: "Method name to generate test for" },
|
|
428
439
|
{ flag: "--audit", desc: "Run audit mode instead of test generation" },
|
|
429
440
|
{ flag: "--trace", desc: "Run symbolic trace mode" },
|
|
441
|
+
{ flag: "--impact", desc: "Run impact audit mode" },
|
|
430
442
|
{ flag: "--clones", desc: "Run clone detection mode" },
|
|
431
443
|
{ flag: "--level=1|2|3|all", desc: "Set clone detection level (default: all)" },
|
|
432
444
|
{ flag: "--deadcode", desc: "Run dead code detection" },
|
data/lib/tng/ui/json_session.rb
CHANGED
|
@@ -101,6 +101,11 @@ module Tng
|
|
|
101
101
|
emit_event("result", trace_json)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
def show_impact_results(impact_file_path)
|
|
105
|
+
impact_json = JSON.parse(File.read(impact_file_path))
|
|
106
|
+
emit_event("result", impact_json)
|
|
107
|
+
end
|
|
108
|
+
|
|
104
109
|
def show_dead_code_results(file_path, results_json)
|
|
105
110
|
parsed = JSON.parse(results_json)
|
|
106
111
|
emit_event("dead_code", parsed)
|
data/lib/tng/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tng
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ralucab
|
|
@@ -222,7 +222,7 @@ post_install_message: "┌ TNG ────────────────
|
|
|
222
222
|
\ │\n│ • bundle exec
|
|
223
223
|
tng --help - Show help information │\n│ │\n│
|
|
224
224
|
\ \U0001F4A1 Generate tests for individual methods with precision │\n└────────────────────────────────────────────────────────────
|
|
225
|
-
v0.5.
|
|
225
|
+
v0.5.1 ┘\n"
|
|
226
226
|
rdoc_options: []
|
|
227
227
|
require_paths:
|
|
228
228
|
- lib
|