env_check 0.1.1 ā 0.1.3
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/CHANGELOG.md +12 -0
- data/bin/env_check +1 -258
- data/lib/env_check/cli.rb +239 -0
- data/lib/env_check/version.rb +1 -1
- data/lib/env_check.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67d64926272f7b6571b33593136f13041d312845a3de3dc04df8c34d126778fc
|
4
|
+
data.tar.gz: cf0f0483265acc680bc710a3606b1f4c189ca4eb2890c764e68ebb98d144aff0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a76db970f24ad2ccc37c188c5de03a4b03c7c01ef5e9d56e961aa25ecb6c3f0dbab92d83dc8b9eff165ad80c2fee2bff09734bb36734cdd9ca93ebac0fd064fb
|
7
|
+
data.tar.gz: 60f546b19f8f57ae9b7d67bf4e48c8cd94138024ffadc1f7dc58d294dfd1bb95549f359e507853883d66a22fbd9872ef3c7ba6b46138d04315f739fdd62b4b82
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,18 @@ This project adheres to [Semantic Versioning](https://semver.org).
|
|
6
6
|
|
7
7
|
---
|
8
8
|
|
9
|
+
## [0.1.2] - 2025-07-29
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- š **CLI Architecture Redesign** - Completely fixed `bundle exec env_check` compatibility
|
14
|
+
- Moved CLI logic from executable to `lib/env_check/cli.rb` as `EnvCheck::CLI` class
|
15
|
+
- Simplified executable to just load gem and call CLI class
|
16
|
+
- Fixed shebang line and file corruption issues
|
17
|
+
- Now works reliably with both `bundle exec` and direct gem installation
|
18
|
+
|
19
|
+
---
|
20
|
+
|
9
21
|
## [0.1.1] - 2025-07-29
|
10
22
|
|
11
23
|
### Fixed
|
data/bin/env_check
CHANGED
@@ -3,9 +3,6 @@
|
|
3
3
|
|
4
4
|
# bin/env_check - CLI for EnvCheck gem
|
5
5
|
|
6
|
-
require "optparse"
|
7
|
-
require "fileutils"
|
8
|
-
|
9
6
|
# Ensure we can load the gem whether it's installed or in development
|
10
7
|
begin
|
11
8
|
require "env_check"
|
@@ -16,259 +13,5 @@ rescue LoadError
|
|
16
13
|
require "env_check"
|
17
14
|
end
|
18
15
|
|
19
|
-
# Module for CLI output helpers
|
20
|
-
module CLIHelpers
|
21
|
-
def success(message)
|
22
|
-
puts message unless @options[:quiet]
|
23
|
-
end
|
24
|
-
|
25
|
-
def info(message)
|
26
|
-
puts message unless @options[:quiet]
|
27
|
-
end
|
28
|
-
|
29
|
-
def warning(message)
|
30
|
-
puts "ā ļø #{message}" unless @options[:quiet]
|
31
|
-
end
|
32
|
-
|
33
|
-
def error(message)
|
34
|
-
warn message
|
35
|
-
end
|
36
|
-
|
37
|
-
def error_exit(message, code = 1)
|
38
|
-
warn "Error: #{message}"
|
39
|
-
exit code
|
40
|
-
end
|
41
|
-
|
42
|
-
def default_config_path
|
43
|
-
Dir.exist?("config") ? "config/env_check.yml" : ".env_check.yml"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# CLI class for better organization
|
48
|
-
class EnvCheckCLI
|
49
|
-
include CLIHelpers
|
50
|
-
def initialize(args = ARGV)
|
51
|
-
@args = args
|
52
|
-
@options = {
|
53
|
-
config: nil, # Will be auto-discovered if not specified
|
54
|
-
quiet: false,
|
55
|
-
verbose: false
|
56
|
-
}
|
57
|
-
@command = nil
|
58
|
-
end
|
59
|
-
|
60
|
-
def run
|
61
|
-
parse_arguments
|
62
|
-
execute_command
|
63
|
-
rescue StandardError => e
|
64
|
-
error_exit(e.message.to_s)
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def parse_arguments
|
70
|
-
parser = create_option_parser
|
71
|
-
parser.parse!(@args)
|
72
|
-
@command = @args.shift
|
73
|
-
end
|
74
|
-
|
75
|
-
def create_option_parser
|
76
|
-
OptionParser.new do |opts|
|
77
|
-
configure_banner_and_commands(opts)
|
78
|
-
configure_options(opts)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def configure_banner_and_commands(opts)
|
83
|
-
opts.banner = "Usage: env_check [options] <command>"
|
84
|
-
opts.separator ""
|
85
|
-
opts.separator "Commands:"
|
86
|
-
opts.separator " init Create a new env_check.yml configuration file"
|
87
|
-
opts.separator " check Validate environment variables against configuration"
|
88
|
-
opts.separator " version Show version number"
|
89
|
-
opts.separator ""
|
90
|
-
opts.separator "Options:"
|
91
|
-
end
|
92
|
-
|
93
|
-
def configure_options(opts)
|
94
|
-
opts.on("-c", "--config PATH",
|
95
|
-
"Configuration file path (auto-discovered: .env_check.yml or config/env_check.yml)") do |path|
|
96
|
-
@options[:config] = path
|
97
|
-
end
|
98
|
-
|
99
|
-
opts.on("-q", "--quiet", "Suppress output (only show errors)") do
|
100
|
-
@options[:quiet] = true
|
101
|
-
end
|
102
|
-
|
103
|
-
opts.on("-v", "--verbose", "Show detailed output") do
|
104
|
-
@options[:verbose] = true
|
105
|
-
end
|
106
|
-
|
107
|
-
opts.on("-h", "--help", "Show this help message") do
|
108
|
-
puts opts
|
109
|
-
exit 0
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def execute_command
|
114
|
-
case @command
|
115
|
-
when "init"
|
116
|
-
init_command
|
117
|
-
when "check"
|
118
|
-
check_command
|
119
|
-
when "version"
|
120
|
-
version_command
|
121
|
-
when nil
|
122
|
-
show_help_and_exit
|
123
|
-
else
|
124
|
-
error_exit("Unknown command: #{@command}")
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def init_command
|
129
|
-
path = @options[:config] || determine_init_path
|
130
|
-
|
131
|
-
begin
|
132
|
-
# Create directory if it doesn't exist
|
133
|
-
dir = File.dirname(path)
|
134
|
-
FileUtils.mkdir_p(dir) unless dir == "."
|
135
|
-
|
136
|
-
if File.exist?(path)
|
137
|
-
warning("Configuration file already exists: #{path}")
|
138
|
-
return
|
139
|
-
end
|
140
|
-
|
141
|
-
create_config_file(path)
|
142
|
-
success("Created configuration file: #{path}")
|
143
|
-
|
144
|
-
unless @options[:quiet]
|
145
|
-
puts "\nNext steps:"
|
146
|
-
puts "1. Edit #{path} to define your required environment variables"
|
147
|
-
puts "2. Run 'env_check check' to validate your environment"
|
148
|
-
end
|
149
|
-
rescue StandardError => e
|
150
|
-
error_exit("Failed to create configuration file: #{e.message}")
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def check_command
|
155
|
-
path = @options[:config] || EnvCheck::Config.discover_config_path
|
156
|
-
validate_config_exists(path)
|
157
|
-
|
158
|
-
info("Checking environment variables using: #{path}") if @options[:verbose]
|
159
|
-
|
160
|
-
result = perform_validation(path)
|
161
|
-
handle_validation_result(result)
|
162
|
-
end
|
163
|
-
|
164
|
-
def validate_config_exists(path)
|
165
|
-
return if File.exist?(path)
|
166
|
-
|
167
|
-
error_exit("Configuration file not found: #{path}. Run 'env_check init' first.")
|
168
|
-
end
|
169
|
-
|
170
|
-
def perform_validation(path)
|
171
|
-
EnvCheck.verify(path)
|
172
|
-
rescue EnvCheck::Error => e
|
173
|
-
error_exit("Validation failed: #{e.message}")
|
174
|
-
rescue StandardError => e
|
175
|
-
error_exit("Unexpected error: #{e.message}")
|
176
|
-
end
|
177
|
-
|
178
|
-
def handle_validation_result(result)
|
179
|
-
if result.success?
|
180
|
-
handle_success_result(result)
|
181
|
-
else
|
182
|
-
handle_failure_result(result)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
def handle_success_result(result)
|
187
|
-
success("ā
All environment variables are valid!")
|
188
|
-
|
189
|
-
if @options[:verbose] && !result.valid_vars.empty?
|
190
|
-
puts "\nValid variables:"
|
191
|
-
result.valid_vars.each { |var| puts " ā
#{var}" }
|
192
|
-
end
|
193
|
-
|
194
|
-
display_warnings(result.warnings) unless result.warnings.empty?
|
195
|
-
end
|
196
|
-
|
197
|
-
def handle_failure_result(result)
|
198
|
-
error("ā Environment validation failed!")
|
199
|
-
|
200
|
-
display_errors(result.errors) unless result.errors.empty?
|
201
|
-
display_warnings(result.warnings) unless result.warnings.empty?
|
202
|
-
|
203
|
-
exit 1
|
204
|
-
end
|
205
|
-
|
206
|
-
def display_errors(errors)
|
207
|
-
puts "\nErrors:"
|
208
|
-
errors.each { |error| puts " ā #{error}" }
|
209
|
-
end
|
210
|
-
|
211
|
-
def display_warnings(warnings)
|
212
|
-
puts "\nWarnings:"
|
213
|
-
warnings.each { |warning| puts " ā ļø #{warning}" }
|
214
|
-
end
|
215
|
-
|
216
|
-
def version_command
|
217
|
-
puts EnvCheck::VERSION
|
218
|
-
end
|
219
|
-
|
220
|
-
def create_config_file(path)
|
221
|
-
File.write(path, config_template)
|
222
|
-
end
|
223
|
-
|
224
|
-
def config_template
|
225
|
-
<<~YAML
|
226
|
-
# EnvCheck Configuration
|
227
|
-
# Configure required and optional environment variables for your application
|
228
|
-
|
229
|
-
# Required environment variables (must be present and non-empty)
|
230
|
-
required:
|
231
|
-
- DATABASE_URL
|
232
|
-
- SECRET_KEY_BASE
|
233
|
-
|
234
|
-
# Optional environment variables with type validation
|
235
|
-
optional:
|
236
|
-
DEBUG: boolean # true, false, 1, 0, yes, no, on, off (case-insensitive)
|
237
|
-
PORT: port # valid port number (1-65535)
|
238
|
-
API_URL: url # must start with http:// or https://
|
239
|
-
ADMIN_EMAIL: email # valid email format
|
240
|
-
LOG_LEVEL: string # any string value
|
241
|
-
RATE_LIMIT: float # floating point number
|
242
|
-
CONFIG_PATH: path # file or directory path
|
243
|
-
SETTINGS: json # valid JSON string
|
244
|
-
#{" "}
|
245
|
-
# You can also configure per-environment settings:
|
246
|
-
# development:
|
247
|
-
# required:
|
248
|
-
# - DATABASE_URL
|
249
|
-
# optional:
|
250
|
-
# DEBUG: boolean
|
251
|
-
##{" "}
|
252
|
-
# production:
|
253
|
-
# required:
|
254
|
-
# - DATABASE_URL
|
255
|
-
# - SECRET_KEY_BASE
|
256
|
-
# - RAILS_MASTER_KEY
|
257
|
-
# optional:
|
258
|
-
# REDIS_URL: url
|
259
|
-
YAML
|
260
|
-
end
|
261
|
-
|
262
|
-
def show_help_and_exit
|
263
|
-
puts create_option_parser.help
|
264
|
-
exit 1
|
265
|
-
end
|
266
|
-
|
267
|
-
# Determine the best path for init command
|
268
|
-
def determine_init_path
|
269
|
-
default_config_path
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
16
|
# Run the CLI
|
274
|
-
|
17
|
+
EnvCheck::CLI.new(ARGV).run
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module EnvCheck
|
7
|
+
# Module for CLI output helpers
|
8
|
+
module CLIHelpers
|
9
|
+
def success(message)
|
10
|
+
puts message unless @options[:quiet]
|
11
|
+
end
|
12
|
+
|
13
|
+
def info(message)
|
14
|
+
puts message unless @options[:quiet]
|
15
|
+
end
|
16
|
+
|
17
|
+
def warning(message)
|
18
|
+
puts "ā ļø #{message}" unless @options[:quiet]
|
19
|
+
end
|
20
|
+
|
21
|
+
def error(message)
|
22
|
+
warn message
|
23
|
+
end
|
24
|
+
|
25
|
+
def error_exit(message, code = 1)
|
26
|
+
warn "Error: #{message}"
|
27
|
+
exit code
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_config_path
|
31
|
+
Dir.exist?("config") ? "config/env_check.yml" : ".env_check.yml"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# CLI class for better organization
|
36
|
+
class CLI # rubocop:disable Metrics/ClassLength
|
37
|
+
include CLIHelpers
|
38
|
+
|
39
|
+
def initialize(args = ARGV)
|
40
|
+
@args = args
|
41
|
+
@options = {
|
42
|
+
config: nil, # Will be auto-discovered if not specified
|
43
|
+
quiet: false,
|
44
|
+
verbose: false
|
45
|
+
}
|
46
|
+
@command = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def run
|
50
|
+
parse_arguments
|
51
|
+
execute_command
|
52
|
+
rescue StandardError => e
|
53
|
+
error_exit(e.message.to_s)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def parse_arguments
|
59
|
+
parser = create_option_parser
|
60
|
+
parser.parse!(@args)
|
61
|
+
@command = @args.shift
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_option_parser
|
65
|
+
OptionParser.new do |opts|
|
66
|
+
configure_banner_and_commands(opts)
|
67
|
+
configure_options(opts)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def configure_banner_and_commands(opts)
|
72
|
+
opts.banner = "Usage: env_check [options] <command>"
|
73
|
+
opts.separator ""
|
74
|
+
opts.separator "Commands:"
|
75
|
+
opts.separator " init Create a new env_check.yml configuration file"
|
76
|
+
opts.separator " check Validate environment variables against configuration"
|
77
|
+
opts.separator " version Show version number"
|
78
|
+
opts.separator ""
|
79
|
+
opts.separator "Options:"
|
80
|
+
end
|
81
|
+
|
82
|
+
def configure_options(opts)
|
83
|
+
opts.on("-c", "--config PATH",
|
84
|
+
"Configuration file path (auto-discovered: .env_check.yml or config/env_check.yml)") do |path|
|
85
|
+
@options[:config] = path
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on("-q", "--quiet", "Suppress output (only show errors)") do
|
89
|
+
@options[:quiet] = true
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on("-v", "--verbose", "Show detailed output") do
|
93
|
+
@options[:verbose] = true
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("-h", "--help", "Show this help message") do
|
97
|
+
puts opts
|
98
|
+
exit 0
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def execute_command
|
103
|
+
case @command
|
104
|
+
when "init"
|
105
|
+
init_command
|
106
|
+
when "check"
|
107
|
+
check_command
|
108
|
+
when "version"
|
109
|
+
version_command
|
110
|
+
when nil
|
111
|
+
show_help_and_exit
|
112
|
+
else
|
113
|
+
error_exit("Unknown command: #{@command}")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def init_command
|
118
|
+
path = @options[:config] || determine_init_path
|
119
|
+
|
120
|
+
begin
|
121
|
+
# Create directory if it doesn't exist
|
122
|
+
dir = File.dirname(path)
|
123
|
+
FileUtils.mkdir_p(dir) unless dir == "."
|
124
|
+
|
125
|
+
if File.exist?(path)
|
126
|
+
warning("Configuration file already exists: #{path}")
|
127
|
+
return
|
128
|
+
end
|
129
|
+
|
130
|
+
create_config_file(path)
|
131
|
+
success("Created configuration file: #{path}")
|
132
|
+
|
133
|
+
unless @options[:quiet]
|
134
|
+
puts "\nNext steps:"
|
135
|
+
puts "1. Edit #{path} to define your required environment variables"
|
136
|
+
puts "2. Run 'env_check check' to validate your environment"
|
137
|
+
end
|
138
|
+
rescue StandardError => e
|
139
|
+
error_exit("Failed to create configuration file: #{e.message}")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def check_command
|
144
|
+
config_path = find_config_file
|
145
|
+
|
146
|
+
error_exit("No configuration file found. Run 'env_check init' to create one.") if config_path.nil?
|
147
|
+
|
148
|
+
begin
|
149
|
+
result = EnvCheck.verify(config_path)
|
150
|
+
display_results(result)
|
151
|
+
exit 1 unless result.success?
|
152
|
+
rescue StandardError => e
|
153
|
+
error_exit("Validation failed: #{e.message}")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def version_command
|
158
|
+
puts EnvCheck::VERSION
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_config_file(path)
|
162
|
+
File.write(path, config_template)
|
163
|
+
end
|
164
|
+
|
165
|
+
def config_template
|
166
|
+
<<~YAML
|
167
|
+
# EnvCheck Configuration#{Dir.exist?("config") ? " (Rails)" : " (Root Level)"}
|
168
|
+
# Configure required and optional environment variables for your application
|
169
|
+
|
170
|
+
# Required environment variables (must be present and non-empty)
|
171
|
+
required:
|
172
|
+
- DATABASE_URL
|
173
|
+
- SECRET_KEY_BASE
|
174
|
+
|
175
|
+
# Optional environment variables with type validation
|
176
|
+
optional:
|
177
|
+
DEBUG: boolean # true, false, 1, 0, yes, no (case-insensitive)
|
178
|
+
PORT: integer # numeric values only
|
179
|
+
API_URL: url # must start with http:// or https://
|
180
|
+
ADMIN_EMAIL: email # valid email format
|
181
|
+
LOG_LEVEL: string # any string value
|
182
|
+
YAML
|
183
|
+
end
|
184
|
+
|
185
|
+
def find_config_file
|
186
|
+
return @options[:config] if @options[:config]
|
187
|
+
|
188
|
+
# Check ENV variable first
|
189
|
+
return ENV["ENV_CHECK_CONFIG"] if ENV["ENV_CHECK_CONFIG"]
|
190
|
+
|
191
|
+
# Smart discovery
|
192
|
+
candidates = [".env_check.yml", "config/env_check.yml"]
|
193
|
+
candidates.find { |path| File.exist?(path) }
|
194
|
+
end
|
195
|
+
|
196
|
+
def display_results(result) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
197
|
+
# Show valid variables
|
198
|
+
result.valid_vars.each do |var|
|
199
|
+
success("ā
#{var} is set")
|
200
|
+
end
|
201
|
+
|
202
|
+
# Show warnings for optional variables
|
203
|
+
result.warnings.each do |warning|
|
204
|
+
warning(warning)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Show errors for required variables
|
208
|
+
result.errors.each do |error|
|
209
|
+
error("ā #{error}")
|
210
|
+
end
|
211
|
+
|
212
|
+
# Summary
|
213
|
+
if result.success?
|
214
|
+
success("\nā
Environment validation passed!")
|
215
|
+
info("Valid variables: #{result.valid_vars.count}")
|
216
|
+
info("Warnings: #{result.warnings.count}") if result.warnings.any?
|
217
|
+
else
|
218
|
+
error("\nā Environment validation failed!")
|
219
|
+
error("\nErrors:")
|
220
|
+
result.errors.each { |err| error(" ā #{err}") }
|
221
|
+
|
222
|
+
if result.warnings.any?
|
223
|
+
info("\nWarnings:")
|
224
|
+
result.warnings.each { |warn| info(" ā ļø #{warn}") }
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def show_help_and_exit
|
230
|
+
puts create_option_parser.help
|
231
|
+
exit 1
|
232
|
+
end
|
233
|
+
|
234
|
+
# Determine the best path for init command
|
235
|
+
def determine_init_path
|
236
|
+
default_config_path
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
data/lib/env_check/version.rb
CHANGED
data/lib/env_check.rb
CHANGED
@@ -15,6 +15,7 @@ require "yaml"
|
|
15
15
|
require_relative "env_check/version"
|
16
16
|
require_relative "env_check/config"
|
17
17
|
require_relative "env_check/validators"
|
18
|
+
require_relative "env_check/cli"
|
18
19
|
require_relative "env_check/rake_task" if defined?(Rake)
|
19
20
|
|
20
21
|
# Load .env automatically (if present)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: env_check
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mohammad Nadeem
|
@@ -174,6 +174,7 @@ files:
|
|
174
174
|
- bin/env_check
|
175
175
|
- bin/setup
|
176
176
|
- lib/env_check.rb
|
177
|
+
- lib/env_check/cli.rb
|
177
178
|
- lib/env_check/config.rb
|
178
179
|
- lib/env_check/rake_task.rb
|
179
180
|
- lib/env_check/validators.rb
|