tng 0.1.2 → 0.1.4
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 +0 -79
- data/bin/tng +26 -0
- data/lib/generators/tng/install_generator.rb +21 -13
- data/lib/tng/services/testng.rb +1 -1
- data/lib/tng/ui/about_display.rb +33 -40
- data/lib/tng/ui/authentication_warning_display.rb +172 -0
- data/lib/tng/ui/configuration_display.rb +32 -26
- data/lib/tng/ui/controller_test_flow_display.rb +35 -28
- data/lib/tng/ui/display_banner.rb +13 -23
- data/lib/tng/ui/goodbye_display.rb +14 -23
- data/lib/tng/ui/model_test_flow_display.rb +34 -32
- data/lib/tng/ui/post_install_box.rb +35 -26
- data/lib/tng/ui/service_test_flow_display.rb +34 -28
- data/lib/tng/ui/show_help.rb +82 -47
- data/lib/tng/ui/system_status_display.rb +101 -30
- data/lib/tng/ui/theme.rb +248 -0
- data/lib/tng/ui/user_stats_display.rb +50 -43
- data/lib/tng/version.rb +1 -1
- data/lib/tng.rb +14 -0
- data/tng.gemspec +4 -4
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58907277090e7b363bd0907be694ee5023ec4b18b0d24a4ab0956ba2e29fd648
|
4
|
+
data.tar.gz: 055abaa322144382a523118edbef976b6ded86425b18d5c6b0308c5e282d3d89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e321fee31b6b91e63c54a318b30f28b66cf05e4e342a2cca2fbc67d1fa76e86ee9102fd788ede777bd6d8f80f32bc7d46bfa985db7b82d4e1b91efe2e32addc3
|
7
|
+
data.tar.gz: eca7b0234cf41ef0466f4016229a9236c577e4b0488a227ffa96cfb2baac4587309e70dc95ef6460bad0b4225f98582f00e1c2a50c310e7259a39e3d97f0c3ea
|
data/README.md
CHANGED
@@ -18,55 +18,6 @@ And then execute:
|
|
18
18
|
bundle install
|
19
19
|
```
|
20
20
|
|
21
|
-
### Local Gem Installation
|
22
|
-
|
23
|
-
If you have a local `.gem` file (e.g., for beta versions):
|
24
|
-
|
25
|
-
#### Option 1: Direct Installation (Recommended)
|
26
|
-
|
27
|
-
```bash
|
28
|
-
gem install ~/Downloads/tng-0.1.0.gem
|
29
|
-
```
|
30
|
-
|
31
|
-
Then add to your `Gemfile`:
|
32
|
-
```ruby
|
33
|
-
gem "tng", "~> 0.1.0"
|
34
|
-
```
|
35
|
-
|
36
|
-
Run bundle install:
|
37
|
-
```bash
|
38
|
-
bundle install
|
39
|
-
```
|
40
|
-
|
41
|
-
#### Option 2: Vendor Path Installation
|
42
|
-
|
43
|
-
1. Create vendor directory structure:
|
44
|
-
```bash
|
45
|
-
mkdir -p vendor/gems
|
46
|
-
```
|
47
|
-
|
48
|
-
2. Unpack the gem:
|
49
|
-
```bash
|
50
|
-
cd vendor/gems
|
51
|
-
rm -rf tng-0.1.0 # Remove existing folder if it exists
|
52
|
-
gem unpack ~/Downloads/tng-0.1.0.gem
|
53
|
-
cd ../..
|
54
|
-
```
|
55
|
-
|
56
|
-
3. Add to your `Gemfile`:
|
57
|
-
```ruby
|
58
|
-
gem "tng", path: "vendor/gems/tng-0.1.0"
|
59
|
-
```
|
60
|
-
|
61
|
-
4. Run bundle install:
|
62
|
-
```bash
|
63
|
-
bundle install
|
64
|
-
```
|
65
|
-
|
66
|
-
### Installation Troubleshooting
|
67
|
-
|
68
|
-
For detailed installation troubleshooting, see the [Troubleshooting](#troubleshooting) section.
|
69
|
-
|
70
21
|
## Configuration
|
71
22
|
|
72
23
|
TNG requires proper configuration to generate high-quality tests. Generate the configuration file by running:
|
@@ -397,36 +348,6 @@ bundle exec tng -h # Short help
|
|
397
348
|
|
398
349
|
## Troubleshooting
|
399
350
|
|
400
|
-
### Installation Issues
|
401
|
-
|
402
|
-
#### Gem Installation Problems
|
403
|
-
|
404
|
-
**Error: "Could not find gem 'tng'"**
|
405
|
-
- Ensure you installed the gem file first: `gem install ~/Downloads/tng-0.1.0.gem`
|
406
|
-
- Check installed gems: `gem list tng`
|
407
|
-
- Verify gem name and version in Gemfile matches installed gem
|
408
|
-
|
409
|
-
**Error: "No such file ~/Downloads/tng-0.1.0.gem"**
|
410
|
-
- Verify correct path to downloaded gem file
|
411
|
-
- Use `ls ~/Downloads/tng*` to check exact filename
|
412
|
-
|
413
|
-
**Error: "Could not find gem 'tng' in source" (vendor path)**
|
414
|
-
- Verify path points to correct unpacked directory
|
415
|
-
- Ensure `vendor/gems/tng-0.1.0/` contains `.gemspec` file
|
416
|
-
- Check gem was unpacked correctly: `gem unpack ~/Downloads/tng-0.1.0.gem`
|
417
|
-
|
418
|
-
#### Binary Loading Problems
|
419
|
-
|
420
|
-
**Error: "Native extension not found"**
|
421
|
-
- Check your platform is supported (macOS or Linux x86_64)
|
422
|
-
- Verify binary exists: `ls vendor/gems/tng-*/lib/tng/`
|
423
|
-
- Try reinstalling: `bundle install --force`
|
424
|
-
|
425
|
-
**Error: "Symbol not found" or "Library not loaded"**
|
426
|
-
- macOS: Ensure you have Xcode command line tools: `xcode-select --install`
|
427
|
-
- Linux: Ensure glibc compatibility
|
428
|
-
- Try clearing gem cache: `gem cleanup tng`
|
429
|
-
|
430
351
|
### Configuration Issues
|
431
352
|
|
432
353
|
#### API Key Problems
|
data/bin/tng
CHANGED
@@ -23,6 +23,7 @@ require "tng/ui/show_help"
|
|
23
23
|
require "tng/ui/post_install_box"
|
24
24
|
require "tng/ui/system_status_display"
|
25
25
|
require "tng/ui/configuration_display"
|
26
|
+
require "tng/ui/authentication_warning_display"
|
26
27
|
require "tng/ui/display_banner"
|
27
28
|
require "tng/ui/user_stats_display"
|
28
29
|
require "tng/ui/about_display"
|
@@ -503,6 +504,9 @@ class CLI
|
|
503
504
|
|
504
505
|
return if test_option == :back
|
505
506
|
|
507
|
+
# Check authentication configuration before proceeding with test generation
|
508
|
+
return unless check_authentication_configuration
|
509
|
+
|
506
510
|
case test_option
|
507
511
|
when :all_possible_tests
|
508
512
|
generate_test_for_controller(controller_choice)
|
@@ -517,6 +521,9 @@ class CLI
|
|
517
521
|
|
518
522
|
return if test_option == :back
|
519
523
|
|
524
|
+
# Check authentication configuration before proceeding with test generation
|
525
|
+
return unless check_authentication_configuration
|
526
|
+
|
520
527
|
case test_option
|
521
528
|
when :all_possible_tests
|
522
529
|
generate_test_for_model(model_choice)
|
@@ -531,6 +538,9 @@ class CLI
|
|
531
538
|
|
532
539
|
return if test_option == :back
|
533
540
|
|
541
|
+
# Check authentication configuration before proceeding with test generation
|
542
|
+
return unless check_authentication_configuration
|
543
|
+
|
534
544
|
case test_option
|
535
545
|
when :all_possible_tests
|
536
546
|
generate_test_for_service(service_choice)
|
@@ -853,6 +863,19 @@ class CLI
|
|
853
863
|
false
|
854
864
|
end
|
855
865
|
|
866
|
+
def check_authentication_configuration
|
867
|
+
auth_warning = AuthenticationWarningDisplay.new(@pastel)
|
868
|
+
auth_missing = auth_warning.display_if_missing
|
869
|
+
|
870
|
+
if auth_missing
|
871
|
+
# User chose to cancel (pressed Esc)
|
872
|
+
return false
|
873
|
+
end
|
874
|
+
|
875
|
+
# User chose to continue (pressed Enter) or no auth issues
|
876
|
+
true
|
877
|
+
end
|
878
|
+
|
856
879
|
# ABOUT
|
857
880
|
def show_about
|
858
881
|
AboutDisplay.new(@pastel, @prompt, Tng::VERSION).display
|
@@ -877,6 +900,9 @@ class CLI
|
|
877
900
|
# Check configuration first
|
878
901
|
return unless check_configuration
|
879
902
|
|
903
|
+
# Check authentication configuration
|
904
|
+
return unless check_authentication_configuration
|
905
|
+
|
880
906
|
# Check system status (but don't show the spinner in direct mode)
|
881
907
|
status = @testng.check_system_status
|
882
908
|
unless SystemStatusDisplay.new(@pastel, params).display(status)
|
@@ -68,6 +68,7 @@ module Tng
|
|
68
68
|
"",
|
69
69
|
"Tng.configure do |config|",
|
70
70
|
" config.api_key = nil",
|
71
|
+
" # You dont need to change this url, unless you will instructed by the CLI.",
|
71
72
|
" config.base_url = \"https://app.tng.sh/\"",
|
72
73
|
" config.read_source_code = true # Options: true, false",
|
73
74
|
" config.read_test_code = true # Options: true, false",
|
@@ -83,21 +84,28 @@ module Tng
|
|
83
84
|
" #{auth_enabled} # Options: true, false",
|
84
85
|
" #{auth_lib} # Options: devise, clearance, sorcery, nil",
|
85
86
|
"",
|
87
|
+
"",
|
88
|
+
" # ⚠️ IMPORTANT: AUTHENTICATION CONFIGURATION REQUIRED ⚠️",
|
89
|
+
" # You MUST configure your authentication methods below for TNG to work properly.",
|
90
|
+
" # Uncomment and modify the authentication_methods configuration:",
|
91
|
+
"",
|
86
92
|
" # Authentication Methods (multiple methods supported)",
|
87
93
|
" # Supported authentication types: session, devise, jwt, token_auth, basic_auth, oauth, headers, custom, nil",
|
88
|
-
" # Uncomment and
|
94
|
+
" # EXAMPLE: Uncomment and modify these examples to match your app's authentication:",
|
95
|
+
"",
|
89
96
|
" # config.authentication_methods = [",
|
90
|
-
"
|
91
|
-
"
|
92
|
-
"
|
93
|
-
"
|
94
|
-
"
|
95
|
-
"
|
96
|
-
"
|
97
|
-
"
|
98
|
-
"
|
99
|
-
"
|
97
|
+
" # {",
|
98
|
+
" # method: \"authenticate_user_via_session!\",",
|
99
|
+
" # file_location: \"app/controllers/application_controller.rb\",",
|
100
|
+
" # auth_type: \"session\"",
|
101
|
+
" # },",
|
102
|
+
" # {",
|
103
|
+
" # method: \"authenticate_user_via_api_key!\",",
|
104
|
+
" # file_location: \"app/controllers/application_controller.rb\",",
|
105
|
+
" # auth_type: \"headers\"",
|
106
|
+
" # }",
|
100
107
|
" # ]",
|
108
|
+
" # ⚠️ Remember to configure your authentication methods above! ⚠️",
|
101
109
|
"",
|
102
110
|
" # Authorization#{authz_comment}",
|
103
111
|
" #{authz_lib} # Options: cancancan, pundit, rolify, nil",
|
@@ -209,12 +217,12 @@ module Tng
|
|
209
217
|
|
210
218
|
def generate_framework_specific_config(framework, framework_config)
|
211
219
|
if framework == "minitest"
|
212
|
-
|
220
|
+
" config.test_style = \"#{framework_config["test_style"]}\" # Options: spec, unit, test_block\n" +
|
213
221
|
" config.setup_style = #{framework_config["setup_style"]} # Options: true, false\n" +
|
214
222
|
" config.assertion_style = \"#{framework_config["assertion_style"]}\" # Options: assert/refute, assert/assert_not, must/wont\n" +
|
215
223
|
" config.teardown_style = #{framework_config["teardown_style"]} # Options: true, false"
|
216
224
|
else # rspec
|
217
|
-
|
225
|
+
" config.describe_style = #{framework_config["describe_style"]} # Options: true, false\n" +
|
218
226
|
" config.context_style = \"#{framework_config["context_style"]}\" # Options: context, describe\n" +
|
219
227
|
" config.it_style = \"#{framework_config["it_style"]}\" # Options: it, specify\n" +
|
220
228
|
" config.before_style = \"#{framework_config["before_style"]}\" # Options: before, setup\n" +
|
data/lib/tng/services/testng.rb
CHANGED
@@ -25,7 +25,7 @@ module Services
|
|
25
25
|
server_base_url = data["base_url"]
|
26
26
|
user_base_url = Tng::Services::UserAppConfig.base_url
|
27
27
|
|
28
|
-
if current_version
|
28
|
+
if current_version > Tng::VERSION
|
29
29
|
return {
|
30
30
|
status: :version_mismatch,
|
31
31
|
message: "Version mismatch detected",
|
data/lib/tng/ui/about_display.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "tty-box"
|
4
4
|
require "pastel"
|
5
5
|
require "tty-screen"
|
6
|
+
require_relative "theme"
|
6
7
|
|
7
8
|
class AboutDisplay
|
8
9
|
def initialize(pastel, prompt, version)
|
@@ -10,62 +11,54 @@ class AboutDisplay
|
|
10
11
|
@prompt = prompt
|
11
12
|
@version = version
|
12
13
|
@terminal_width = begin
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
TTY::Screen.width
|
15
|
+
rescue StandardError
|
16
|
+
80
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def display
|
20
21
|
about_content = [
|
21
|
-
@pastel.
|
22
|
+
@pastel.public_send(Tng::UI::Theme.color(:secondary)).bold("About Tng"),
|
22
23
|
"",
|
23
|
-
@pastel.
|
24
|
+
@pastel.public_send(Tng::UI::Theme.color(:primary),
|
25
|
+
"Tng is an LLM-powered test generation tool for Rails applications."),
|
24
26
|
"",
|
25
|
-
@pastel.
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
27
|
+
@pastel.public_send(Tng::UI::Theme.color(:accent), "Features:"),
|
28
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Controller test generation"),
|
29
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Model test generation"),
|
30
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Service test generation"),
|
31
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} LLM-powered test suggestions"),
|
32
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Test coverage analysis"),
|
30
33
|
"",
|
31
|
-
@pastel.
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
@pastel.public_send(Tng::UI::Theme.color(:accent), "Technology:"),
|
35
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
36
|
+
"#{Tng::UI::Theme.icon(:bullet)} Static code analysis with Prism"),
|
37
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
38
|
+
"#{Tng::UI::Theme.icon(:bullet)} Intelligent pattern recognition"),
|
39
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Rails-specific optimizations"),
|
35
40
|
"",
|
36
|
-
@pastel.
|
37
|
-
@pastel.
|
41
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "Version: #{@version}"),
|
42
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
43
|
+
"Built with #{Tng::UI::Theme.icon(:heart)} for Rails developers")
|
38
44
|
].join("\n")
|
39
45
|
|
40
|
-
box_width =
|
46
|
+
box_width = Tng::UI::Theme.calculate_box_width(@terminal_width)
|
47
|
+
style = Tng::UI::Theme.box_style(:default)
|
48
|
+
|
41
49
|
about_box = TTY::Box.frame(
|
42
50
|
title: { top_left: " About Tng " },
|
43
|
-
style:
|
44
|
-
|
45
|
-
border: { fg: :cyan },
|
46
|
-
title: { fg: :bright_cyan }
|
47
|
-
},
|
48
|
-
padding: [1, 2],
|
51
|
+
style: style[:style],
|
52
|
+
padding: style[:padding],
|
49
53
|
width: box_width
|
50
54
|
) do
|
51
55
|
about_content
|
52
56
|
end
|
53
57
|
|
54
|
-
puts center_box(about_box, box_width)
|
55
|
-
@prompt.keypress(center_text(
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def center_text(text)
|
61
|
-
padding = (@terminal_width - @pastel.strip(text).length) / 2
|
62
|
-
padding = 0 if padding.negative?
|
63
|
-
(" " * padding) + text
|
64
|
-
end
|
65
|
-
|
66
|
-
def center_box(box_string, box_width)
|
67
|
-
padding = (@terminal_width - box_width) / 2
|
68
|
-
padding = 0 if padding.negative?
|
69
|
-
box_string.lines.map { |line| (" " * padding) + line.chomp }.join("\n")
|
58
|
+
puts Tng::UI::Theme.center_box(about_box, box_width, @terminal_width)
|
59
|
+
@prompt.keypress(Tng::UI::Theme.center_text(
|
60
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
61
|
+
"Press any key to continue..."), @terminal_width
|
62
|
+
))
|
70
63
|
end
|
71
64
|
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-box"
|
4
|
+
require "pastel"
|
5
|
+
require "tty-screen"
|
6
|
+
require_relative "theme"
|
7
|
+
|
8
|
+
class AuthenticationWarningDisplay
|
9
|
+
def initialize(pastel)
|
10
|
+
@pastel = pastel
|
11
|
+
@terminal_width = begin
|
12
|
+
TTY::Screen.width
|
13
|
+
rescue StandardError
|
14
|
+
80
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def display_if_missing
|
19
|
+
return false unless authentication_config_missing?
|
20
|
+
|
21
|
+
display_warning
|
22
|
+
handle_user_choice
|
23
|
+
end
|
24
|
+
|
25
|
+
def display_warning
|
26
|
+
warning_content = [
|
27
|
+
@pastel.public_send(Tng::UI::Theme.color(:error)).bold("Authentication Configuration Missing"),
|
28
|
+
"",
|
29
|
+
@pastel.public_send(Tng::UI::Theme.color(:primary), "TNG needs authentication setup to generate proper tests."),
|
30
|
+
"",
|
31
|
+
@pastel.public_send(Tng::UI::Theme.color(:accent), "Missing: ") + build_missing_items_summary,
|
32
|
+
"",
|
33
|
+
@pastel.public_send(Tng::UI::Theme.color(:secondary), "Quick fix:"),
|
34
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
35
|
+
"#{Tng::UI::Theme.icon(:bullet)} Edit config/initializers/tng.rb"),
|
36
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
37
|
+
"#{Tng::UI::Theme.icon(:bullet)} Uncomment authentication_methods array"),
|
38
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted), "#{Tng::UI::Theme.icon(:bullet)} Add your auth method details"),
|
39
|
+
"",
|
40
|
+
@pastel.public_send(Tng::UI::Theme.color(:success), "Press Enter to continue anyway"),
|
41
|
+
@pastel.public_send(Tng::UI::Theme.color(:error), "Press Esc to cancel and fix configuration")
|
42
|
+
].join("\n")
|
43
|
+
|
44
|
+
box_width = Tng::UI::Theme.calculate_box_width(@terminal_width)
|
45
|
+
style = Tng::UI::Theme.box_style(:warning)
|
46
|
+
|
47
|
+
warning_box = TTY::Box.frame(
|
48
|
+
title: { top_left: " Auth Warning " },
|
49
|
+
style: style[:style],
|
50
|
+
padding: style[:padding],
|
51
|
+
width: box_width
|
52
|
+
) do
|
53
|
+
warning_content
|
54
|
+
end
|
55
|
+
|
56
|
+
puts Tng::UI::Theme.center_box(warning_box, box_width, @terminal_width)
|
57
|
+
puts
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def handle_user_choice
|
63
|
+
require "io/console"
|
64
|
+
|
65
|
+
loop do
|
66
|
+
key = $stdin.getch
|
67
|
+
case key
|
68
|
+
when "\r", "\n" # Enter key
|
69
|
+
return false # Continue anyway
|
70
|
+
when "\e" # Escape key
|
71
|
+
return true # Cancel (authentication missing)
|
72
|
+
when "\u0003" # Ctrl+C
|
73
|
+
puts "\n#{@pastel.public_send(Tng::UI::Theme.color(:warning), "Operation cancelled.")}"
|
74
|
+
exit(0)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
rescue StandardError
|
78
|
+
# Fallback if getch is not available
|
79
|
+
puts @pastel.public_send(Tng::UI::Theme.color(:muted), "Press Enter to continue or Ctrl+C to cancel...")
|
80
|
+
gets
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_missing_items_summary
|
85
|
+
issues = []
|
86
|
+
|
87
|
+
issues << "empty auth methods" if Tng.authentication_enabled && authentication_methods_empty?
|
88
|
+
|
89
|
+
issues << "invalid auth config" if !authentication_methods_empty? && !authentication_methods_valid?
|
90
|
+
|
91
|
+
issues << "auth disabled" unless Tng.authentication_enabled
|
92
|
+
|
93
|
+
issues.empty? ? "unknown issue" : issues.join(", ")
|
94
|
+
end
|
95
|
+
|
96
|
+
def authentication_config_missing?
|
97
|
+
# Check if authentication is enabled but methods are not configured
|
98
|
+
return true if Tng.authentication_enabled && authentication_methods_empty?
|
99
|
+
|
100
|
+
# Check if authentication methods exist but are invalid
|
101
|
+
return true if !authentication_methods_empty? && !authentication_methods_valid?
|
102
|
+
|
103
|
+
false
|
104
|
+
end
|
105
|
+
|
106
|
+
def authentication_methods_empty?
|
107
|
+
methods = Tng.authentication_methods
|
108
|
+
methods.nil? || methods.empty?
|
109
|
+
end
|
110
|
+
|
111
|
+
def authentication_methods_valid?
|
112
|
+
methods = Tng.authentication_methods
|
113
|
+
return false if methods.nil? || methods.empty?
|
114
|
+
|
115
|
+
methods.all? do |method|
|
116
|
+
method.is_a?(Hash) &&
|
117
|
+
method.key?(:method) && !method[:method].to_s.strip.empty? &&
|
118
|
+
method.key?(:file_location) && !method[:file_location].to_s.strip.empty? &&
|
119
|
+
method.key?(:auth_type) && !method[:auth_type].to_s.strip.empty?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def build_missing_items_list
|
124
|
+
issues = []
|
125
|
+
|
126
|
+
if Tng.authentication_enabled && authentication_methods_empty?
|
127
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:error), " • authentication_methods array is empty")
|
128
|
+
end
|
129
|
+
|
130
|
+
if !authentication_methods_empty? && !authentication_methods_valid?
|
131
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:error), " • authentication_methods contains invalid entries")
|
132
|
+
|
133
|
+
Tng.authentication_methods.each_with_index do |method, index|
|
134
|
+
next if method.is_a?(Hash)
|
135
|
+
|
136
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:muted), " - Entry #{index + 1}: not a valid hash")
|
137
|
+
next
|
138
|
+
end
|
139
|
+
|
140
|
+
Tng.authentication_methods.each_with_index do |method, index|
|
141
|
+
next unless method.is_a?(Hash)
|
142
|
+
|
143
|
+
if !method.key?(:method) || method[:method].to_s.strip.empty?
|
144
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:muted),
|
145
|
+
" - Entry #{index + 1}: missing or empty 'method'")
|
146
|
+
end
|
147
|
+
|
148
|
+
if !method.key?(:file_location) || method[:file_location].to_s.strip.empty?
|
149
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:muted),
|
150
|
+
" - Entry #{index + 1}: missing or empty 'file_location'")
|
151
|
+
end
|
152
|
+
|
153
|
+
if !method.key?(:auth_type) || method[:auth_type].to_s.strip.empty?
|
154
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:muted),
|
155
|
+
" - Entry #{index + 1}: missing or empty 'auth_type'")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
unless Tng.authentication_enabled
|
161
|
+
issues << @pastel.public_send(Tng::UI::Theme.color(:warning),
|
162
|
+
" • authentication_enabled is set to false")
|
163
|
+
end
|
164
|
+
|
165
|
+
if issues.empty?
|
166
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
167
|
+
" • Configuration appears valid")
|
168
|
+
else
|
169
|
+
issues.join("\n")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "tty-box"
|
3
4
|
require "pastel"
|
4
5
|
require "tty-screen"
|
6
|
+
require_relative "theme"
|
5
7
|
|
6
8
|
class ConfigurationDisplay
|
7
9
|
def initialize(pastel)
|
@@ -14,33 +16,37 @@ class ConfigurationDisplay
|
|
14
16
|
end
|
15
17
|
|
16
18
|
def display_missing_config(missing_config)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
puts @pastel.dim("💡 Verify the generated setup corresponds to your project settings.")
|
35
|
-
puts
|
36
|
-
puts @pastel.yellow("After configuring, run 'bundle exec tng' again.")
|
37
|
-
end
|
19
|
+
config_content = [
|
20
|
+
@pastel.public_send(Tng::UI::Theme.color(:error)).bold("Configuration Required"),
|
21
|
+
"",
|
22
|
+
@pastel.public_send(Tng::UI::Theme.color(:accent), "Missing required configuration:"),
|
23
|
+
missing_config.map do |key|
|
24
|
+
@pastel.public_send(Tng::UI::Theme.color(:secondary), "#{Tng::UI::Theme.icon(:bullet)} #{key}")
|
25
|
+
end.join("\n"),
|
26
|
+
"",
|
27
|
+
@pastel.public_send(Tng::UI::Theme.color(:secondary), "Quick fix:"),
|
28
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
29
|
+
"#{Tng::UI::Theme.icon(:bullet)} Edit config/initializers/tng.rb"),
|
30
|
+
@pastel.public_send(Tng::UI::Theme.color(:muted),
|
31
|
+
"#{Tng::UI::Theme.icon(:bullet)} Set your API key and other required values"),
|
32
|
+
"",
|
33
|
+
@pastel.public_send(Tng::UI::Theme.color(:success), "Press Enter to continue after fixing"),
|
34
|
+
@pastel.public_send(Tng::UI::Theme.color(:error), "Press Ctrl+C to exit")
|
35
|
+
].join("\n")
|
38
36
|
|
39
|
-
|
37
|
+
box_width = Tng::UI::Theme.calculate_box_width(@terminal_width)
|
38
|
+
style = Tng::UI::Theme.box_style(:error)
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
config_box = TTY::Box.frame(
|
41
|
+
title: { top_left: " Config Required " },
|
42
|
+
style: style[:style],
|
43
|
+
padding: style[:padding],
|
44
|
+
width: box_width
|
45
|
+
) do
|
46
|
+
config_content
|
47
|
+
end
|
48
|
+
|
49
|
+
puts Tng::UI::Theme.center_box(config_box, box_width, @terminal_width)
|
50
|
+
puts
|
45
51
|
end
|
46
52
|
end
|