tng 0.4.7 โ 0.4.8
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 +291 -321
- data/Rakefile +8 -0
- data/bin/tng +170 -11
- 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/generators/tng/install_generator.rb +1 -0
- data/lib/tng/ui/go_ui_session.rb +43 -4
- 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: 1050b64ce05cdf8195c4bd1a5603161eea0f88c077ccd09e1ad2d3c17d78850f
|
|
4
|
+
data.tar.gz: 2c38ad45bd123379e2d24cfe4b20e538684c7969ece4dddc7b4d64e546b4c49d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f864c1e9dacc0c05d65304f1c640287c163e2f3d2882df4fa8220e4f656d70586894ddaf9c28fb14e920025802da5ceece8260a4bec42fd0fdfdff67354db90
|
|
7
|
+
data.tar.gz: e39fe64e2595c3a98fa96647eadc16bd178196fdbd5a831cf8edc20573a8095e687d317faf33daaf7090aeac8899548bf96a07cbb80a4d7ab38fbd2fc02b7707
|
data/README.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
# TNG - AI-Powered Test Generation for Rails
|
|
1
|
+
# TNG - AI-Powered Test Generation & Code Analysis for Rails
|
|
2
2
|
|
|
3
|
-
TNG is
|
|
3
|
+
TNG is a comprehensive AI-powered tool for Rails applications that combines intelligent test generation with advanced static analysis. Analyze your code structure, detect issues, find duplicates, and generate high-quality tests that follow your project's conventions.
|
|
4
4
|
|
|
5
5
|
**Owner:** Binary Dreams LLC
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **๐งช AI Test Generation** - Generate comprehensive tests for controllers, models, services, and 20+ file types
|
|
10
|
+
- **๐ Code Audit** - Deep security, performance, and best-practice analysis
|
|
11
|
+
- **๐ฌ Symbolic Trace** - Visualize execution paths and logic flow with Mermaid diagrams
|
|
12
|
+
- **๐ Clone Detection** - Find duplicate code with 3 detection levels (Token, Structural, Fuzzy)
|
|
13
|
+
- **๐ Dead Code Detection** - Identify unreachable code, unused variables, and unused private methods
|
|
14
|
+
- **โก Blazing Fast** - Powered by Rust for near-instant analysis
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
## Installation
|
|
10
17
|
|
|
11
18
|
Add this line to your application's Gemfile:
|
|
12
19
|
|
|
@@ -20,415 +27,378 @@ And then execute:
|
|
|
20
27
|
bundle install
|
|
21
28
|
```
|
|
22
29
|
|
|
23
|
-
##
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### 1. Initialize Configuration
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
Generate the configuration file:
|
|
26
35
|
|
|
27
36
|
```bash
|
|
28
37
|
rails generate tng:install
|
|
29
38
|
```
|
|
30
39
|
|
|
31
|
-
This creates `config/initializers/tng.rb
|
|
32
|
-
|
|
33
|
-
### Configuration Options Explained
|
|
34
|
-
|
|
35
|
-
#### API Configuration
|
|
36
|
-
- **`api_key`**: Your TNG API key from https://app.tng.sh/
|
|
37
|
-
- **`base_url`**: TNG service endpoint (automatically configured, do not modify)
|
|
38
|
-
|
|
39
|
-
#### Code Reading
|
|
40
|
-
- **`read_source_code`**: Analyzes the specific code file for which tests are being generated
|
|
41
|
-
- **`read_test_code`**: Reads existing tests for the specific file to match your testing patterns
|
|
42
|
-
|
|
43
|
-
#### Testing Framework Settings
|
|
44
|
-
- **`testing_framework`**: Automatically detected. Possible values: `minitest` or `rspec`
|
|
45
|
-
|
|
46
|
-
*Note: The following settings depend on your testing framework.*
|
|
47
|
-
|
|
48
|
-
**For Minitest:**
|
|
49
|
-
- **`test_style`**: Test organization style. Possible options:
|
|
50
|
-
- `test_block` - `test "does something" do ... end`
|
|
51
|
-
- `spec` - `it "does something" do ... end`
|
|
52
|
-
- `unit` - `def test_does_something ... end`
|
|
53
|
-
- **`assertion_style`**: Assertion syntax preference. Possible values:
|
|
54
|
-
- `assert/refute` - Uses syntax like `assert`, `assert_equal`, `assert_nil`, `refute`, `refute_nil`
|
|
55
|
-
- `assert/assert_not` - Uses syntax like `assert`, `assert_equal`, `assert_nil`, `assert_not`, `assert_not_equl`, `assert_not_nil`
|
|
56
|
-
- `must/wont` - `value.must_equal`, `value.must_be_instance_of`, `value.must_raise`, `value.wont_equal`, `value.wont_be_instance_of`, `value.wont_raise`
|
|
57
|
-
|
|
58
|
-
**For RSpec:**
|
|
59
|
-
- **`describe_style`**: Include describe blocks. Possible values: `true`, `false`
|
|
60
|
-
- **`context_style`**: Context block style. Possible values: `context`, `describe`
|
|
61
|
-
- **`it_style`**: Example block style. Possible values: `it`, `specify`
|
|
62
|
-
- **`before_style`**: Setup block style. Possible values: `before`, `setup`
|
|
63
|
-
- **`after_style`**: Teardown block style. Possible values: `after`, `teardown`
|
|
64
|
-
- **`let_style`**: Use let helpers. Possible values: `true`, `false`
|
|
65
|
-
- **`subject_style`**: Use subject helpers. Possible values: `true`, `false`
|
|
66
|
-
|
|
67
|
-
#### Authentication Methods
|
|
68
|
-
Supported authentication types:
|
|
69
|
-
- **`session`**: Session-based authentication
|
|
70
|
-
- **`devise`**: Devise gem integration
|
|
71
|
-
- **`jwt`**: JSON Web Token authentication
|
|
72
|
-
- **`token_auth`**: Token-based authentication
|
|
73
|
-
- **`basic_auth`**: HTTP Basic Authentication
|
|
74
|
-
- **`oauth`**: OAuth authentication
|
|
75
|
-
- **`headers`**: Custom header authentication
|
|
76
|
-
- **`custom`**: Custom authentication logic
|
|
77
|
-
|
|
78
|
-
#### Mock and Factory Libraries
|
|
79
|
-
- **`mock_library`**: Mock library preference
|
|
80
|
-
- **For Minitest**: `minitest/mock`, `mocha`, `nil`
|
|
81
|
-
- **For RSpec**: `rspec-mocks`, `mocha`, `flexmock`, `nil`
|
|
82
|
-
- **`http_mock_library`**: HTTP mocking library. Possible values: `webmock`, `vcr`, `httparty`, `nil`
|
|
83
|
-
- **`factory_library`**: Factory library preference. Possible values: `factory_bot`, `factory_girl`, `fabrication`, `fabricator`, `fixtures`, `active_record`
|
|
84
|
-
|
|
85
|
-
## Configuration Examples
|
|
86
|
-
|
|
87
|
-
### Minitest with FactoryBot Setup
|
|
40
|
+
This creates `config/initializers/tng.rb`:
|
|
88
41
|
|
|
89
42
|
```ruby
|
|
90
|
-
# config/initializers/tng.rb
|
|
91
43
|
Tng.configure do |config|
|
|
44
|
+
# Get your API key from https://app.tng.sh/
|
|
92
45
|
config.api_key = ENV["TNG_API_KEY"]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
config.
|
|
96
|
-
config.read_test_code = true
|
|
97
|
-
|
|
98
|
-
config.testing_framework = "minitest"
|
|
99
|
-
config.test_style = "test_block"
|
|
100
|
-
config.assertion_style = "assert/refute"
|
|
101
|
-
config.setup_style = true
|
|
102
|
-
config.teardown_style = false
|
|
103
|
-
|
|
104
|
-
config.mock_library = "minitest/mock"
|
|
105
|
-
config.http_mock_library = "webmock"
|
|
106
|
-
config.factory_library = "factory_bot"
|
|
107
|
-
|
|
108
|
-
config.authentication_enabled = true
|
|
109
|
-
config.authentication_methods = [
|
|
110
|
-
{
|
|
111
|
-
method: "authenticate_user!",
|
|
112
|
-
file_location: "app/controllers/application_controller.rb",
|
|
113
|
-
auth_type: "session"
|
|
114
|
-
}
|
|
115
|
-
]
|
|
46
|
+
|
|
47
|
+
# API endpoint (do not modify unless instructed)
|
|
48
|
+
config.base_url = ENV["API_BASE_URI"] || "https://app.tng.sh/"
|
|
116
49
|
end
|
|
117
50
|
```
|
|
118
51
|
|
|
119
|
-
###
|
|
52
|
+
### 2. Set Your API Key
|
|
120
53
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
config.base_url = "https://app.tng.sh/"
|
|
126
|
-
|
|
127
|
-
config.testing_framework = "rspec"
|
|
128
|
-
config.assertion_style = "expect"
|
|
129
|
-
config.describe_style = true
|
|
130
|
-
config.context_style = "context"
|
|
131
|
-
config.it_style = "it"
|
|
132
|
-
config.before_style = "before"
|
|
133
|
-
config.after_style = "after"
|
|
134
|
-
config.let_style = true
|
|
135
|
-
config.subject_style = true
|
|
136
|
-
|
|
137
|
-
config.mock_library = "rspec-mocks"
|
|
138
|
-
config.http_mock_library = "webmock"
|
|
139
|
-
config.factory_library = "factory_bot"
|
|
140
|
-
|
|
141
|
-
config.authentication_enabled = true
|
|
142
|
-
config.authentication_methods = [
|
|
143
|
-
{
|
|
144
|
-
method: "authenticate_user!",
|
|
145
|
-
file_location: "app/controllers/application_controller.rb",
|
|
146
|
-
auth_type: "devise"
|
|
147
|
-
}
|
|
148
|
-
]
|
|
149
|
-
end
|
|
54
|
+
Add to your `.env` file or export:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export TNG_API_KEY=your_api_key_here
|
|
150
58
|
```
|
|
151
59
|
|
|
152
|
-
|
|
60
|
+
Get your API key from [https://app.tng.sh/](https://app.tng.sh/)
|
|
153
61
|
|
|
154
|
-
|
|
155
|
-
# config/initializers/tng.rb
|
|
156
|
-
Tng.configure do |config|
|
|
157
|
-
config.api_key = ENV["TNG_API_KEY"]
|
|
158
|
-
config.base_url = "https://app.tng.sh/"
|
|
159
|
-
|
|
160
|
-
config.read_source_code = true
|
|
161
|
-
config.read_test_code = true
|
|
162
|
-
|
|
163
|
-
config.testing_framework = "minitest"
|
|
164
|
-
config.test_style = "test_block"
|
|
165
|
-
config.assertion_style = "assert/refute"
|
|
166
|
-
|
|
167
|
-
config.mock_library = "minitest/mock"
|
|
168
|
-
config.http_mock_library = "webmock"
|
|
169
|
-
config.factory_library = "fixtures"
|
|
170
|
-
|
|
171
|
-
config.authentication_enabled = true
|
|
172
|
-
config.authentication_methods = [
|
|
173
|
-
{
|
|
174
|
-
method: "authenticate_via_token!",
|
|
175
|
-
file_location: "app/controllers/application_controller.rb",
|
|
176
|
-
auth_type: "headers"
|
|
177
|
-
}
|
|
178
|
-
]
|
|
179
|
-
end
|
|
180
|
-
```
|
|
62
|
+
### 3. Start Using TNG
|
|
181
63
|
|
|
182
|
-
|
|
64
|
+
```bash
|
|
65
|
+
# Interactive mode (recommended)
|
|
66
|
+
bundle exec tng
|
|
183
67
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
Tng.configure do |config|
|
|
187
|
-
config.api_key = ENV["TNG_API_KEY"]
|
|
188
|
-
config.base_url = "https://app.tng.sh/"
|
|
189
|
-
config.testing_framework = "rspec"
|
|
190
|
-
config.assertion_style = "expect"
|
|
191
|
-
config.let_style = true
|
|
192
|
-
|
|
193
|
-
config.mock_library = "rspec-mocks"
|
|
194
|
-
config.http_mock_library = "webmock"
|
|
195
|
-
config.factory_library = "factory_bot"
|
|
196
|
-
|
|
197
|
-
config.authentication_enabled = true
|
|
198
|
-
config.authentication_methods = [
|
|
199
|
-
{
|
|
200
|
-
method: "authenticate_user!",
|
|
201
|
-
file_location: "app/controllers/application_controller.rb",
|
|
202
|
-
auth_type: "session"
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
method: "authenticate_api_user!",
|
|
206
|
-
file_location: "app/controllers/api/base_controller.rb",
|
|
207
|
-
auth_type: "token_auth"
|
|
208
|
-
}
|
|
209
|
-
]
|
|
210
|
-
|
|
211
|
-
config.authorization_library = "pundit"
|
|
212
|
-
end
|
|
68
|
+
# Or use direct commands
|
|
69
|
+
bundle exec tng --file app/models/user.rb --clones
|
|
213
70
|
```
|
|
214
71
|
|
|
215
|
-
##
|
|
72
|
+
## Usage
|
|
216
73
|
|
|
217
|
-
###
|
|
74
|
+
### Interactive Mode (TUI)
|
|
218
75
|
|
|
219
|
-
|
|
76
|
+
The most powerful way to use TNG:
|
|
220
77
|
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
{
|
|
224
|
-
method: "verify_custom_auth!",
|
|
225
|
-
file_location: "app/controllers/concerns/custom_auth.rb",
|
|
226
|
-
auth_type: "custom"
|
|
227
|
-
}
|
|
228
|
-
]
|
|
78
|
+
```bash
|
|
79
|
+
bundle exec tng
|
|
229
80
|
```
|
|
230
81
|
|
|
231
|
-
|
|
82
|
+
**Interactive Features:**
|
|
83
|
+
- ๐ **Browse** your application structure
|
|
84
|
+
- ๐งช **Generate Tests** for specific methods
|
|
85
|
+
- ๐ **Audit** methods for issues and improvements
|
|
86
|
+
- ๐ฌ **Trace** symbolic execution paths
|
|
87
|
+
- ๐ **Check Duplicates** across your codebase
|
|
88
|
+
- ๐ **Find Dead Code** in files
|
|
89
|
+
- ๐ **View Stats** and usage metrics
|
|
232
90
|
|
|
233
|
-
|
|
234
|
-
config.authentication_enabled = true
|
|
235
|
-
config.authentication_methods = [
|
|
236
|
-
{
|
|
237
|
-
method: "authenticate_with_token",
|
|
238
|
-
file_location: "app/controllers/application_controller.rb",
|
|
239
|
-
auth_type: "jwt"
|
|
240
|
-
}
|
|
241
|
-
]
|
|
242
|
-
config.factory_library = "fixtures" # Often simpler for API apps
|
|
243
|
-
```
|
|
91
|
+
### Command Line Interface
|
|
244
92
|
|
|
245
|
-
####
|
|
93
|
+
#### Test Generation
|
|
246
94
|
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
file_location: "app/controllers/application_controller.rb",
|
|
257
|
-
auth_type: "devise"
|
|
258
|
-
}
|
|
259
|
-
]
|
|
95
|
+
```bash
|
|
96
|
+
# Generate test for a specific method
|
|
97
|
+
bundle exec tng --file app/controllers/users_controller.rb --method index
|
|
98
|
+
|
|
99
|
+
# Short form
|
|
100
|
+
bundle exec tng -f users_controller.rb -m show
|
|
101
|
+
|
|
102
|
+
# Works from subdirectories (auto-detection)
|
|
103
|
+
bundle exec tng users_controller.rb index
|
|
260
104
|
```
|
|
261
105
|
|
|
262
|
-
|
|
106
|
+
**Supported File Types:**
|
|
107
|
+
Controllers, Models, Services, Jobs, Helpers, Lib, Policies, Presenters, Mailers, Serializers, Decorators, Forms, Queries, Channels, GraphQL (Resolvers, Types, Mutations, Loaders, Schemas), and more.
|
|
263
108
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
auth_type: "session"
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
method: "authenticate_api_key!",
|
|
278
|
-
file_location: "app/controllers/api/v1/base_controller.rb",
|
|
279
|
-
auth_type: "headers"
|
|
280
|
-
}
|
|
281
|
-
]
|
|
109
|
+
#### Code Audit
|
|
110
|
+
|
|
111
|
+
Analyze code for security, performance, and best practices:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Audit a specific method
|
|
115
|
+
bundle exec tng --file app/services/payment_service.rb --method process_payment --audit
|
|
116
|
+
|
|
117
|
+
# Interactive audit mode
|
|
118
|
+
bundle exec tng -f payment_service.rb -m process_payment -a
|
|
282
119
|
```
|
|
283
120
|
|
|
284
|
-
|
|
121
|
+
**Audit Checks:**
|
|
122
|
+
- Security vulnerabilities
|
|
123
|
+
- Performance bottlenecks
|
|
124
|
+
- Code smells
|
|
125
|
+
- Best practice violations
|
|
126
|
+
- Rails-specific patterns
|
|
285
127
|
|
|
286
|
-
|
|
128
|
+
#### Symbolic Trace
|
|
287
129
|
|
|
288
|
-
|
|
130
|
+
Visualize execution paths and generate Mermaid diagrams:
|
|
289
131
|
|
|
290
132
|
```bash
|
|
291
|
-
|
|
133
|
+
# Trace a method's execution flow
|
|
134
|
+
bundle exec tng --file app/models/order.rb --method calculate_total --trace
|
|
135
|
+
|
|
136
|
+
# Short form
|
|
137
|
+
bundle exec tng -f order.rb -m calculate_total -t
|
|
292
138
|
```
|
|
293
139
|
|
|
294
|
-
|
|
295
|
-
-
|
|
296
|
-
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
140
|
+
**Trace Features:**
|
|
141
|
+
- Control flow visualization
|
|
142
|
+
- Conditional path analysis
|
|
143
|
+
- Loop detection
|
|
144
|
+
- Method call chains
|
|
145
|
+
- Mermaid diagram generation
|
|
146
|
+
|
|
147
|
+
#### Clone Detection
|
|
299
148
|
|
|
300
|
-
|
|
149
|
+
Find duplicate code with 3 levels of detection:
|
|
301
150
|
|
|
302
|
-
|
|
151
|
+
```bash
|
|
152
|
+
# Check for all types of clones
|
|
153
|
+
bundle exec tng --file app/services/pricing_service.rb --clones
|
|
303
154
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
155
|
+
# Specific detection level
|
|
156
|
+
bundle exec tng --file app/services/pricing_service.rb --clones --level=1
|
|
157
|
+
bundle exec tng --file app/services/pricing_service.rb --clones --level=2
|
|
158
|
+
bundle exec tng --file app/services/pricing_service.rb --clones --level=3
|
|
308
159
|
|
|
309
|
-
|
|
160
|
+
# Short form
|
|
161
|
+
bundle exec tng -f pricing_service.rb -c
|
|
162
|
+
```
|
|
310
163
|
|
|
311
|
-
|
|
164
|
+
**Detection Levels:**
|
|
165
|
+
- **Level 1 (Token)** - Exact or near-exact duplicates (copy-paste detection)
|
|
166
|
+
- **Level 2 (Structural)** - Same AST structure with different names
|
|
167
|
+
- **Level 3 (Fuzzy)** - Similar logic with variations (up to 20% difference)
|
|
312
168
|
|
|
313
|
-
|
|
169
|
+
#### Dead Code Detection
|
|
170
|
+
|
|
171
|
+
Identify unreachable code and unused elements:
|
|
314
172
|
|
|
315
173
|
```bash
|
|
316
|
-
#
|
|
317
|
-
bundle exec tng app/
|
|
174
|
+
# Detect dead code in a file
|
|
175
|
+
bundle exec tng --file app/models/user.rb --deadcode
|
|
318
176
|
|
|
319
|
-
# Short form
|
|
320
|
-
bundle exec tng f
|
|
177
|
+
# Short form
|
|
178
|
+
bundle exec tng -f user.rb -d
|
|
321
179
|
|
|
322
|
-
#
|
|
323
|
-
bundle exec tng
|
|
180
|
+
# JSON output for CI/CD
|
|
181
|
+
bundle exec tng -f user.rb --deadcode --json
|
|
182
|
+
```
|
|
324
183
|
|
|
325
|
-
|
|
326
|
-
|
|
184
|
+
**Dead Code Types:**
|
|
185
|
+
- **Unreachable Code** - Code after `return`, `raise`, `exit`, etc.
|
|
186
|
+
- **Unused Variables** - Local variables assigned but never used
|
|
187
|
+
- **Unused Private Methods** - Private methods never called
|
|
188
|
+
- **Unused Parameters** - Method parameters never referenced
|
|
189
|
+
|
|
190
|
+
### JSON Output Mode
|
|
191
|
+
|
|
192
|
+
Get machine-readable output for CI/CD integration:
|
|
327
193
|
|
|
328
|
-
|
|
329
|
-
|
|
194
|
+
```bash
|
|
195
|
+
# Any command with --json flag
|
|
196
|
+
bundle exec tng --file app/models/user.rb --clones --json
|
|
197
|
+
bundle exec tng --file app/services/payment.rb --deadcode --json
|
|
198
|
+
bundle exec tng --file app/controllers/api_controller.rb --trace --json
|
|
330
199
|
```
|
|
331
200
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
201
|
+
## Advanced Features
|
|
202
|
+
|
|
203
|
+
### Method-Specific Analysis
|
|
204
|
+
|
|
205
|
+
TNG focuses on precise, method-level analysis:
|
|
206
|
+
|
|
207
|
+
- **Select specific methods** from any file type
|
|
208
|
+
- **Interactive browsing** with search and filter
|
|
209
|
+
- **Focused generation** for individual methods
|
|
210
|
+
- **No bulk generation** - designed for precision
|
|
211
|
+
|
|
212
|
+
### File Type Auto-Detection
|
|
213
|
+
|
|
214
|
+
No need to specify file types - TNG automatically detects:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# All of these work automatically
|
|
218
|
+
bundle exec tng users_controller.rb index
|
|
219
|
+
bundle exec tng user.rb validate_email
|
|
220
|
+
bundle exec tng payment_service.rb process
|
|
221
|
+
bundle exec tng user_mailer.rb welcome_email
|
|
222
|
+
bundle exec tng user_resolver.rb find_user
|
|
223
|
+
```
|
|
337
224
|
|
|
338
225
|
### Debug Mode
|
|
339
226
|
|
|
340
|
-
|
|
227
|
+
Enable detailed logging for troubleshooting:
|
|
341
228
|
|
|
342
229
|
```bash
|
|
343
|
-
# Interactive mode with debug on
|
|
344
230
|
DEBUG=1 bundle exec tng
|
|
231
|
+
DEBUG=1 bundle exec tng -f users_controller.rb -m index
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Examples
|
|
235
|
+
|
|
236
|
+
### Example 1: Find Duplicate Code
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
$ bundle exec tng --file app/services/pricing_service.rb --clones
|
|
240
|
+
|
|
241
|
+
๐ Clone Detection Results
|
|
345
242
|
|
|
346
|
-
|
|
347
|
-
|
|
243
|
+
Level 1 (Token): 2 matches found
|
|
244
|
+
โโ Lines 45-52 โ Lines 78-85 (8 lines, exact match)
|
|
245
|
+
โโ Lines 120-127 โ Lines 156-163 (8 lines, exact match)
|
|
246
|
+
|
|
247
|
+
Level 2 (Structural): 1 match found
|
|
248
|
+
โโ Lines 200-215 โ Lines 240-255 (16 nodes, complexity: 85)
|
|
249
|
+
|
|
250
|
+
Level 3 (Fuzzy): 1 match found
|
|
251
|
+
โโ Lines 300-320 โ Lines 350-370 (similar logic, 15% variation)
|
|
348
252
|
```
|
|
349
253
|
|
|
350
|
-
###
|
|
254
|
+
### Example 2: Detect Dead Code
|
|
351
255
|
|
|
352
256
|
```bash
|
|
353
|
-
bundle exec tng --
|
|
354
|
-
|
|
257
|
+
$ bundle exec tng --file app/models/user.rb --deadcode
|
|
258
|
+
|
|
259
|
+
๐ Dead Code Detection Results
|
|
260
|
+
|
|
261
|
+
[Unreachable Code] Line 42: Code follows terminal statement
|
|
262
|
+
42: puts "This will never execute"
|
|
263
|
+
|
|
264
|
+
[Unused Variable] Line 67: Variable 'temp' is assigned but never used
|
|
265
|
+
67: temp = calculate_something
|
|
266
|
+
|
|
267
|
+
[Unused Method] Line 120: Private method 'unused_helper' is never used
|
|
268
|
+
120: def unused_helper
|
|
269
|
+
|
|
270
|
+
[Unused Parameter] Line 85: Parameter 'options' is never used
|
|
271
|
+
85: def process(data, options)
|
|
355
272
|
```
|
|
356
273
|
|
|
357
|
-
|
|
274
|
+
### Example 3: Trace Execution Flow
|
|
358
275
|
|
|
359
|
-
|
|
276
|
+
```bash
|
|
277
|
+
$ bundle exec tng --file app/models/order.rb --method calculate_total --trace
|
|
278
|
+
|
|
279
|
+
๐ฌ Symbolic Trace Results
|
|
280
|
+
|
|
281
|
+
Execution Paths: 3
|
|
282
|
+
Complexity Score: 12
|
|
283
|
+
|
|
284
|
+
Path 1: items.empty? โ return 0
|
|
285
|
+
Path 2: discount_code.present? โ apply_discount โ calculate_tax โ total
|
|
286
|
+
Path 3: !discount_code.present? โ calculate_tax โ total
|
|
360
287
|
|
|
361
|
-
|
|
288
|
+
[Mermaid diagram saved to: trace_order_calculate_total.md]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## CLI Reference
|
|
292
|
+
|
|
293
|
+
### Flags
|
|
294
|
+
|
|
295
|
+
| Flag | Short | Description |
|
|
296
|
+
|------|-------|-------------|
|
|
297
|
+
| `--file` | `-f` | Target file path |
|
|
298
|
+
| `--method` | `-m` | Method name to analyze |
|
|
299
|
+
| `--audit` | `-a` | Run audit mode |
|
|
300
|
+
| `--trace` | `-t` | Run symbolic trace mode |
|
|
301
|
+
| `--clones` | `-c` | Run clone detection |
|
|
302
|
+
| `--deadcode` | `-d` | Run dead code detection |
|
|
303
|
+
| `--level` | `-l` | Clone detection level (1, 2, 3, or all) |
|
|
304
|
+
| `--json` | | Output as JSON |
|
|
305
|
+
| `--help` | `-h` | Show help message |
|
|
306
|
+
|
|
307
|
+
### Examples
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Test generation
|
|
311
|
+
bundle exec tng -f users_controller.rb -m index
|
|
312
|
+
|
|
313
|
+
# Code audit
|
|
314
|
+
bundle exec tng -f payment_service.rb -m process -a
|
|
315
|
+
|
|
316
|
+
# Symbolic trace
|
|
317
|
+
bundle exec tng -f order.rb -m calculate_total -t
|
|
318
|
+
|
|
319
|
+
# Clone detection (all levels)
|
|
320
|
+
bundle exec tng -f pricing_service.rb -c
|
|
321
|
+
|
|
322
|
+
# Clone detection (specific level)
|
|
323
|
+
bundle exec tng -f pricing_service.rb -c -l 2
|
|
324
|
+
|
|
325
|
+
# Dead code detection
|
|
326
|
+
bundle exec tng -f user.rb -d
|
|
327
|
+
|
|
328
|
+
# JSON output
|
|
329
|
+
bundle exec tng -f user.rb -c --json
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Troubleshooting
|
|
333
|
+
|
|
334
|
+
### API Key Issues
|
|
362
335
|
|
|
363
336
|
**Error: "Invalid API key"**
|
|
364
337
|
- Verify your API key from https://app.tng.sh/
|
|
365
|
-
- Check
|
|
366
|
-
- Ensure no extra spaces in `.env
|
|
338
|
+
- Check: `echo $TNG_API_KEY`
|
|
339
|
+
- Ensure no extra spaces in `.env`: `TNG_API_KEY=your_key_here`
|
|
367
340
|
|
|
368
341
|
**Error: "API key not found"**
|
|
369
342
|
- Set environment variable: `export TNG_API_KEY=your_key`
|
|
370
343
|
- Or add to `.env` file: `TNG_API_KEY=your_key`
|
|
371
|
-
- Restart Rails server after
|
|
344
|
+
- Restart Rails server after changes
|
|
372
345
|
|
|
373
|
-
|
|
346
|
+
### Configuration Issues
|
|
374
347
|
|
|
375
348
|
**Error: "Invalid configuration"**
|
|
376
|
-
- Run
|
|
377
|
-
- Verify
|
|
349
|
+
- Run: `rails console` then `Tng.configuration`
|
|
350
|
+
- Verify `config/initializers/tng.rb` exists
|
|
378
351
|
- Check for typos in configuration file
|
|
379
352
|
|
|
380
|
-
**Poor Test Quality**
|
|
381
|
-
- Verify authentication methods are correctly configured
|
|
382
|
-
- Check factory library setting matches your setup
|
|
383
|
-
- Ensure `read_source_code` and `read_test_code` are enabled
|
|
384
|
-
- Review testing framework settings match your project
|
|
385
|
-
|
|
386
|
-
#### Authentication Configuration Issues
|
|
387
|
-
|
|
388
|
-
**Tests don't include authentication**
|
|
389
|
-
- Verify `authentication_enabled = true`
|
|
390
|
-
- Check authentication methods are correctly specified
|
|
391
|
-
- Ensure file paths exist: `ls app/controllers/application_controller.rb`
|
|
392
|
-
- Verify method names exist in specified files
|
|
393
|
-
|
|
394
|
-
**Authentication tests fail**
|
|
395
|
-
- Check auth method names match your application
|
|
396
|
-
- Verify file locations are correct
|
|
397
|
-
- Ensure auth_type matches your authentication pattern
|
|
398
|
-
|
|
399
353
|
### Generation Issues
|
|
400
354
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
3. Configuration is valid
|
|
407
|
-
4. API key is working
|
|
408
|
-
5. Internet connection is available
|
|
355
|
+
**No tests generated:**
|
|
356
|
+
1. Verify file path: `ls app/controllers/users_controller.rb`
|
|
357
|
+
2. Check file contains valid Ruby code
|
|
358
|
+
3. Verify API key is working
|
|
359
|
+
4. Check internet connection
|
|
409
360
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
-
|
|
414
|
-
- Factory library setting doesn't match your setup
|
|
415
|
-
- `read_source_code` or `read_test_code` disabled
|
|
416
|
-
- File analysis failed (check DEBUG mode)
|
|
361
|
+
**Poor test quality:**
|
|
362
|
+
- Ensure you're using the latest version
|
|
363
|
+
- Try audit mode for better insights
|
|
364
|
+
- Check file is properly formatted
|
|
417
365
|
|
|
418
366
|
### Debug Mode
|
|
419
367
|
|
|
420
|
-
Enable debug
|
|
368
|
+
Enable debug output for detailed information:
|
|
421
369
|
|
|
422
370
|
```bash
|
|
423
|
-
DEBUG=1 bundle exec tng
|
|
371
|
+
DEBUG=1 bundle exec tng -f users_controller.rb -m index
|
|
424
372
|
```
|
|
425
373
|
|
|
426
374
|
Debug output includes:
|
|
427
|
-
- API request/response
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
375
|
+
- API request/response details
|
|
376
|
+
- File analysis results
|
|
377
|
+
- Configuration validation
|
|
378
|
+
- Error stack traces
|
|
379
|
+
|
|
380
|
+
## What's New in v0.4.8
|
|
381
|
+
|
|
382
|
+
### New Features
|
|
383
|
+
- โจ **Level 3 Fuzzy Clone Detection** - Find similar code with variations
|
|
384
|
+
- โจ **Dead Code Detection** - Identify unreachable code and unused elements
|
|
385
|
+
- โจ **Simplified Configuration** - Only API key required to get started
|
|
386
|
+
- โจ **Enhanced Clone Detection** - 3 levels of duplicate detection
|
|
387
|
+
- โจ **Improved UI** - Better visualization of results
|
|
388
|
+
|
|
389
|
+
### Improvements
|
|
390
|
+
- โก Faster file analysis with optimized Rust parsers
|
|
391
|
+
- ๐จ Better error messages and user feedback
|
|
392
|
+
- ๐ Enhanced reporting for all analysis modes
|
|
393
|
+
- ๐ง Auto-detection of file types and test frameworks
|
|
394
|
+
|
|
395
|
+
## Getting Help
|
|
396
|
+
|
|
397
|
+
If you're experiencing issues:
|
|
398
|
+
- Check the troubleshooting section above
|
|
399
|
+
- Enable debug mode: `DEBUG=1 bundle exec tng`
|
|
400
|
+
- Contact support at https://app.tng.sh/
|
|
401
|
+
- Open a GitHub issue for bug reports
|
|
432
402
|
|
|
433
403
|
## License
|
|
434
404
|
|
data/Rakefile
CHANGED
|
@@ -75,9 +75,17 @@ task :redo do
|
|
|
75
75
|
# Code sign the bundles on macOS
|
|
76
76
|
if RUBY_PLATFORM.include?("darwin")
|
|
77
77
|
puts "๐ Signing bundles..."
|
|
78
|
+
system("xattr -dr com.apple.quarantine binaries/ || true")
|
|
79
|
+
|
|
80
|
+
# Sign tng bundle
|
|
78
81
|
system("codesign --force --sign - #{source_file}")
|
|
79
82
|
system("codesign --force --sign - #{File.join(destination_dir, binary_name)}")
|
|
80
83
|
|
|
84
|
+
# Sign go-ui binaries if present
|
|
85
|
+
Dir.glob("binaries/go-ui-darwin-*").each do |binary|
|
|
86
|
+
system("codesign --force --sign - #{binary}")
|
|
87
|
+
end
|
|
88
|
+
|
|
81
89
|
# Also sign the gem installation if it exists
|
|
82
90
|
ruby_version = RUBY_VERSION.split(".")[0..1].join(".")
|
|
83
91
|
gem_bundle = File.expand_path("~/.local/share/mise/installs/ruby/#{RUBY_VERSION}/lib/ruby/gems/#{ruby_version}.0/gems/tng-*/binaries/tng.bundle")
|
data/bin/tng
CHANGED
|
@@ -48,6 +48,10 @@ class CLI
|
|
|
48
48
|
example "Duplicate Detection:", ""
|
|
49
49
|
example " bundle exec tng app/services/pricing_service.rb --clones", ""
|
|
50
50
|
example " bundle exec tng --file=users_controller.rb --clones --level=2", ""
|
|
51
|
+
example ""
|
|
52
|
+
example "Dead Code Detection:", ""
|
|
53
|
+
example " bundle exec tng app/models/user.rb --deadcode", ""
|
|
54
|
+
example " bundle exec tng --file=app/services/auth_service.rb -d", ""
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
option :file do
|
|
@@ -68,10 +72,16 @@ class CLI
|
|
|
68
72
|
desc "Run in clone detection mode (find code duplication)"
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
flag :deadcode do
|
|
76
|
+
short "-d"
|
|
77
|
+
long "--deadcode"
|
|
78
|
+
desc "Run in dead code detection mode (unreachable code, unused variables)"
|
|
79
|
+
end
|
|
80
|
+
|
|
71
81
|
option :level do
|
|
72
82
|
short "-l"
|
|
73
83
|
long "--level=LEVEL"
|
|
74
|
-
desc "Analysis level: 1 (Token), 2 (Structural), all (
|
|
84
|
+
desc "Analysis level: 1 (Token), 2 (Structural), 3 (Fuzzy), all (All levels)"
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
flag :audit do
|
|
@@ -140,6 +150,8 @@ class CLI
|
|
|
140
150
|
handle_fix_command
|
|
141
151
|
elsif params[:trace] && params[:file]
|
|
142
152
|
run_direct_trace
|
|
153
|
+
elsif params[:deadcode] && params[:file]
|
|
154
|
+
run_dead_code_detection
|
|
143
155
|
elsif params[:file]
|
|
144
156
|
run_direct_generation
|
|
145
157
|
else
|
|
@@ -153,7 +165,10 @@ class CLI
|
|
|
153
165
|
return unless check_configuration
|
|
154
166
|
|
|
155
167
|
check_system_status
|
|
168
|
+
# puts "DEBUG: Verifying authentication..."
|
|
156
169
|
return unless check_authentication
|
|
170
|
+
# puts "DEBUG: Authentication verified."
|
|
171
|
+
|
|
157
172
|
|
|
158
173
|
clear_screen
|
|
159
174
|
@go_ui.show_banner(Tng::VERSION)
|
|
@@ -181,6 +196,8 @@ class CLI
|
|
|
181
196
|
normalized << "--fix"
|
|
182
197
|
when /^(?:--)?(clones|c)$/
|
|
183
198
|
normalized << "--clones"
|
|
199
|
+
when /^(?:--)?(deadcode|d)$/
|
|
200
|
+
normalized << "--deadcode"
|
|
184
201
|
when /^(?:--)?(level|l)=(.+)$/
|
|
185
202
|
normalized << "--level=#{::Regexp.last_match(2)}"
|
|
186
203
|
when /^(help|h)=(.+)$/
|
|
@@ -242,6 +259,8 @@ class CLI
|
|
|
242
259
|
handle_trace_method
|
|
243
260
|
when "clones"
|
|
244
261
|
handle_clone_detection
|
|
262
|
+
when "deadcode"
|
|
263
|
+
handle_dead_code_detection_menu
|
|
245
264
|
when "stats"
|
|
246
265
|
user_stats
|
|
247
266
|
when "about"
|
|
@@ -506,6 +525,35 @@ class CLI
|
|
|
506
525
|
@go_ui.show_audit_results(audit_data, "issues")
|
|
507
526
|
end
|
|
508
527
|
|
|
528
|
+
def run_dead_code_detection
|
|
529
|
+
file_path = params[:file]
|
|
530
|
+
unless File.exist?(file_path)
|
|
531
|
+
puts @pastel.red("Error: File '#{file_path}' not found.")
|
|
532
|
+
return
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
absolute_path = File.expand_path(file_path)
|
|
536
|
+
json_output = params[:json] || false
|
|
537
|
+
|
|
538
|
+
begin
|
|
539
|
+
# Always get JSON from Rust for flexibility
|
|
540
|
+
result = Tng.detect_dead_code(absolute_path, true)
|
|
541
|
+
|
|
542
|
+
if json_output
|
|
543
|
+
puts result
|
|
544
|
+
else
|
|
545
|
+
if @go_ui
|
|
546
|
+
@go_ui.show_dead_code_results(absolute_path, result)
|
|
547
|
+
else
|
|
548
|
+
# Fallback to text output
|
|
549
|
+
puts Tng.detect_dead_code(absolute_path, false)
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
rescue => e
|
|
553
|
+
puts @pastel.red("Error detecting dead code: #{e.message}")
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
|
|
509
557
|
# Placeholder methods for other component types
|
|
510
558
|
def audit_model_method
|
|
511
559
|
models = nil
|
|
@@ -1470,18 +1518,129 @@ class CLI
|
|
|
1470
1518
|
choice = files.find { |f| f[:name] == selected }
|
|
1471
1519
|
next unless choice
|
|
1472
1520
|
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
end
|
|
1521
|
+
# For dead code, we don't need to select a method, just the file.
|
|
1522
|
+
# But this helper yields (file_choice, method_choice).
|
|
1523
|
+
# We might need a simpler selector for dead code if it's file-based only.
|
|
1524
|
+
# Re-using method selector for now if we want per-method, but dead code is usually per-file.
|
|
1478
1525
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
next if m_selected == "back"
|
|
1526
|
+
# Actually, dead code analysis is whole-file.
|
|
1527
|
+
# So we should probably just return the file choice.
|
|
1482
1528
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1529
|
+
# Let's implement specific helpers for dead code that just pick files.
|
|
1530
|
+
end
|
|
1531
|
+
end
|
|
1532
|
+
|
|
1533
|
+
def handle_dead_code_detection_menu
|
|
1534
|
+
# Pick a file type first to narrow down
|
|
1535
|
+
choice = @go_ui.show_test_type_menu("deadcode")
|
|
1536
|
+
return if choice == "back"
|
|
1537
|
+
|
|
1538
|
+
case choice
|
|
1539
|
+
when "controller"
|
|
1540
|
+
detect_dead_code_for_type("app/controllers", Tng::Analyzers::Controller)
|
|
1541
|
+
when "model"
|
|
1542
|
+
detect_dead_code_for_type("app/models", Tng::Analyzers::Model)
|
|
1543
|
+
when "service"
|
|
1544
|
+
# Service analyzer is a bit different, it scans app/services usually
|
|
1545
|
+
detect_dead_code_for_service
|
|
1546
|
+
when "other"
|
|
1547
|
+
detect_dead_code_for_other
|
|
1548
|
+
end
|
|
1549
|
+
end
|
|
1550
|
+
|
|
1551
|
+
def detect_dead_code_for_type(dir, analyzer_class)
|
|
1552
|
+
files = nil
|
|
1553
|
+
@go_ui.show_spinner("Analyzing files in #{dir}...") do
|
|
1554
|
+
files = analyzer_class.files_in_dir(dir).map do |file|
|
|
1555
|
+
relative_path = file[:path].gsub(%r{^.*#{dir}/}, "").gsub(".rb", "")
|
|
1556
|
+
namespaced_name = relative_path.split("/").map(&:camelize).join("::")
|
|
1557
|
+
{ name: namespaced_name, path: file[:path] }
|
|
1558
|
+
end
|
|
1559
|
+
{ success: true, message: "Found #{files.length} files" }
|
|
1560
|
+
end
|
|
1561
|
+
|
|
1562
|
+
return @go_ui.show_no_items(dir) if files.empty?
|
|
1563
|
+
|
|
1564
|
+
items = files.map { |f| { name: f[:name], path: f[:path] } }
|
|
1565
|
+
|
|
1566
|
+
loop do
|
|
1567
|
+
selected = @go_ui.show_list_view("Select File to Analyze", items)
|
|
1568
|
+
return if selected == "back"
|
|
1569
|
+
|
|
1570
|
+
choice = files.find { |f| f[:name] == selected }
|
|
1571
|
+
next unless choice
|
|
1572
|
+
|
|
1573
|
+
# Run detection on the file
|
|
1574
|
+
run_dead_code_detection_interactive(choice[:path])
|
|
1575
|
+
end
|
|
1576
|
+
end
|
|
1577
|
+
|
|
1578
|
+
def detect_dead_code_for_service
|
|
1579
|
+
services = nil
|
|
1580
|
+
@go_ui.show_spinner("Analyzing services...") do
|
|
1581
|
+
services = Tng::Analyzers::Service.files_in_dir.map do |file|
|
|
1582
|
+
relative_path = file[:path].gsub(%r{^.*app/services?/}, "").gsub(".rb", "")
|
|
1583
|
+
namespaced_name = relative_path.split("/").map(&:camelize).join("::")
|
|
1584
|
+
{ name: namespaced_name, path: file[:path] }
|
|
1585
|
+
end
|
|
1586
|
+
{ success: true, message: "Found #{services.length} services" }
|
|
1587
|
+
end
|
|
1588
|
+
|
|
1589
|
+
return @go_ui.show_no_items("services") if services.empty?
|
|
1590
|
+
|
|
1591
|
+
items = services.map { |s| { name: s[:name], path: s[:path] } }
|
|
1592
|
+
|
|
1593
|
+
loop do
|
|
1594
|
+
selected = @go_ui.show_list_view("Select Service to Analyze", items)
|
|
1595
|
+
return if selected == "back"
|
|
1596
|
+
|
|
1597
|
+
choice = services.find { |s| s[:name] == selected }
|
|
1598
|
+
next unless choice
|
|
1599
|
+
|
|
1600
|
+
run_dead_code_detection_interactive(choice[:path])
|
|
1601
|
+
end
|
|
1602
|
+
end
|
|
1603
|
+
|
|
1604
|
+
def detect_dead_code_for_other
|
|
1605
|
+
files = nil
|
|
1606
|
+
@go_ui.show_spinner("Analyzing other files...") do
|
|
1607
|
+
files = Tng::Analyzers::Other.files_in_dir.map do |file|
|
|
1608
|
+
relative_path = file[:relative_path].gsub(".rb", "")
|
|
1609
|
+
namespaced_name = relative_path.split("/").map(&:camelize).join("::")
|
|
1610
|
+
{ name: namespaced_name, path: file[:path], type: file[:type] }
|
|
1611
|
+
end
|
|
1612
|
+
{ success: true, message: "Found #{files.length} other files" }
|
|
1613
|
+
end
|
|
1614
|
+
|
|
1615
|
+
return @go_ui.show_no_items("other files") if files.empty?
|
|
1616
|
+
|
|
1617
|
+
items = files.map { |f| { name: f[:name], path: f[:path] } }
|
|
1618
|
+
|
|
1619
|
+
loop do
|
|
1620
|
+
selected = @go_ui.show_list_view("Select File to Analyze", items)
|
|
1621
|
+
return if selected == "back"
|
|
1622
|
+
|
|
1623
|
+
choice = files.find { |f| f[:name] == selected }
|
|
1624
|
+
next unless choice
|
|
1625
|
+
|
|
1626
|
+
run_dead_code_detection_interactive(choice[:path])
|
|
1627
|
+
end
|
|
1628
|
+
end
|
|
1629
|
+
|
|
1630
|
+
def run_dead_code_detection_interactive(path)
|
|
1631
|
+
@go_ui.show_spinner("Detecting dead code...") do
|
|
1632
|
+
# Just a visual delay or setup if needed
|
|
1633
|
+
sleep(0.5)
|
|
1634
|
+
{ success: true, message: "Analysis complete" }
|
|
1635
|
+
end
|
|
1636
|
+
|
|
1637
|
+
# Reuse the CLI logic but bypass params
|
|
1638
|
+
absolute_path = File.expand_path(path)
|
|
1639
|
+
begin
|
|
1640
|
+
result = Tng.detect_dead_code(absolute_path, true)
|
|
1641
|
+
@go_ui.show_dead_code_results(absolute_path, result)
|
|
1642
|
+
rescue => e
|
|
1643
|
+
@go_ui.display_error("Error detecting dead code: #{e.message}")
|
|
1485
1644
|
end
|
|
1486
1645
|
end
|
|
1487
1646
|
end
|
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
|
@@ -272,6 +272,35 @@ module Tng
|
|
|
272
272
|
_cleanup_temp_file(input_path)
|
|
273
273
|
end
|
|
274
274
|
|
|
275
|
+
def show_dead_code_results(file_path, results_json)
|
|
276
|
+
parsed = JSON.parse(results_json)
|
|
277
|
+
|
|
278
|
+
# Rust returns {"file": "...", "dead_code": [...]}
|
|
279
|
+
issues = parsed["dead_code"] || []
|
|
280
|
+
|
|
281
|
+
data = {
|
|
282
|
+
file: file_path,
|
|
283
|
+
dead_code: issues.map do |issue|
|
|
284
|
+
{
|
|
285
|
+
type: issue["type"],
|
|
286
|
+
line: issue["line"],
|
|
287
|
+
message: issue["message"],
|
|
288
|
+
code: issue["code"]
|
|
289
|
+
}
|
|
290
|
+
end
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
input_path = _create_temp_file("go_ui_dead_code", ".json")
|
|
294
|
+
File.write(input_path, JSON.generate(data))
|
|
295
|
+
|
|
296
|
+
system(@binary_path, "deadcode", "--file", input_path)
|
|
297
|
+
rescue StandardError => e
|
|
298
|
+
puts "Dead code results error: #{e.message}"
|
|
299
|
+
ensure
|
|
300
|
+
_cleanup_temp_file(input_path)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
|
|
275
304
|
# Show authentication error
|
|
276
305
|
# @param message [String] Error message to display
|
|
277
306
|
def show_auth_error(message = "Authentication failed")
|
|
@@ -346,7 +375,8 @@ module Tng
|
|
|
346
375
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD", desc: "Direct test generation" },
|
|
347
376
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --audit", desc: "Direct audit mode" },
|
|
348
377
|
{ cmd: "bundle exec tng --file=FILE --method=METHOD --trace", desc: "Symbolic trace mode" },
|
|
349
|
-
{ cmd: "bundle exec tng --file=FILE --clones", desc: "Check for code duplicates" }
|
|
378
|
+
{ cmd: "bundle exec tng --file=FILE --clones", desc: "Check for code duplicates" },
|
|
379
|
+
{ cmd: "bundle exec tng --file=FILE --deadcode", desc: "Run dead code detection" }
|
|
350
380
|
],
|
|
351
381
|
features: [
|
|
352
382
|
"Controllers, Models, Services",
|
|
@@ -355,6 +385,7 @@ module Tng
|
|
|
355
385
|
"Code audit for issues & behaviors",
|
|
356
386
|
"Symbolic execution traces",
|
|
357
387
|
"Duplicate code detection (Clones)",
|
|
388
|
+
"Dead code detection (Rust-powered)",
|
|
358
389
|
"Searchable method lists"
|
|
359
390
|
],
|
|
360
391
|
options: [
|
|
@@ -364,15 +395,17 @@ module Tng
|
|
|
364
395
|
{ flag: "--audit", desc: "Run audit mode instead of test generation" },
|
|
365
396
|
{ flag: "--trace", desc: "Run symbolic trace mode" },
|
|
366
397
|
{ flag: "--clones", desc: "Run clone detection mode" },
|
|
367
|
-
{ flag: "--level=1|2|all", desc: "Set clone detection level (default: all)" }
|
|
398
|
+
{ flag: "--level=1|2|3|all", desc: "Set clone detection level (default: all)" },
|
|
399
|
+
{ flag: "--deadcode", desc: "Run dead code detection" }
|
|
368
400
|
],
|
|
369
401
|
how_to: [
|
|
370
402
|
"Run 'bundle exec tng' for interactive mode",
|
|
371
403
|
"Run 'tng [file] --clones' for duplicate detection",
|
|
404
|
+
"Run 'tng [file] --deadcode' for dead code analysis",
|
|
372
405
|
"Select Controller, Model, or Service to start",
|
|
373
406
|
"Choose a method to generate/audit or select 'Check Duplicates'"
|
|
374
407
|
],
|
|
375
|
-
footer: "
|
|
408
|
+
footer: ""
|
|
376
409
|
}
|
|
377
410
|
|
|
378
411
|
system(@binary_path, "help-box", "--version", version, "--data", JSON.generate(help_data))
|
|
@@ -478,8 +511,14 @@ module Tng
|
|
|
478
511
|
File.expand_path("binaries/#{binary_name}", Dir.pwd)
|
|
479
512
|
]
|
|
480
513
|
|
|
514
|
+
# puts "DEBUG: Searching for binary #{binary_name} in:"
|
|
515
|
+
# binary_paths.each { |p| puts " - #{p}" }
|
|
516
|
+
|
|
481
517
|
binary_paths.each do |path|
|
|
482
|
-
|
|
518
|
+
if File.exist?(path) && File.executable?(path)
|
|
519
|
+
# puts "DEBUG: Found binary at #{path}"
|
|
520
|
+
return path
|
|
521
|
+
end
|
|
483
522
|
end
|
|
484
523
|
|
|
485
524
|
raise "go-ui binary not found. Searched: #{binary_paths.join(", ")}"
|
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.4.
|
|
4
|
+
version: 0.4.8
|
|
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.4.
|
|
225
|
+
v0.4.8 โ\n"
|
|
226
226
|
rdoc_options: []
|
|
227
227
|
require_paths:
|
|
228
228
|
- lib
|