Skip to content

Commit 563a958

Browse files
authored
Merge pull request #205 from DannyBen/add/validation-for-unknown-keys
Abort generation if the config file contains unknown keys
2 parents 2c13c5e + 8ad48fe commit 563a958

File tree

15 files changed

+105
-34
lines changed

15 files changed

+105
-34
lines changed

lib/bashly/config_validator.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ def assert_array(key, value, of: nil)
4242
end
4343
end
4444

45-
def assert_hash(key, value)
45+
def assert_hash(key, value, whitelist = nil)
4646
assert value.is_a?(Hash), "#{key} must be a hash"
47+
48+
if whitelist
49+
invalid_keys = value.keys.map(&:to_sym) - whitelist
50+
assert invalid_keys.empty?, "#{key} contains invalid options: #{invalid_keys.join(', ')}"
51+
end
4752
end
4853

4954
def assert_version(key, value)
@@ -61,6 +66,7 @@ def assert_catch_all(key, value)
6166
end
6267

6368
def assert_catch_all_hash(key, value)
69+
assert_hash key, value, Script::CatchAll.option_keys
6470
assert_string "#{key}.label", value['label']
6571
assert_optional_string "#{key}.help", value['help']
6672
assert_boolean "#{key}.required", value['required']
@@ -73,7 +79,7 @@ def assert_extensible(key, value)
7379
end
7480

7581
def assert_arg(key, value)
76-
assert_hash key, value
82+
assert_hash key, value, Script::Argument.option_keys
7783
assert_string "#{key}.name", value['name']
7884
assert_optional_string "#{key}.help", value['help']
7985
assert_optional_string "#{key}.default", value['default']
@@ -89,7 +95,7 @@ def assert_arg(key, value)
8995
end
9096

9197
def assert_flag(key, value)
92-
assert_hash key, value
98+
assert_hash key, value, Script::Flag.option_keys
9399
assert value['short'] || value['long'], "#{key} must have at least one of long or short name"
94100

95101
assert_optional_string "#{key}.long", value['long']
@@ -120,15 +126,15 @@ def assert_flag(key, value)
120126
end
121127

122128
def assert_env_var(key, value)
123-
assert_hash key, value
129+
assert_hash key, value, Script::EnvironmentVariable.option_keys
124130
assert_string "#{key}.name", value['name']
125131
assert_optional_string "#{key}.help", value['help']
126132
assert_optional_string "#{key}.default", value['default']
127133
assert_boolean "#{key}.required", value['required']
128134
end
129135

130136
def assert_command(key, value)
131-
assert_hash key, value
137+
assert_hash key, value, Script::Command.option_keys
132138

133139
refute value['commands'] && value['args'], "#{key} cannot have both commands and args"
134140
refute value['commands'] && value['flags'], "#{key} cannot have both commands and flags"
@@ -140,6 +146,7 @@ def assert_command(key, value)
140146
assert_optional_string "#{key}.group", value['group']
141147
assert_optional_string "#{key}.filename", value['filename']
142148

149+
assert_boolean "#{key}.private", value['private']
143150
assert_boolean "#{key}.default", value['default']
144151
assert_version "#{key}.version", value['version']
145152
assert_catch_all "#{key}.catch_all", value['catch_all']

lib/bashly/extensions/yaml.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module YAML
33
def self.properly_load_file(path)
44
YAML.load_file path, aliases: true
55
rescue ArgumentError
6+
# :nocov:
67
YAML.load_file path
8+
# :nocov:
79
end
810
end

lib/bashly/script/argument.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
module Bashly
22
module Script
33
class Argument < Base
4+
class << self
5+
def option_keys
6+
@option_keys ||= %i[
7+
allowed default help name repeatable required validate
8+
]
9+
end
10+
end
11+
412
def usage_string
513
required ? label : "[#{label}]"
614
end

lib/bashly/script/base.rb

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,19 @@ class Base
55

66
attr_reader :options
77

8-
OPTION_KEYS = %i[
9-
allowed
10-
arg
11-
catch_all
12-
completions
13-
conflicts
14-
default
15-
dependencies
16-
description
17-
environment_variables
18-
examples
19-
extensible
20-
filters
21-
flags
22-
footer
23-
group
24-
help
25-
long
26-
name
27-
parent_name
28-
private
29-
repeatable
30-
required
31-
short
32-
validate
33-
version
34-
]
8+
class << self
9+
def option_keys
10+
@option_keys ||= []
11+
end
12+
end
3513

3614
def initialize(options)
3715
raise Error, "Invalid options provided" unless options.respond_to? :keys
3816
@options = options
3917
end
4018

4119
def optional
42-
!required
20+
!options['required']
4321
end
4422

4523
def summary
@@ -56,7 +34,7 @@ def method_missing(method_name, *arguments, &block)
5634
end
5735

5836
def respond_to_missing?(method_name, include_private = false)
59-
OPTION_KEYS.include?(method_name) || super
37+
self.class.option_keys.include?(method_name) || super
6038
end
6139
end
6240
end

lib/bashly/script/catch_all.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module Bashly
22
module Script
33
class CatchAll
44
class << self
5+
def option_keys
6+
@option_keys ||= %i[label help required]
7+
end
8+
59
def from_config(config)
610
options = case config
711
when nil

lib/bashly/script/command.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ class Command < Base
44
include Completions
55
include CommandScopes
66

7+
class << self
8+
def option_keys
9+
@option_keys ||= %i[
10+
args catch_all commands completions
11+
default dependencies environment_variables examples
12+
extensible filename filters flags
13+
footer group help name
14+
private short version
15+
]
16+
end
17+
end
18+
719
# Returns the name to be used as an action.
820
# - If it is the root command, the action is "root"
921
# - Else, it is all the parents, except the first one (root) joined

lib/bashly/script/environment_variable.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
module Bashly
22
module Script
33
class EnvironmentVariable < Base
4+
class << self
5+
def option_keys
6+
@option_keys ||= %i[default help name required]
7+
end
8+
end
9+
410
def usage_string(extended: false)
511
result = [name.upcase]
612
result << strings[:required] if required and extended

lib/bashly/script/flag.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
module Bashly
22
module Script
33
class Flag < Base
4+
class << self
5+
def option_keys
6+
@option_keys ||= %i[
7+
allowed arg conflicts default help long repeatable required
8+
short validate
9+
]
10+
end
11+
end
12+
413
def aliases
514
if long and short
615
[long, short]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#<Bashly::ConfigurationError: root.args[0] contains invalid options: private, disallowed>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#<Bashly::ConfigurationError: root.catch_all contains invalid options: private>

0 commit comments

Comments
 (0)