tng 0.5.8 → 0.5.9
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/bin/tng +7 -298
- 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/services/direct_generation.rb +1 -16
- data/lib/tng/services/test_generator.rb +4 -102
- data/lib/tng/ui/go_ui_session.rb +3 -46
- data/lib/tng/ui/json_session.rb +4 -5
- 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: 5ac92dae68f80b3257a5b3b13eb26b58df3bd9e1519991d61604e6cf4710bc4d
|
|
4
|
+
data.tar.gz: 34cff72d5582236daeff78511aa9614c642e10bedb74024f26249cedbefcd5c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae6d50a8894289861a03f8f107520f141b0ea394ede15cc69cb33e0367bc895bc6d205cc7381a25b3ec3f5c93ded663fd59f19a8f0f9ee4b0a7779df6313b7a5
|
|
7
|
+
data.tar.gz: 6632fa1c7f7759f1e45409c6dca7c39dae7852288ae6291a05469427b70578e975a81a97314f81dd56a7840fdced3a9c7c1cd76f5f5dd2b8b8279a86b9c30d36
|
data/bin/tng
CHANGED
|
@@ -71,13 +71,6 @@ class CLI
|
|
|
71
71
|
example " bundle exec tng app/models/user.rb --deadcode", ""
|
|
72
72
|
example " bundle exec tng --file=app/services/auth_service.rb -d", ""
|
|
73
73
|
example ""
|
|
74
|
-
example "X-Ray Visualization:", ""
|
|
75
|
-
example " bundle exec tng app/services/payment_processor.rb process_payment --xray", ""
|
|
76
|
-
example " bundle exec tng --file=users_controller.rb --method=create --xray --json", ""
|
|
77
|
-
example ""
|
|
78
|
-
example "Regression Check:", ""
|
|
79
|
-
example " bundle exec tng --file=app/services/payment_service.rb --method=process --impact", ""
|
|
80
|
-
example ""
|
|
81
74
|
example "Call Sites:", ""
|
|
82
75
|
example " bundle exec tng --file=app/services/payment_service.rb --method=process --callsites", ""
|
|
83
76
|
example ""
|
|
@@ -131,6 +124,11 @@ class CLI
|
|
|
131
124
|
desc "Run in audit mode (find issues and behaviours instead of generating tests)"
|
|
132
125
|
end
|
|
133
126
|
|
|
127
|
+
flag :prepare do
|
|
128
|
+
long "--prepare"
|
|
129
|
+
desc "Prepare audit prompt only (no LLM call)"
|
|
130
|
+
end
|
|
131
|
+
|
|
134
132
|
flag :trace do
|
|
135
133
|
long "--trace"
|
|
136
134
|
desc "Generate and visualize a symbolic trace"
|
|
@@ -141,16 +139,6 @@ class CLI
|
|
|
141
139
|
desc "Find in-repo call sites for a method"
|
|
142
140
|
end
|
|
143
141
|
|
|
144
|
-
flag :impact do
|
|
145
|
-
long "--impact"
|
|
146
|
-
desc "Run regression check (compare against Git HEAD)"
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
flag :xray do
|
|
150
|
-
long "--xray"
|
|
151
|
-
desc "Generate X-Ray visualization (Mermaid flowchart)"
|
|
152
|
-
end
|
|
153
|
-
|
|
154
142
|
flag :json do
|
|
155
143
|
short "-j"
|
|
156
144
|
long "--json"
|
|
@@ -213,16 +201,12 @@ class CLI
|
|
|
213
201
|
|
|
214
202
|
if params[:fix]
|
|
215
203
|
handle_fix_command
|
|
216
|
-
elsif params[:impact] && params[:file]
|
|
217
|
-
run_direct_impact
|
|
218
204
|
elsif params[:callsites] && params[:file]
|
|
219
205
|
run_direct_call_sites
|
|
220
206
|
elsif params[:trace] && params[:file]
|
|
221
207
|
run_direct_trace
|
|
222
208
|
elsif params[:deadcode]
|
|
223
209
|
run_dead_code_detection
|
|
224
|
-
elsif params[:xray] && params[:file]
|
|
225
|
-
run_direct_xray
|
|
226
210
|
elsif params[:file]
|
|
227
211
|
run_direct_generation
|
|
228
212
|
else
|
|
@@ -259,12 +243,10 @@ class CLI
|
|
|
259
243
|
normalized << "--method=#{::Regexp.last_match(2)}"
|
|
260
244
|
when /^(?:--)?(audit|a)$/
|
|
261
245
|
normalized << "--audit"
|
|
246
|
+
when /^(?:--)?(prepare)$/
|
|
247
|
+
normalized << "--prepare"
|
|
262
248
|
when /^(?:--)?(trace)$/
|
|
263
249
|
normalized << "--trace"
|
|
264
|
-
when /^(?:--)?(impact)$/
|
|
265
|
-
normalized << "--impact"
|
|
266
|
-
when /^(?:--)?(xray)$/
|
|
267
|
-
normalized << "--xray"
|
|
268
250
|
when /^(?:--)?(callsites)$/
|
|
269
251
|
normalized << "--callsites"
|
|
270
252
|
when /^(?:--)?(json|j)$/
|
|
@@ -336,10 +318,6 @@ class CLI
|
|
|
336
318
|
handle_audit_method
|
|
337
319
|
when "trace"
|
|
338
320
|
handle_trace_method
|
|
339
|
-
when "impact"
|
|
340
|
-
handle_impact_method
|
|
341
|
-
when "xray"
|
|
342
|
-
handle_xray_method
|
|
343
321
|
when "clones"
|
|
344
322
|
handle_clone_detection
|
|
345
323
|
when "deadcode"
|
|
@@ -1589,46 +1567,6 @@ class CLI
|
|
|
1589
1567
|
end
|
|
1590
1568
|
end
|
|
1591
1569
|
|
|
1592
|
-
def handle_impact_method
|
|
1593
|
-
if @generic_mode
|
|
1594
|
-
handle_generic_impact
|
|
1595
|
-
return
|
|
1596
|
-
end
|
|
1597
|
-
|
|
1598
|
-
choice = @go_ui.show_test_type_menu("impact")
|
|
1599
|
-
|
|
1600
|
-
case choice
|
|
1601
|
-
when "controller"
|
|
1602
|
-
impact_controller_method
|
|
1603
|
-
when "model"
|
|
1604
|
-
impact_model_method
|
|
1605
|
-
when "service"
|
|
1606
|
-
impact_service_method
|
|
1607
|
-
when "other"
|
|
1608
|
-
impact_other_method
|
|
1609
|
-
end
|
|
1610
|
-
end
|
|
1611
|
-
|
|
1612
|
-
def handle_xray_method
|
|
1613
|
-
if @generic_mode
|
|
1614
|
-
handle_generic_xray
|
|
1615
|
-
return
|
|
1616
|
-
end
|
|
1617
|
-
|
|
1618
|
-
choice = @go_ui.show_test_type_menu("xray")
|
|
1619
|
-
|
|
1620
|
-
case choice
|
|
1621
|
-
when "controller"
|
|
1622
|
-
xray_controller_method
|
|
1623
|
-
when "model"
|
|
1624
|
-
xray_model_method
|
|
1625
|
-
when "service"
|
|
1626
|
-
xray_service_method
|
|
1627
|
-
when "other"
|
|
1628
|
-
xray_other_method
|
|
1629
|
-
end
|
|
1630
|
-
end
|
|
1631
|
-
|
|
1632
1570
|
def trace_controller_method
|
|
1633
1571
|
select_controller_and_method("Trace") do |controller, method_info|
|
|
1634
1572
|
run_trace_for_method(controller, method_info)
|
|
@@ -1653,54 +1591,6 @@ class CLI
|
|
|
1653
1591
|
end
|
|
1654
1592
|
end
|
|
1655
1593
|
|
|
1656
|
-
def impact_controller_method
|
|
1657
|
-
select_controller_and_method("Regression Check") do |controller, method_info|
|
|
1658
|
-
run_impact_for_method(controller, method_info)
|
|
1659
|
-
end
|
|
1660
|
-
end
|
|
1661
|
-
|
|
1662
|
-
def impact_model_method
|
|
1663
|
-
select_model_and_method("Regression Check") do |model, method_info|
|
|
1664
|
-
run_impact_for_method(model, method_info)
|
|
1665
|
-
end
|
|
1666
|
-
end
|
|
1667
|
-
|
|
1668
|
-
def impact_service_method
|
|
1669
|
-
select_service_and_method("Regression Check") do |service, method_info|
|
|
1670
|
-
run_impact_for_method(service, method_info)
|
|
1671
|
-
end
|
|
1672
|
-
end
|
|
1673
|
-
|
|
1674
|
-
def impact_other_method
|
|
1675
|
-
select_other_and_method("Regression Check") do |file, method_info|
|
|
1676
|
-
run_impact_for_method(file, method_info)
|
|
1677
|
-
end
|
|
1678
|
-
end
|
|
1679
|
-
|
|
1680
|
-
def xray_controller_method
|
|
1681
|
-
select_controller_and_method("X-Ray") do |controller, method_info|
|
|
1682
|
-
run_xray_for_method(controller, method_info)
|
|
1683
|
-
end
|
|
1684
|
-
end
|
|
1685
|
-
|
|
1686
|
-
def xray_model_method
|
|
1687
|
-
select_model_and_method("X-Ray") do |model, method_info|
|
|
1688
|
-
run_xray_for_method(model, method_info)
|
|
1689
|
-
end
|
|
1690
|
-
end
|
|
1691
|
-
|
|
1692
|
-
def xray_service_method
|
|
1693
|
-
select_service_and_method("X-Ray") do |service, method_info|
|
|
1694
|
-
run_xray_for_method(service, method_info)
|
|
1695
|
-
end
|
|
1696
|
-
end
|
|
1697
|
-
|
|
1698
|
-
def xray_other_method
|
|
1699
|
-
select_other_and_method("X-Ray") do |file, method_info|
|
|
1700
|
-
run_xray_for_method(file, method_info)
|
|
1701
|
-
end
|
|
1702
|
-
end
|
|
1703
|
-
|
|
1704
1594
|
def run_trace_for_method(file_info, method_info)
|
|
1705
1595
|
result_path = nil
|
|
1706
1596
|
|
|
@@ -1766,54 +1656,6 @@ class CLI
|
|
|
1766
1656
|
end
|
|
1767
1657
|
end
|
|
1768
1658
|
|
|
1769
|
-
def run_impact_for_method(file_info, method_info)
|
|
1770
|
-
result_path = nil
|
|
1771
|
-
|
|
1772
|
-
@go_ui.show_spinner("Running regression check for #{method_info[:name]}...") do
|
|
1773
|
-
begin
|
|
1774
|
-
project_root = Dir.pwd
|
|
1775
|
-
path = File.expand_path(file_info[:path])
|
|
1776
|
-
|
|
1777
|
-
class_name =
|
|
1778
|
-
if @generic_mode
|
|
1779
|
-
method_info[:class_name]
|
|
1780
|
-
else
|
|
1781
|
-
method_info[:class_name] || file_info[:name]
|
|
1782
|
-
end
|
|
1783
|
-
impact_json =
|
|
1784
|
-
if @generic_mode
|
|
1785
|
-
Tng::Analyzer::Context.analyze_impact_ruby(
|
|
1786
|
-
project_root,
|
|
1787
|
-
path,
|
|
1788
|
-
method_info[:name],
|
|
1789
|
-
class_name
|
|
1790
|
-
)
|
|
1791
|
-
else
|
|
1792
|
-
Tng::Analyzer::Context.analyze_impact(
|
|
1793
|
-
project_root,
|
|
1794
|
-
path,
|
|
1795
|
-
method_info[:name],
|
|
1796
|
-
class_name
|
|
1797
|
-
)
|
|
1798
|
-
end
|
|
1799
|
-
|
|
1800
|
-
f = Tempfile.new(['impact', '.json'])
|
|
1801
|
-
f.write(JSON.generate(impact_json))
|
|
1802
|
-
f.close
|
|
1803
|
-
result_path = f.path
|
|
1804
|
-
|
|
1805
|
-
{ success: true, message: "Regression check completed" }
|
|
1806
|
-
rescue => e
|
|
1807
|
-
{ success: false, message: e.message }
|
|
1808
|
-
end
|
|
1809
|
-
end
|
|
1810
|
-
|
|
1811
|
-
if result_path
|
|
1812
|
-
@go_ui.show_impact_results(result_path)
|
|
1813
|
-
File.unlink(result_path) if File.exist?(result_path)
|
|
1814
|
-
end
|
|
1815
|
-
end
|
|
1816
|
-
|
|
1817
1659
|
def run_direct_trace
|
|
1818
1660
|
file_path = params[:file]
|
|
1819
1661
|
method_name = params[:method]
|
|
@@ -1891,103 +1733,6 @@ class CLI
|
|
|
1891
1733
|
puts @pastel.dim("... #{sites.length - 200} more") if sites.length > 200
|
|
1892
1734
|
end
|
|
1893
1735
|
|
|
1894
|
-
def run_direct_impact
|
|
1895
|
-
file_path = params[:file]
|
|
1896
|
-
method_name = params[:method]
|
|
1897
|
-
class_name = params[:class_name]
|
|
1898
|
-
|
|
1899
|
-
unless method_name
|
|
1900
|
-
puts @pastel.decorate("Please specify a method name with --method or -m", Tng::UI::Theme.color(:error))
|
|
1901
|
-
return
|
|
1902
|
-
end
|
|
1903
|
-
|
|
1904
|
-
full_path = File.expand_path(file_path)
|
|
1905
|
-
unless File.exist?(full_path)
|
|
1906
|
-
puts @pastel.decorate("File not found: #{full_path}", Tng::UI::Theme.color(:error))
|
|
1907
|
-
return
|
|
1908
|
-
end
|
|
1909
|
-
return unless ensure_not_ignored(full_path)
|
|
1910
|
-
|
|
1911
|
-
relative_path = full_path.gsub("#{Dir.pwd}/", "")
|
|
1912
|
-
namespaced_name = relative_path.sub(/\.rb\z/, "").split("/").map(&:camelize).join("::")
|
|
1913
|
-
file_info = { path: full_path, name: namespaced_name }
|
|
1914
|
-
method_info = { name: method_name, class_name: class_name }
|
|
1915
|
-
|
|
1916
|
-
run_impact_for_method(file_info, method_info)
|
|
1917
|
-
end
|
|
1918
|
-
|
|
1919
|
-
def run_direct_xray
|
|
1920
|
-
return unless check_configuration
|
|
1921
|
-
|
|
1922
|
-
return unless check_authentication_configuration
|
|
1923
|
-
|
|
1924
|
-
file_path = params[:file]
|
|
1925
|
-
method_name = params[:method]
|
|
1926
|
-
|
|
1927
|
-
unless method_name
|
|
1928
|
-
puts @pastel.decorate("Please specify a method name with --method or -m", Tng::UI::Theme.color(:error))
|
|
1929
|
-
return
|
|
1930
|
-
end
|
|
1931
|
-
|
|
1932
|
-
full_path = File.expand_path(file_path)
|
|
1933
|
-
unless File.exist?(full_path)
|
|
1934
|
-
puts @pastel.decorate("File not found: #{full_path}", Tng::UI::Theme.color(:error))
|
|
1935
|
-
return
|
|
1936
|
-
end
|
|
1937
|
-
return unless ensure_not_ignored(full_path)
|
|
1938
|
-
|
|
1939
|
-
relative_path = full_path.gsub("#{Dir.pwd}/", "")
|
|
1940
|
-
namespaced_name = relative_path.sub(/\.rb\z/, "").split("/").map(&:camelize).join("::")
|
|
1941
|
-
file_info = { path: full_path, name: namespaced_name }
|
|
1942
|
-
method_info = { name: method_name }
|
|
1943
|
-
|
|
1944
|
-
run_xray_for_method(file_info, method_info)
|
|
1945
|
-
end
|
|
1946
|
-
|
|
1947
|
-
def run_xray_for_method(file_info, method_info)
|
|
1948
|
-
xray_result = nil
|
|
1949
|
-
|
|
1950
|
-
@go_ui.show_spinner("Generating X-Ray for #{method_info[:name]}...") do
|
|
1951
|
-
begin
|
|
1952
|
-
generator = Tng::Services::TestGenerator.new(@http_client)
|
|
1953
|
-
|
|
1954
|
-
if @generic_mode
|
|
1955
|
-
method_info = method_info.merge(test_type: method_info[:test_type] || "other")
|
|
1956
|
-
file_object = generic_file_object(file_info)
|
|
1957
|
-
xray_result = generator.run_xray_for_ruby_method(file_object, method_info)
|
|
1958
|
-
else
|
|
1959
|
-
type = Tng::Services::FileTypeDetector.detect_type(file_info[:path])
|
|
1960
|
-
file_object = Tng::Services::FileTypeDetector.build_file_object(file_info[:path], type)
|
|
1961
|
-
|
|
1962
|
-
xray_result = case type
|
|
1963
|
-
when "controller"
|
|
1964
|
-
generator.run_xray_for_controller_method(file_object, method_info)
|
|
1965
|
-
when "model"
|
|
1966
|
-
generator.run_xray_for_model_method(file_object, method_info)
|
|
1967
|
-
when "service"
|
|
1968
|
-
generator.run_xray_for_service_method(file_object, method_info)
|
|
1969
|
-
else
|
|
1970
|
-
generator.run_xray_for_other_method(file_object, method_info)
|
|
1971
|
-
end
|
|
1972
|
-
end
|
|
1973
|
-
|
|
1974
|
-
if xray_result&.dig(:error)
|
|
1975
|
-
{ success: false, message: xray_result[:message] || "X-Ray failed" }
|
|
1976
|
-
else
|
|
1977
|
-
{ success: true, message: "X-Ray generated" }
|
|
1978
|
-
end
|
|
1979
|
-
rescue => e
|
|
1980
|
-
{ success: false, message: e.message }
|
|
1981
|
-
end
|
|
1982
|
-
end
|
|
1983
|
-
|
|
1984
|
-
return @go_ui.show_auth_error(xray_result[:message] || "X-Ray failed") if xray_result&.dig(:error)
|
|
1985
|
-
|
|
1986
|
-
if xray_result && xray_result[:mermaid_code]
|
|
1987
|
-
@go_ui.show_xray_results(xray_result, method_info)
|
|
1988
|
-
end
|
|
1989
|
-
end
|
|
1990
|
-
|
|
1991
1736
|
def select_controller_and_method(action_name)
|
|
1992
1737
|
controllers = nil
|
|
1993
1738
|
@go_ui.show_spinner("Analyzing controllers...") do
|
|
@@ -2268,32 +2013,6 @@ class CLI
|
|
|
2268
2013
|
display_audit_results(audit_result || result)
|
|
2269
2014
|
end
|
|
2270
2015
|
|
|
2271
|
-
def handle_generic_xray
|
|
2272
|
-
selection = select_generic_method_and_type("X-Ray")
|
|
2273
|
-
return if selection.nil?
|
|
2274
|
-
|
|
2275
|
-
file_info, method_info = selection
|
|
2276
|
-
file_object = generic_file_object(file_info)
|
|
2277
|
-
|
|
2278
|
-
xray_result = nil
|
|
2279
|
-
@go_ui.show_spinner("Generating X-Ray for #{method_info[:name]}...") do
|
|
2280
|
-
xray_result = Tng::Services::TestGenerator.new(@http_client).run_xray_for_ruby_method(
|
|
2281
|
-
file_object,
|
|
2282
|
-
method_info
|
|
2283
|
-
)
|
|
2284
|
-
|
|
2285
|
-
if xray_result&.dig(:error)
|
|
2286
|
-
{ success: false, message: xray_result[:message] || "X-Ray failed" }
|
|
2287
|
-
else
|
|
2288
|
-
{ success: true, message: "X-Ray generated" }
|
|
2289
|
-
end
|
|
2290
|
-
end
|
|
2291
|
-
|
|
2292
|
-
return @go_ui.display_error(@pastel.red("❌ X-Ray failed: #{xray_result[:message]}")) if xray_result&.dig(:error)
|
|
2293
|
-
|
|
2294
|
-
@go_ui.show_xray_results(xray_result, method_info) if xray_result
|
|
2295
|
-
end
|
|
2296
|
-
|
|
2297
2016
|
def handle_generic_trace
|
|
2298
2017
|
file_info = select_generic_file("Trace")
|
|
2299
2018
|
return if file_info.nil?
|
|
@@ -2304,16 +2023,6 @@ class CLI
|
|
|
2304
2023
|
run_trace_for_method(file_info, method_info)
|
|
2305
2024
|
end
|
|
2306
2025
|
|
|
2307
|
-
def handle_generic_impact
|
|
2308
|
-
file_info = select_generic_file("Regression Check")
|
|
2309
|
-
return if file_info.nil?
|
|
2310
|
-
|
|
2311
|
-
method_info = select_generic_method(file_info, "Regression Check")
|
|
2312
|
-
return if method_info.nil?
|
|
2313
|
-
|
|
2314
|
-
run_impact_for_method(file_info, method_info)
|
|
2315
|
-
end
|
|
2316
|
-
|
|
2317
2026
|
def handle_generic_clone_detection
|
|
2318
2027
|
file_info = select_generic_file("Check Duplicates")
|
|
2319
2028
|
return if file_info.nil?
|
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
|
|
@@ -135,8 +135,6 @@ module Tng
|
|
|
135
135
|
action =
|
|
136
136
|
if @params[:trace]
|
|
137
137
|
"Tracing"
|
|
138
|
-
elsif @params[:xray]
|
|
139
|
-
"Generating X-Ray for"
|
|
140
138
|
elsif @params[:audit]
|
|
141
139
|
"Auditing"
|
|
142
140
|
else
|
|
@@ -153,8 +151,6 @@ module Tng
|
|
|
153
151
|
label =
|
|
154
152
|
if @params[:trace]
|
|
155
153
|
"Trace"
|
|
156
|
-
elsif @params[:xray]
|
|
157
|
-
"X-Ray"
|
|
158
154
|
elsif @params[:audit]
|
|
159
155
|
"Audit"
|
|
160
156
|
else
|
|
@@ -166,8 +162,6 @@ module Tng
|
|
|
166
162
|
@go_ui.show_trace_results(result[:file_path])
|
|
167
163
|
File.unlink(result[:file_path]) if File.exist?(result[:file_path])
|
|
168
164
|
end
|
|
169
|
-
elsif @params[:xray]
|
|
170
|
-
@go_ui.show_xray_results(result, method_info) if result
|
|
171
165
|
elsif @params[:audit]
|
|
172
166
|
display_audit_results(result)
|
|
173
167
|
elsif result && result[:file_path]
|
|
@@ -206,24 +200,15 @@ module Tng
|
|
|
206
200
|
|
|
207
201
|
if !Tng::Utils.rails_project?(Dir.pwd)
|
|
208
202
|
method_info = method_info.merge(test_type: method_info[:test_type] || "other")
|
|
209
|
-
return generator.run_for_ruby_method(file_object, method_info, progress: progress) unless @params[:trace] || @params[:audit]
|
|
203
|
+
return generator.run_for_ruby_method(file_object, method_info, progress: progress) unless @params[:trace] || @params[:audit]
|
|
210
204
|
|
|
211
205
|
if @params[:audit]
|
|
212
206
|
return generator.run_audit_for_ruby_method(file_object, method_info, progress: progress)
|
|
213
|
-
elsif @params[:xray]
|
|
214
|
-
return generator.run_xray_for_ruby_method(file_object, method_info, progress: progress)
|
|
215
207
|
end
|
|
216
208
|
end
|
|
217
209
|
|
|
218
210
|
if @params[:trace]
|
|
219
211
|
perform_trace_analysis(file_object, method_info, progress)
|
|
220
|
-
elsif @params[:xray]
|
|
221
|
-
case type
|
|
222
|
-
when "controller" then generator.run_xray_for_controller_method(file_object, method_info, progress: progress)
|
|
223
|
-
when "model" then generator.run_xray_for_model_method(file_object, method_info, progress: progress)
|
|
224
|
-
when "service" then generator.run_xray_for_service_method(file_object, method_info, progress: progress)
|
|
225
|
-
else generator.run_xray_for_other_method(file_object, method_info, progress: progress)
|
|
226
|
-
end
|
|
227
212
|
elsif @params[:audit]
|
|
228
213
|
case type
|
|
229
214
|
when "controller" then generator.run_audit_for_controller_method(file_object, method_info, progress: progress)
|
|
@@ -62,28 +62,6 @@ module Tng
|
|
|
62
62
|
def run_audit_for_ruby_method(other_file, method_info, progress: nil)
|
|
63
63
|
run_audit_for_ruby(other_file, method_info, progress: progress)
|
|
64
64
|
end
|
|
65
|
-
|
|
66
|
-
# X-Ray mode - async, polls for completion
|
|
67
|
-
def run_xray_for_controller_method(controller, method_info, progress: nil)
|
|
68
|
-
run_xray_for_type(controller, method_info, :controller, progress: progress)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def run_xray_for_model_method(model, method_info, progress: nil)
|
|
72
|
-
run_xray_for_type(model, method_info, :model, progress: progress)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def run_xray_for_service_method(service, method_info, progress: nil)
|
|
76
|
-
run_xray_for_type(service, method_info, :service, progress: progress)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def run_xray_for_other_method(other_file, method_info, progress: nil)
|
|
80
|
-
run_xray_for_type(other_file, method_info, :other, progress: progress)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def run_xray_for_ruby_method(other_file, method_info, progress: nil)
|
|
84
|
-
run_xray_for_ruby(other_file, method_info, progress: progress)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
65
|
def run_audit_for_type(file_object, method_info, type, progress: nil)
|
|
88
66
|
response = send_audit_request_for_type(file_object, method_info, type)
|
|
89
67
|
return { error: :network_error, message: "Network error" } unless response
|
|
@@ -131,54 +109,6 @@ module Tng
|
|
|
131
109
|
Tng.send_request_for_other(name, file_object[:path], enriched_method_info, *config, true, false)
|
|
132
110
|
end
|
|
133
111
|
end
|
|
134
|
-
|
|
135
|
-
def run_xray_for_type(file_object, method_info, type, progress: nil)
|
|
136
|
-
response = send_xray_request_for_type(file_object, method_info, type)
|
|
137
|
-
return { error: :network_error, message: "Network error" } unless response
|
|
138
|
-
|
|
139
|
-
if response.is_a?(HTTPX::ErrorResponse)
|
|
140
|
-
return { error: :network_error, message: response.error&.message || "Network error" }
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
return { error: :auth_failed, message: "Invalid or missing API key" } if response.status == 401
|
|
144
|
-
return { error: :auth_failed, message: "API key expired" } if response.status == 403
|
|
145
|
-
|
|
146
|
-
begin
|
|
147
|
-
job_data = JSON.parse(response.body)
|
|
148
|
-
return { error: :server_error, message: job_data["error"] } if job_data["error"]
|
|
149
|
-
|
|
150
|
-
job_id = job_data["job_id"]
|
|
151
|
-
return { error: :server_error, message: "No job_id returned" } unless job_id
|
|
152
|
-
|
|
153
|
-
# Poll for completion (similar to audit)
|
|
154
|
-
result = poll_for_completion(job_id, progress: progress, content_path: CONTENT_RESPONSES_PATH)
|
|
155
|
-
return { error: :timeout, message: "X-Ray generation timed out" } unless result
|
|
156
|
-
|
|
157
|
-
# X-Ray results should contain mermaid_code and explanation
|
|
158
|
-
result
|
|
159
|
-
rescue JSON::ParserError => e
|
|
160
|
-
{ error: :parse_error, message: "Failed to parse X-Ray response: #{e.message}" }
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def send_xray_request_for_type(file_object, method_info, type)
|
|
165
|
-
config = request_config
|
|
166
|
-
name = file_object[:name] || File.basename(file_object[:path], ".rb")
|
|
167
|
-
enriched_method_info = enrich_method_info_with_trace_v2(file_object, method_info, ruby_mode: false)
|
|
168
|
-
|
|
169
|
-
# Pass xray_mode: true as 9th parameter (audit_mode: false, xray_mode: true)
|
|
170
|
-
case type
|
|
171
|
-
when :controller
|
|
172
|
-
Tng.send_request_for_controller(name, file_object[:path], enriched_method_info, *config, false, true)
|
|
173
|
-
when :model
|
|
174
|
-
Tng.send_request_for_model(name, file_object[:path], enriched_method_info, *config, false, true)
|
|
175
|
-
when :service
|
|
176
|
-
Tng.send_request_for_service(name, file_object[:path], enriched_method_info, *config, false, true)
|
|
177
|
-
when :other
|
|
178
|
-
Tng.send_request_for_other(name, file_object[:path], enriched_method_info, *config, false, true)
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
112
|
def generate_test_for_type(file_object, method_info, type, progress: nil)
|
|
183
113
|
start_time = Time.now
|
|
184
114
|
|
|
@@ -237,7 +167,7 @@ module Tng
|
|
|
237
167
|
def generate_test_for_ruby(file_object, method_info, progress: nil)
|
|
238
168
|
start_time = Time.now
|
|
239
169
|
|
|
240
|
-
response = send_request_for_ruby(file_object, method_info, audit_mode: false
|
|
170
|
+
response = send_request_for_ruby(file_object, method_info, audit_mode: false)
|
|
241
171
|
return unless response
|
|
242
172
|
|
|
243
173
|
if response.is_a?(HTTPX::ErrorResponse)
|
|
@@ -266,7 +196,7 @@ module Tng
|
|
|
266
196
|
end
|
|
267
197
|
|
|
268
198
|
def run_audit_for_ruby(file_object, method_info, progress: nil)
|
|
269
|
-
response = send_request_for_ruby(file_object, method_info, audit_mode: true
|
|
199
|
+
response = send_request_for_ruby(file_object, method_info, audit_mode: true)
|
|
270
200
|
return { error: :network_error, message: "Network error" } unless response
|
|
271
201
|
|
|
272
202
|
if response.is_a?(HTTPX::ErrorResponse)
|
|
@@ -291,40 +221,12 @@ module Tng
|
|
|
291
221
|
{ error: :parse_error, message: "Failed to parse audit response: #{e.message}" }
|
|
292
222
|
end
|
|
293
223
|
end
|
|
294
|
-
|
|
295
|
-
def run_xray_for_ruby(file_object, method_info, progress: nil)
|
|
296
|
-
response = send_request_for_ruby(file_object, method_info, audit_mode: false, xray_mode: true)
|
|
297
|
-
return { error: :network_error, message: "Network error" } unless response
|
|
298
|
-
|
|
299
|
-
if response.is_a?(HTTPX::ErrorResponse)
|
|
300
|
-
return { error: :network_error, message: response.error&.message || "Network error" }
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
return { error: :auth_failed, message: "Invalid or missing API key" } if response.status == 401
|
|
304
|
-
return { error: :auth_failed, message: "API key expired" } if response.status == 403
|
|
305
|
-
|
|
306
|
-
begin
|
|
307
|
-
job_data = JSON.parse(response.body)
|
|
308
|
-
return { error: :server_error, message: job_data["error"] } if job_data["error"]
|
|
309
|
-
|
|
310
|
-
job_id = job_data["job_id"]
|
|
311
|
-
return { error: :server_error, message: "No job_id returned" } unless job_id
|
|
312
|
-
|
|
313
|
-
result = poll_for_completion(job_id, progress: progress, content_path: RUBY_CONTENT_RESPONSES_PATH)
|
|
314
|
-
return { error: :timeout, message: "X-Ray generation timed out" } unless result
|
|
315
|
-
|
|
316
|
-
result
|
|
317
|
-
rescue JSON::ParserError => e
|
|
318
|
-
{ error: :parse_error, message: "Failed to parse X-Ray response: #{e.message}" }
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
def send_request_for_ruby(file_object, method_info, audit_mode:, xray_mode:)
|
|
224
|
+
def send_request_for_ruby(file_object, method_info, audit_mode:)
|
|
323
225
|
config = request_config
|
|
324
226
|
name = file_object[:name] || File.basename(file_object[:path], ".rb")
|
|
325
227
|
enriched_method_info = enrich_method_info_with_trace_v2(file_object, method_info, ruby_mode: true)
|
|
326
228
|
|
|
327
|
-
Tng.send_request_for_ruby(name, file_object[:path], enriched_method_info, *config, audit_mode,
|
|
229
|
+
Tng.send_request_for_ruby(name, file_object[:path], enriched_method_info, *config, audit_mode, false)
|
|
328
230
|
end
|
|
329
231
|
|
|
330
232
|
def enrich_method_info_with_trace_v2(file_object, method_info, ruby_mode:)
|
data/lib/tng/ui/go_ui_session.rb
CHANGED
|
@@ -275,45 +275,6 @@ module Tng
|
|
|
275
275
|
puts "Trace results error: #{e.message}"
|
|
276
276
|
end
|
|
277
277
|
|
|
278
|
-
# Show regression check results
|
|
279
|
-
# @param impact_file_path [String] Path to JSON impact file
|
|
280
|
-
def show_impact_results(impact_file_path)
|
|
281
|
-
system(@binary_path, "ruby-impact-results", "--file", impact_file_path)
|
|
282
|
-
rescue StandardError => e
|
|
283
|
-
puts "Impact results error: #{e.message}"
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Show X-Ray visualization results
|
|
287
|
-
# @param xray_result [Hash] X-Ray result with mermaid_code
|
|
288
|
-
# @param method_info [Hash] Optional method info for context
|
|
289
|
-
def show_xray_results(xray_result, method_info = {})
|
|
290
|
-
data = {
|
|
291
|
-
mermaid_code: xray_result[:mermaid_code] || xray_result["mermaid_code"] || "",
|
|
292
|
-
explanation: xray_result[:explanation] || xray_result["explanation"] || "Logic flow visualization generated by TNG.",
|
|
293
|
-
method_name: method_info[:name] || method_info["name"] || "",
|
|
294
|
-
class_name: method_info[:class_name] || method_info["class_name"] || ""
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
# Silently copy to clipboard for mermaid.live
|
|
298
|
-
mermaid_code = data[:mermaid_code]
|
|
299
|
-
if RUBY_PLATFORM.include?("darwin")
|
|
300
|
-
IO.popen("pbcopy", "w") { |io| io.print mermaid_code } rescue nil
|
|
301
|
-
elsif RUBY_PLATFORM.include?("linux")
|
|
302
|
-
IO.popen("xclip -selection clipboard", "w") { |io| io.print mermaid_code } rescue nil
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
input_path = _create_temp_file("go_ui_xray", ".json")
|
|
306
|
-
File.write(input_path, JSON.generate(data))
|
|
307
|
-
|
|
308
|
-
begin
|
|
309
|
-
system(@binary_path, "xray-results", "--file", input_path)
|
|
310
|
-
rescue StandardError => e
|
|
311
|
-
puts "X-Ray results error: #{e.message}"
|
|
312
|
-
ensure
|
|
313
|
-
_cleanup_temp_file(input_path)
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
278
|
# Show clone detection results
|
|
318
279
|
# @param file_path [String] Original file path analyzed
|
|
319
280
|
# @param results [Hash] Clone detection results { matches: [...] }
|
|
@@ -434,10 +395,9 @@ module Tng
|
|
|
434
395
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD", desc: "Direct test generation" },
|
|
435
396
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --audit", desc: "Direct audit mode" },
|
|
436
397
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --trace", desc: "Symbolic trace mode" },
|
|
437
|
-
{ cmd: "bundle exec tng --file=FILE --method=METHOD --impact", desc: "Regression check mode" },
|
|
438
398
|
{ cmd: "bundle exec tng --file=FILE --clones", desc: "Check for code duplicates" },
|
|
439
399
|
{ cmd: "bundle exec tng --file=FILE --deadcode", desc: "Run dead code detection" },
|
|
440
|
-
|
|
400
|
+
|
|
441
401
|
],
|
|
442
402
|
features: [
|
|
443
403
|
"Controllers, Models, Services",
|
|
@@ -445,10 +405,8 @@ module Tng
|
|
|
445
405
|
"Per-method test generation",
|
|
446
406
|
"Code audit for issues & behaviors",
|
|
447
407
|
"Symbolic execution traces",
|
|
448
|
-
"Regression check against Git HEAD",
|
|
449
408
|
"Duplicate code detection (Clones)",
|
|
450
409
|
"Dead code detection (Rust-powered)",
|
|
451
|
-
"X-Ray Logic Flow Visualization",
|
|
452
410
|
"Searchable method lists"
|
|
453
411
|
],
|
|
454
412
|
options: [
|
|
@@ -457,17 +415,16 @@ module Tng
|
|
|
457
415
|
{ flag: "--method=NAME", desc: "Method name to generate test for" },
|
|
458
416
|
{ flag: "--audit", desc: "Run audit mode instead of test generation" },
|
|
459
417
|
{ flag: "--trace", desc: "Run symbolic trace mode" },
|
|
460
|
-
{ flag: "--impact", desc: "Run regression check mode" },
|
|
461
418
|
{ flag: "--clones", desc: "Run clone detection mode" },
|
|
462
419
|
{ flag: "--level=1|2|3|all", desc: "Set clone detection level (default: all)" },
|
|
463
420
|
{ flag: "--deadcode", desc: "Run dead code detection" },
|
|
464
|
-
|
|
421
|
+
|
|
465
422
|
],
|
|
466
423
|
how_to: [
|
|
467
424
|
"Run 'bundle exec tng' for interactive mode",
|
|
468
425
|
"Run 'tng [file] --clones' for duplicate detection",
|
|
469
426
|
"Run 'tng [file] --deadcode' for dead code analysis",
|
|
470
|
-
|
|
427
|
+
|
|
471
428
|
"Select Controller, Model, or Service to start",
|
|
472
429
|
"Choose a method to generate/audit or select 'Check Duplicates'"
|
|
473
430
|
],
|
data/lib/tng/ui/json_session.rb
CHANGED
|
@@ -101,11 +101,6 @@ 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
|
-
|
|
109
104
|
def show_dead_code_results(file_path, results_json)
|
|
110
105
|
parsed = JSON.parse(results_json)
|
|
111
106
|
emit_event("dead_code", parsed)
|
|
@@ -130,6 +125,10 @@ module Tng
|
|
|
130
125
|
emit_event("result", result)
|
|
131
126
|
end
|
|
132
127
|
|
|
128
|
+
def show_prompt(content)
|
|
129
|
+
emit_event("prompt", { content: content.to_s })
|
|
130
|
+
end
|
|
131
|
+
|
|
133
132
|
# ------------------------------------------------------------------
|
|
134
133
|
# Errors & Warnings
|
|
135
134
|
# ------------------------------------------------------------------
|
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.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ralucab
|
|
@@ -201,7 +201,7 @@ metadata:
|
|
|
201
201
|
source_code_uri: https://github.com/tng-sh/tng-rails-public
|
|
202
202
|
license_uri: https://github.com/tng-sh/tng-rails-public/blob/main/LICENSE.md
|
|
203
203
|
post_install_message: |-
|
|
204
|
-
TNG v0.5.
|
|
204
|
+
TNG v0.5.9 installed successfully!
|
|
205
205
|
Run 'bundle exec tng init' to get started.
|
|
206
206
|
Use 'bundle exec tng --help' for usage information.
|
|
207
207
|
rdoc_options: []
|