console_kit 0.1.3 → 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/.reek.yml +4 -0
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +7 -0
- data/SECURITY.md +28 -0
- data/lib/console_kit/configuration.rb +8 -4
- data/lib/console_kit/connections/base_connection_handler.rb +18 -0
- data/lib/console_kit/connections/connection_manager.rb +24 -0
- data/lib/console_kit/connections/mongo_connection_handler.rb +26 -0
- data/lib/console_kit/connections/sql_connection_handler.rb +24 -0
- data/lib/console_kit/output.rb +11 -8
- data/lib/console_kit/railtie.rb +1 -1
- data/lib/console_kit/setup.rb +22 -30
- data/lib/console_kit/tenant_configurator.rb +26 -26
- data/lib/console_kit/tenant_selector.rb +40 -27
- data/lib/console_kit/version.rb +1 -1
- data/lib/console_kit.rb +1 -0
- data/lib/generators/console_kit/install_generator.rb +3 -2
- metadata +8 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 634e983d59fba9a10d608945d11f0be809c4b3008612c804489a0ee18fd8bcf0
|
|
4
|
+
data.tar.gz: 646bf39efa3b81058524433d88852906313c20e0b584b1e205386bae45b8e638
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70f8f1282f3e6a63588187a86de442b663f17efd40773f7ad6c2916a21917549917d5fa9fba688774e18608f173e8126cee711cb468faf94efdda1ef7653151d
|
|
7
|
+
data.tar.gz: 436bfcb527f71341dd2f6fe1b865a884b4e4208a4dec75820e2bc46068de85db706f2e037e2b1aa94f07091600e204c35ef89cff612dd2bb103ae6d1baa414f7
|
data/.reek.yml
ADDED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [0.1.4] - 2025-09-30
|
|
10
|
+
### Added
|
|
11
|
+
- Minor Fixes and Improvements
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
9
15
|
## [0.1.3] - 2025-08-12
|
|
10
16
|
### Added
|
|
11
17
|
- `ConsoleKit.current_tenant` method to retrieve the current tenant at runtime.
|
|
@@ -50,6 +56,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
50
56
|
|
|
51
57
|
## [Unreleased]
|
|
52
58
|
|
|
59
|
+
[0.1.4]: https://github.com/Soumyadeep-ai/console_kit/releases/tag/v0.1.4
|
|
53
60
|
[0.1.3]: https://github.com/Soumyadeep-ai/console_kit/releases/tag/v0.1.3
|
|
54
61
|
[0.1.2]: https://github.com/Soumyadeep-ai/console_kit/releases/tag/v0.1.2
|
|
55
62
|
[0.1.1]: https://github.com/Soumyadeep-ai/console_kit/releases/tag/v0.1.1
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
We do **not maintain multiple supported versions**. Only the latest released version is eligible for security updates.
|
|
6
|
+
|
|
7
|
+
Once a new version is released, the previous version is branched and locked, and will no longer receive updates — including security patches.
|
|
8
|
+
|
|
9
|
+
| Version | Supported |
|
|
10
|
+
| ------- | ------------------ |
|
|
11
|
+
| 0.1.4 | :white_check_mark: |
|
|
12
|
+
| 0.1.3 | :x: |
|
|
13
|
+
| 0.1.2 | :x: |
|
|
14
|
+
| 0.1.1 | :x: |
|
|
15
|
+
| 0.1.0 | :x: |
|
|
16
|
+
|
|
17
|
+
## Reporting a Vulnerability
|
|
18
|
+
|
|
19
|
+
If you discover a security vulnerability, please use the GitHub [Security Advisories](https://github.com/Soumyadeep-ai/console_kit/security/advisories/new) feature to report it privately.
|
|
20
|
+
|
|
21
|
+
We follow this process:
|
|
22
|
+
- All reported vulnerabilities are reviewed promptly.
|
|
23
|
+
- A new version with security fixes will be released.
|
|
24
|
+
- Once validated, we will publish an advisory and issue a patched release if necessary.
|
|
25
|
+
|
|
26
|
+
Please avoid disclosing vulnerabilities publicly until we’ve had a chance to review and respond.
|
|
27
|
+
|
|
28
|
+
For more details, visit [GitHub Docs: Reporting a Vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability).
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ConsoleKit
|
|
4
|
-
# Stores configurations
|
|
4
|
+
# Stores ConsoleKit configurations such as tenant map and context behavior
|
|
5
5
|
class Configuration
|
|
6
|
-
|
|
6
|
+
attr_reader :pretty_output, :tenants, :context_class
|
|
7
7
|
|
|
8
|
-
def initialize(
|
|
9
|
-
@pretty_output =
|
|
8
|
+
def initialize(tenants: nil, context_class: nil)
|
|
9
|
+
@pretty_output = true
|
|
10
10
|
@tenants = tenants
|
|
11
11
|
@context_class = context_class
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
%i[pretty_output tenants context_class].each do |attr|
|
|
15
|
+
define_method("#{attr}=") { |value| instance_variable_set("@#{attr}", value) }
|
|
16
|
+
end
|
|
13
17
|
end
|
|
14
18
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConsoleKit
|
|
4
|
+
module Connections
|
|
5
|
+
# Parent class for connection handlers
|
|
6
|
+
class BaseConnectionHandler
|
|
7
|
+
attr_reader :context
|
|
8
|
+
|
|
9
|
+
def initialize(context) = @context = context
|
|
10
|
+
|
|
11
|
+
def connect
|
|
12
|
+
raise NotImplementedError, "#{self.class} must implement #connect"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def available? = false
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'sql_connection_handler'
|
|
4
|
+
require_relative 'mongo_connection_handler'
|
|
5
|
+
|
|
6
|
+
module ConsoleKit
|
|
7
|
+
module Connections
|
|
8
|
+
# Manages available connection handlers
|
|
9
|
+
class ConnectionManager
|
|
10
|
+
class << self
|
|
11
|
+
def available_handlers(context)
|
|
12
|
+
handler_classes.filter_map do |klass|
|
|
13
|
+
handler = klass.new(context)
|
|
14
|
+
handler if handler.available?
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def handler_classes = BaseConnectionHandler.descendants
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
require_relative 'base_connection_handler'
|
|
5
|
+
|
|
6
|
+
module ConsoleKit
|
|
7
|
+
module Connections
|
|
8
|
+
# Handles MongoDB connections
|
|
9
|
+
class MongoConnectionHandler < BaseConnectionHandler
|
|
10
|
+
extend Forwardable
|
|
11
|
+
|
|
12
|
+
def_delegator :@context, :tenant_mongo_db
|
|
13
|
+
|
|
14
|
+
def connect
|
|
15
|
+
return if tenant_mongo_db.blank?
|
|
16
|
+
|
|
17
|
+
Output.print_info("Switching to MongoDB client: #{tenant_mongo_db}")
|
|
18
|
+
Mongoid.override_client(tenant_mongo_db)
|
|
19
|
+
rescue NoMethodError
|
|
20
|
+
Output.print_warning('Mongoid.override_client is not defined.')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def available? = defined?(Mongoid)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
require_relative 'base_connection_handler'
|
|
5
|
+
|
|
6
|
+
module ConsoleKit
|
|
7
|
+
module Connections
|
|
8
|
+
# Handles SQL connections
|
|
9
|
+
class SqlConnectionHandler < BaseConnectionHandler
|
|
10
|
+
extend Forwardable
|
|
11
|
+
|
|
12
|
+
def_delegator :@context, :tenant_shard
|
|
13
|
+
|
|
14
|
+
def connect
|
|
15
|
+
return if tenant_shard.blank?
|
|
16
|
+
|
|
17
|
+
Output.print_info("Establishing SQL connection to shard: #{tenant_shard}")
|
|
18
|
+
ApplicationRecord.establish_connection(tenant_shard.to_sym)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def available? = defined?(ApplicationRecord)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/console_kit/output.rb
CHANGED
|
@@ -16,30 +16,33 @@ module ConsoleKit
|
|
|
16
16
|
|
|
17
17
|
class << self
|
|
18
18
|
TYPES.each_key do |type|
|
|
19
|
-
define_method("print_#{type}") do |text|
|
|
19
|
+
define_method("print_#{type}") do |text, timestamp: false|
|
|
20
20
|
formatted = (type == :header ? "\n=== #{text} ===" : text)
|
|
21
|
-
print_with(type, formatted)
|
|
21
|
+
print_with(type, formatted, timestamp)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# Backtrace prints always with timestamp, no param
|
|
25
26
|
def print_backtrace(exception)
|
|
26
|
-
exception&.backtrace&.each { |line| print_with(:trace, " #{line}") }
|
|
27
|
+
exception&.backtrace&.each { |line| print_with(:trace, " #{line}", true) }
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
private
|
|
30
31
|
|
|
31
|
-
def print_with(type, text, timestamp
|
|
32
|
-
meta = TYPES
|
|
32
|
+
def print_with(type, text, timestamp)
|
|
33
|
+
meta = TYPES.fetch(type)
|
|
33
34
|
message = build_message(text, meta[:symbol], timestamp)
|
|
34
35
|
output(message, meta[:color])
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def build_message(text, symbol, timestamp)
|
|
38
|
-
|
|
39
|
-
sym = symbol ? "#{symbol} " : ''
|
|
40
|
-
"#{PREFIX} #{time}#{sym}#{text}"
|
|
39
|
+
"#{PREFIX} #{timestamp_prefix(timestamp)}#{symbol_prefix(symbol)}#{text}"
|
|
41
40
|
end
|
|
42
41
|
|
|
42
|
+
def prefix_for(value) = value ? yield(value) : ''
|
|
43
|
+
def timestamp_prefix(timestamp) = prefix_for(timestamp) { Time.current.strftime('[%Y-%m-%d %H:%M:%S] ') }
|
|
44
|
+
def symbol_prefix(symbol) = prefix_for(symbol) { |sym| "#{sym} " }
|
|
45
|
+
|
|
43
46
|
def output(message, color)
|
|
44
47
|
return puts message unless ConsoleKit.configuration.pretty_output && color
|
|
45
48
|
|
data/lib/console_kit/railtie.rb
CHANGED
data/lib/console_kit/setup.rb
CHANGED
|
@@ -11,34 +11,39 @@ module ConsoleKit
|
|
|
11
11
|
class << self
|
|
12
12
|
attr_reader :current_tenant
|
|
13
13
|
|
|
14
|
-
def setup
|
|
15
|
-
return Output.print_error('No tenants configured.') if no_tenants?
|
|
16
|
-
|
|
17
|
-
key = select_tenant_key
|
|
18
|
-
return Output.print_error('No tenant selected. Loading without tenant configuration.') unless key
|
|
19
|
-
|
|
20
|
-
configure(key)
|
|
21
|
-
rescue StandardError => e
|
|
22
|
-
handle_error(e)
|
|
23
|
-
end
|
|
24
|
-
|
|
14
|
+
def setup = run_setup
|
|
25
15
|
def tenant_setup_successful? = !@current_tenant.to_s.empty?
|
|
26
16
|
|
|
27
17
|
def reset_current_tenant
|
|
28
18
|
return warn_no_tenants unless tenants?
|
|
29
19
|
|
|
30
20
|
warn_reset if @current_tenant
|
|
31
|
-
TenantConfigurator.clear
|
|
21
|
+
TenantConfigurator.clear if @current_tenant
|
|
32
22
|
|
|
33
23
|
@current_tenant = nil
|
|
34
24
|
setup
|
|
35
|
-
tenant_setup_successful?
|
|
36
25
|
end
|
|
37
26
|
|
|
38
27
|
private
|
|
39
28
|
|
|
29
|
+
def run_setup
|
|
30
|
+
return Output.print_error('No tenants configured.') if no_tenants?
|
|
31
|
+
|
|
32
|
+
select_and_configure
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
handle_error(e)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def select_and_configure
|
|
38
|
+
key = select_tenant_key
|
|
39
|
+
return Output.print_error('No tenant selected. Loading without tenant configuration.') unless key
|
|
40
|
+
|
|
41
|
+
configure(key)
|
|
42
|
+
end
|
|
43
|
+
|
|
40
44
|
def configure(key)
|
|
41
|
-
|
|
45
|
+
TenantConfigurator.configure_tenant(key)
|
|
46
|
+
return unless TenantConfigurator.configuration_success
|
|
42
47
|
|
|
43
48
|
@current_tenant = key
|
|
44
49
|
Output.print_success("Tenant initialized: #{key}")
|
|
@@ -48,25 +53,12 @@ module ConsoleKit
|
|
|
48
53
|
def context_class = ConsoleKit.configuration.context_class
|
|
49
54
|
def tenants? = tenants&.any?
|
|
50
55
|
def no_tenants? = !tenants?
|
|
51
|
-
|
|
52
|
-
def select_tenant_key
|
|
53
|
-
return tenants.keys.first if auto_select?
|
|
54
|
-
|
|
55
|
-
TenantSelector.select(tenants, tenants.keys)
|
|
56
|
-
end
|
|
57
|
-
|
|
56
|
+
def select_tenant_key = auto_select? ? tenants.keys.first : TenantSelector.select
|
|
58
57
|
def auto_select? = single_tenant? || non_interactive?
|
|
59
58
|
def single_tenant? = tenants.size == 1
|
|
60
59
|
def non_interactive? = !$stdin.tty?
|
|
61
|
-
|
|
62
|
-
def
|
|
63
|
-
Output.print_warning('Cannot reset tenant: No tenants configured.')
|
|
64
|
-
false
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def warn_reset
|
|
68
|
-
Output.print_warning("Resetting tenant: #{@current_tenant}")
|
|
69
|
-
end
|
|
60
|
+
def warn_no_tenants = Output.print_warning('Cannot reset tenant: No tenants configured.')
|
|
61
|
+
def warn_reset = Output.print_warning("Resetting tenant: #{@current_tenant}")
|
|
70
62
|
|
|
71
63
|
def handle_error(error)
|
|
72
64
|
Output.print_error("Error setting up tenant: #{error.message}")
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'output'
|
|
4
|
+
require_relative 'connections/connection_manager'
|
|
4
5
|
|
|
5
6
|
module ConsoleKit
|
|
6
7
|
# For tenant configuration
|
|
7
8
|
module TenantConfigurator
|
|
8
9
|
class << self
|
|
9
|
-
|
|
10
|
-
constants = tenants[key]&.[](:constants)
|
|
11
|
-
return missing_config_error(key) unless constants
|
|
10
|
+
attr_reader :configuration_success
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
def configure_tenant(key)
|
|
13
|
+
constants = ConsoleKit.configuration.tenants[key]&.[](:constants)
|
|
14
|
+
return missing_config_error(key) unless constants
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
true
|
|
16
|
+
perform_configuration(key, constants)
|
|
19
17
|
rescue StandardError => e
|
|
20
18
|
handle_error(e, key)
|
|
21
|
-
false
|
|
22
19
|
end
|
|
23
20
|
|
|
24
|
-
def clear
|
|
21
|
+
def clear
|
|
22
|
+
@configuration_success = false
|
|
25
23
|
%i[tenant_shard tenant_mongo_db partner_identifier].each do |attr|
|
|
26
|
-
context_class.public_send("#{attr}=", nil)
|
|
24
|
+
ConsoleKit.configuration.context_class.public_send("#{attr}=", nil)
|
|
27
25
|
end
|
|
28
26
|
Output.print_info('Tenant context has been cleared.')
|
|
29
27
|
end
|
|
@@ -36,34 +34,36 @@ module ConsoleKit
|
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def missing_config_error(key)
|
|
37
|
+
@configuration_success = false
|
|
39
38
|
Output.print_error("No configuration found for tenant: #{key}")
|
|
40
|
-
false
|
|
41
39
|
end
|
|
42
40
|
|
|
43
|
-
def
|
|
41
|
+
def perform_configuration(key, constants)
|
|
42
|
+
validate_constants!(constants)
|
|
43
|
+
apply_context(constants)
|
|
44
|
+
configure_success(key)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def apply_context(constant)
|
|
48
|
+
ctx = ConsoleKit.configuration.context_class
|
|
44
49
|
ctx.tenant_shard = constant[:shard]
|
|
45
50
|
ctx.tenant_mongo_db = constant[:mongo_db]
|
|
46
51
|
ctx.partner_identifier = constant[:partner_code]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def setup_connections(ctx)
|
|
50
|
-
ApplicationRecord.establish_connection(ctx.tenant_shard.to_sym) if defined?(ApplicationRecord)
|
|
51
|
-
return unless defined?(Mongoid) && Mongoid.respond_to?(:override_client)
|
|
52
|
-
return if ctx.tenant_mongo_db.nil? || ctx.tenant_mongo_db.empty?
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
Mongoid.override_client(client)
|
|
53
|
+
setup_connections(ctx)
|
|
56
54
|
end
|
|
57
55
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return if context_class.tenant_mongo_db.nil? || context_class.tenant_mongo_db.empty?
|
|
56
|
+
def setup_connections(context)
|
|
57
|
+
ConsoleKit::Connections::ConnectionManager.available_handlers(context).each(&:connect)
|
|
58
|
+
end
|
|
62
59
|
|
|
63
|
-
|
|
60
|
+
def configure_success(key)
|
|
61
|
+
Output.print_success("Tenant set to: #{key}")
|
|
62
|
+
@configuration_success = true
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
def handle_error(error, key)
|
|
66
|
+
@configuration_success = false
|
|
67
67
|
Output.print_error("Failed to configure tenant '#{key}': #{error.message}")
|
|
68
68
|
Output.print_backtrace(error)
|
|
69
69
|
end
|
|
@@ -5,51 +5,64 @@ require_relative 'output'
|
|
|
5
5
|
module ConsoleKit
|
|
6
6
|
# For tenant selection
|
|
7
7
|
module TenantSelector
|
|
8
|
+
RETRY_LIMIT = 3
|
|
9
|
+
DEFAULT_SELECTION = '1'
|
|
10
|
+
|
|
8
11
|
class << self
|
|
9
|
-
def select
|
|
10
|
-
|
|
12
|
+
def select
|
|
13
|
+
attempt_selection(RETRY_LIMIT)
|
|
14
|
+
end
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
index = prompt_user_for_selection(keys.size)
|
|
14
|
-
return nil if index.zero?
|
|
15
|
-
return keys[index - 1] if index.positive?
|
|
16
|
+
private
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
def attempt_selection(retries_left)
|
|
19
|
+
return nil if retries_left.zero?
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
print_tenant_selection_menu
|
|
22
|
+
selection = parse_user_selection
|
|
23
|
+
selection ? resolve_selection(selection) : attempt_selection(retries_left - 1)
|
|
21
24
|
end
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def print_tenant_selection_menu(tenants, keys)
|
|
26
|
+
def print_tenant_selection_menu
|
|
26
27
|
Output.print_header('Multiple tenants detected. Please choose one:')
|
|
27
28
|
Output.print_info(' 0. Load without tenant (no tenant configuration)')
|
|
28
29
|
|
|
29
|
-
keys.each_with_index do |key, index|
|
|
30
|
-
|
|
31
|
-
Output.print_info(" #{index + 1}. #{key} (partner: #{partner})")
|
|
30
|
+
ConsoleKit.tenants.keys.each_with_index do |key, index|
|
|
31
|
+
Output.print_info(" #{index + 1}. #{key} (partner: #{tenant_partner(key)})")
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def
|
|
36
|
-
Output.print_prompt("\nEnter the number of the tenant you want (or press Enter for default '1'): ")
|
|
37
|
-
input = $stdin.gets&.chomp&.strip
|
|
38
|
-
input = '1' if input.to_s.empty?
|
|
39
|
-
return invalid_input_response unless valid_integer?(input)
|
|
35
|
+
def tenant_partner(key) = ConsoleKit.tenants.dig(key, :constants, :partner_code) || 'N/A'
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
def parse_user_selection
|
|
38
|
+
input = read_input_with_default
|
|
39
|
+
return handle_invalid_input('Invalid input. Please enter a number.') unless valid_integer?(input)
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
index = input.to_i
|
|
42
|
+
unless valid_selection_index?(index)
|
|
43
|
+
return handle_invalid_input("Selection must be between 0 and #{max_index}.")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
index
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def read_input_with_default
|
|
50
|
+
prompt_message = "\nEnter the number of the tenant you want " \
|
|
51
|
+
"(or press Enter for default '#{DEFAULT_SELECTION}'): "
|
|
52
|
+
Output.print_prompt(prompt_message)
|
|
53
|
+
input = $stdin.gets&.chomp&.strip
|
|
54
|
+
input.to_s.empty? ? DEFAULT_SELECTION : input
|
|
45
55
|
end
|
|
46
56
|
|
|
57
|
+
def handle_invalid_input(message) = Output.print_warning(message).then { nil }
|
|
47
58
|
def valid_integer?(input) = input.match?(/\A\d+\z/)
|
|
48
|
-
def
|
|
59
|
+
def max_index = ConsoleKit.tenants.size
|
|
60
|
+
def valid_selection_index?(index) = index.between?(0, max_index)
|
|
61
|
+
|
|
62
|
+
def resolve_selection(index)
|
|
63
|
+
return nil if index.zero?
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
Output.print_warning("Selection must be between 0 and #{max_index}.")
|
|
52
|
-
-1
|
|
65
|
+
ConsoleKit.tenants.keys[index - 1]
|
|
53
66
|
end
|
|
54
67
|
end
|
|
55
68
|
end
|
data/lib/console_kit/version.rb
CHANGED
data/lib/console_kit.rb
CHANGED
|
@@ -12,12 +12,13 @@ module ConsoleKit
|
|
|
12
12
|
class_option :force, type: :boolean, default: false, desc: 'Overwrite existing files'
|
|
13
13
|
|
|
14
14
|
def copy_initializer
|
|
15
|
+
force = options[:force]
|
|
15
16
|
initializer_path = Rails.root.join('config', 'initializers', 'console_kit.rb')
|
|
16
17
|
|
|
17
|
-
if File.exist?(initializer_path) && !
|
|
18
|
+
if File.exist?(initializer_path) && !force
|
|
18
19
|
say_status :skipped, "Initializer already exists: #{initializer_path}", :yellow
|
|
19
20
|
else
|
|
20
|
-
template 'console_kit.rb', 'config/initializers/console_kit.rb', force:
|
|
21
|
+
template 'console_kit.rb', 'config/initializers/console_kit.rb', force: force
|
|
21
22
|
say_status :created, "Initializer generated at #{initializer_path}", :green
|
|
22
23
|
end
|
|
23
24
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: console_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Soumyadeep Pal
|
|
@@ -44,6 +44,7 @@ executables: []
|
|
|
44
44
|
extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
|
46
46
|
files:
|
|
47
|
+
- ".reek.yml"
|
|
47
48
|
- ".rspec"
|
|
48
49
|
- ".rubocop.yml"
|
|
49
50
|
- CHANGELOG.md
|
|
@@ -51,8 +52,13 @@ files:
|
|
|
51
52
|
- LICENSE.txt
|
|
52
53
|
- README.md
|
|
53
54
|
- Rakefile
|
|
55
|
+
- SECURITY.md
|
|
54
56
|
- lib/console_kit.rb
|
|
55
57
|
- lib/console_kit/configuration.rb
|
|
58
|
+
- lib/console_kit/connections/base_connection_handler.rb
|
|
59
|
+
- lib/console_kit/connections/connection_manager.rb
|
|
60
|
+
- lib/console_kit/connections/mongo_connection_handler.rb
|
|
61
|
+
- lib/console_kit/connections/sql_connection_handler.rb
|
|
56
62
|
- lib/console_kit/output.rb
|
|
57
63
|
- lib/console_kit/railtie.rb
|
|
58
64
|
- lib/console_kit/setup.rb
|
|
@@ -70,6 +76,7 @@ metadata:
|
|
|
70
76
|
homepage_uri: https://github.com/Soumyadeep-ai/console_kit
|
|
71
77
|
source_code_uri: https://github.com/Soumyadeep-ai/console_kit
|
|
72
78
|
changelog_uri: https://github.com/Soumyadeep-ai/console_kit/blob/main/CHANGELOG.md
|
|
79
|
+
rubygems_mfa_required: 'true'
|
|
73
80
|
rdoc_options: []
|
|
74
81
|
require_paths:
|
|
75
82
|
- lib
|