hammer_cli 0.15.1 → 0.16.0
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/doc/commands_modification.md +82 -0
- data/doc/creating_commands.md +78 -38
- data/doc/developer_docs.md +2 -0
- data/doc/help_modification.md +119 -0
- data/doc/i18n.md +2 -2
- data/doc/installation_rpm.md +3 -3
- data/doc/release_notes.md +9 -1
- data/lib/hammer_cli.rb +0 -1
- data/lib/hammer_cli/abstract.rb +44 -13
- data/lib/hammer_cli/exception_handler.rb +1 -1
- data/lib/hammer_cli/help/definition.rb +55 -0
- data/lib/hammer_cli/help/definition/abstract_item.rb +38 -0
- data/lib/hammer_cli/help/definition/list.rb +53 -0
- data/lib/hammer_cli/help/definition/section.rb +36 -0
- data/lib/hammer_cli/help/definition/text.rb +21 -0
- data/lib/hammer_cli/help/text_builder.rb +26 -49
- data/lib/hammer_cli/i18n.rb +0 -1
- data/lib/hammer_cli/options/option_collector.rb +12 -9
- data/lib/hammer_cli/options/option_processor.rb +17 -0
- data/lib/hammer_cli/options/processor_list.rb +37 -0
- data/lib/hammer_cli/options/sources/base.rb +17 -0
- data/lib/hammer_cli/options/sources/command_line.rb +3 -1
- data/lib/hammer_cli/options/sources/saved_defaults.rb +3 -1
- data/lib/hammer_cli/options/validators/base.rb +20 -0
- data/lib/hammer_cli/options/validators/dsl.rb +160 -0
- data/lib/hammer_cli/options/validators/dsl_block_validator.rb +19 -0
- data/lib/hammer_cli/output/adapter/csv.rb +11 -11
- data/lib/hammer_cli/output/adapter/tree_structure.rb +5 -3
- data/lib/hammer_cli/output/definition.rb +42 -4
- data/lib/hammer_cli/output/dsl.rb +4 -2
- data/lib/hammer_cli/output/fields.rb +9 -2
- data/lib/hammer_cli/testing/messages.rb +6 -6
- data/lib/hammer_cli/utils.rb +15 -0
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
- data/test/unit/abstract_test.rb +70 -5
- data/test/unit/exception_handler_test.rb +1 -1
- data/test/unit/help/definition/abstract_item_test.rb +33 -0
- data/test/unit/help/definition/list_test.rb +17 -0
- data/test/unit/help/definition/section_test.rb +25 -0
- data/test/unit/help/definition/text_test.rb +11 -0
- data/test/unit/help/definition_test.rb +236 -0
- data/test/unit/help/text_builder_test.rb +170 -1
- data/test/unit/options/option_collector_test.rb +18 -9
- data/test/unit/options/processor_list_test.rb +70 -0
- data/test/unit/{validator_test.rb → options/validators/dsl_test.rb} +57 -93
- data/test/unit/output/adapter/abstract_test.rb +3 -0
- data/test/unit/output/adapter/base_test.rb +5 -0
- data/test/unit/output/adapter/csv_test.rb +3 -0
- data/test/unit/output/adapter/json_test.rb +12 -0
- data/test/unit/output/adapter/table_test.rb +5 -0
- data/test/unit/output/adapter/yaml_test.rb +11 -0
- data/test/unit/output/definition_test.rb +221 -1
- data/test/unit/utils_test.rb +23 -0
- metadata +31 -5
- data/lib/hammer_cli/validator.rb +0 -172
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../option_processor'
|
2
|
+
|
3
|
+
module HammerCLI
|
4
|
+
module Options
|
5
|
+
module Validators
|
6
|
+
class ValidationError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
class Base < HammerCLI::Options::OptionProcessor
|
10
|
+
def process(defined_options, result)
|
11
|
+
run(defined_options, result)
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(defined_options, result)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module HammerCLI
|
2
|
+
module Options
|
3
|
+
module Validators
|
4
|
+
class DSL
|
5
|
+
class BaseConstraint
|
6
|
+
attr_reader :rejected_msg, :required_msg
|
7
|
+
|
8
|
+
def initialize(option_definitions, option_values, to_check)
|
9
|
+
@to_check = to_check
|
10
|
+
@rejected_msg = ""
|
11
|
+
@required_msg = ""
|
12
|
+
|
13
|
+
@option_values = option_values
|
14
|
+
@options = option_definitions.inject({}) do |hash, opt|
|
15
|
+
hash.update({opt.attribute_name => opt})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def rejected(args={})
|
20
|
+
msg = args[:msg] || rejected_msg % option_switches.join(", ")
|
21
|
+
raise HammerCLI::Options::Validators::ValidationError.new(msg) if exist?
|
22
|
+
end
|
23
|
+
|
24
|
+
def required(args={})
|
25
|
+
msg = args[:msg] || required_msg % option_switches.join(", ")
|
26
|
+
raise HammerCLI::Options::Validators::ValidationError.new(msg) unless exist?
|
27
|
+
end
|
28
|
+
|
29
|
+
def exist?
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def get_option(name)
|
36
|
+
name = name.to_s
|
37
|
+
raise _("Unknown option name '%s'.") % name unless @options.has_key? name
|
38
|
+
@options[name]
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_option_value(name)
|
42
|
+
@option_values[name] || @option_values[name.to_s]
|
43
|
+
end
|
44
|
+
|
45
|
+
def option_passed?(option_name)
|
46
|
+
!get_option_value(option_name).nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
def option_switches(opts=nil)
|
50
|
+
opts ||= @to_check
|
51
|
+
opts.collect do |option_name|
|
52
|
+
get_option(option_name).long_switch || get_option(option_name).switches.first
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class AllConstraint < BaseConstraint
|
58
|
+
def initialize(options, option_values, to_check)
|
59
|
+
super
|
60
|
+
@rejected_msg = _("You can't set all options %s at one time.")
|
61
|
+
@required_msg = _("Options %s are required.")
|
62
|
+
end
|
63
|
+
|
64
|
+
def exist?
|
65
|
+
@to_check.each do |opt|
|
66
|
+
return false unless option_passed?(opt)
|
67
|
+
end
|
68
|
+
return true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class OneOptionConstraint < AllConstraint
|
73
|
+
def initialize(options, option_values, to_check)
|
74
|
+
super(options, option_values, [to_check])
|
75
|
+
@rejected_msg = _("You can't set option %s.")
|
76
|
+
@required_msg = _("Option %s is required.")
|
77
|
+
end
|
78
|
+
|
79
|
+
def value
|
80
|
+
get_option_value(@to_check[0])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class AnyConstraint < BaseConstraint
|
85
|
+
def initialize(options, option_values, to_check)
|
86
|
+
super
|
87
|
+
@rejected_msg = _("You can't set any of options %s.")
|
88
|
+
@required_msg = _("At least one of options %s is required.")
|
89
|
+
end
|
90
|
+
|
91
|
+
def exist?
|
92
|
+
@to_check.each do |opt|
|
93
|
+
return true if option_passed?(opt)
|
94
|
+
end
|
95
|
+
return @to_check.empty?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
class OneOfConstraint < BaseConstraint
|
101
|
+
def initialize(options, option_values, to_check)
|
102
|
+
raise 'Set at least one expected option' if to_check.empty?
|
103
|
+
super
|
104
|
+
end
|
105
|
+
|
106
|
+
def rejected
|
107
|
+
raise NotImplementedError, '#rejected is unsupported for OneOfConstraint'
|
108
|
+
end
|
109
|
+
|
110
|
+
def required_msg
|
111
|
+
case count_present_options
|
112
|
+
when 0
|
113
|
+
_("One of options %s is required.")
|
114
|
+
when 1
|
115
|
+
''
|
116
|
+
else
|
117
|
+
_("Only one of options %s can be set.")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def exist?
|
122
|
+
return count_present_options == 1
|
123
|
+
end
|
124
|
+
|
125
|
+
protected
|
126
|
+
def count_present_options
|
127
|
+
@to_check.count do |opt|
|
128
|
+
option_passed?(opt)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def initialize(options, option_values)
|
134
|
+
@options = options
|
135
|
+
@option_values = option_values
|
136
|
+
end
|
137
|
+
|
138
|
+
def all(*to_check)
|
139
|
+
AllConstraint.new(@options, @option_values, to_check.flatten(1))
|
140
|
+
end
|
141
|
+
|
142
|
+
def option(to_check)
|
143
|
+
OneOptionConstraint.new(@options, @option_values, to_check)
|
144
|
+
end
|
145
|
+
|
146
|
+
def any(*to_check)
|
147
|
+
AnyConstraint.new(@options, @option_values, to_check.flatten(1))
|
148
|
+
end
|
149
|
+
|
150
|
+
def one_of(*to_check)
|
151
|
+
OneOfConstraint.new(@options, @option_values, to_check.flatten(1))
|
152
|
+
end
|
153
|
+
|
154
|
+
def run(&block)
|
155
|
+
self.instance_eval &block
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
require_relative './dsl'
|
3
|
+
|
4
|
+
module HammerCLI
|
5
|
+
module Options
|
6
|
+
module Validators
|
7
|
+
class DSLBlockValidator < Base
|
8
|
+
def initialize(&block)
|
9
|
+
@validation_block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(options, option_values)
|
13
|
+
dsl = DSL.new(options, option_values)
|
14
|
+
dsl.run(&@validation_block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -165,20 +165,20 @@ module HammerCLI::Output::Adapter
|
|
165
165
|
|
166
166
|
def print_message(msg, msg_params={})
|
167
167
|
csv_string = generate do |csv|
|
168
|
-
id = msg_params["id"] || msg_params[:id]
|
169
|
-
name = msg_params["name"] || msg_params[:name]
|
170
|
-
|
171
168
|
labels = [_("Message")]
|
172
169
|
data = [msg.format(msg_params)]
|
173
170
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
171
|
+
unless msg_params.nil?
|
172
|
+
id = msg_params["id"] || msg_params[:id]
|
173
|
+
name = msg_params["name"] || msg_params[:name]
|
174
|
+
if id
|
175
|
+
labels << _("Id")
|
176
|
+
data << id
|
177
|
+
end
|
178
|
+
if name
|
179
|
+
labels << _("Name")
|
180
|
+
data << name
|
181
|
+
end
|
182
182
|
end
|
183
183
|
|
184
184
|
csv << labels
|
@@ -19,12 +19,14 @@ module HammerCLI::Output::Adapter
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def prepare_message(msg, msg_params = {})
|
22
|
-
id = msg_params['id'] || msg_params[:id]
|
23
|
-
name = msg_params['name'] || msg_params[:name]
|
24
|
-
|
25
22
|
data = {
|
26
23
|
capitalize(:message) => msg.format(msg_params)
|
27
24
|
}
|
25
|
+
return data if msg_params.nil?
|
26
|
+
|
27
|
+
id = msg_params['id'] || msg_params[:id]
|
28
|
+
name = msg_params['name'] || msg_params[:name]
|
29
|
+
|
28
30
|
data[capitalize(:id)] = id unless id.nil?
|
29
31
|
data[capitalize(:name)] = name unless name.nil?
|
30
32
|
data
|
@@ -1,21 +1,59 @@
|
|
1
1
|
module HammerCLI::Output
|
2
|
-
|
3
2
|
class Definition
|
4
|
-
|
5
3
|
attr_accessor :fields
|
6
4
|
|
7
5
|
def initialize
|
8
6
|
@fields = []
|
9
7
|
end
|
10
8
|
|
11
|
-
def append(fields)
|
9
|
+
def append(fields = nil, &block)
|
10
|
+
fields = [fields].compact unless fields.is_a?(Array)
|
12
11
|
@fields += fields
|
12
|
+
return @fields unless block_given?
|
13
|
+
dsl = Dsl.new
|
14
|
+
dsl.build(&block)
|
15
|
+
@fields += dsl.fields
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_field(field_id)
|
19
|
+
@fields[field_index(field_id)]
|
20
|
+
end
|
21
|
+
|
22
|
+
def insert(mode, field_id, fields = nil, &block)
|
23
|
+
definition = self.class.new
|
24
|
+
definition.append(fields, &block)
|
25
|
+
HammerCLI.insert_relative(@fields, mode, field_index(field_id), *definition.fields)
|
26
|
+
end
|
27
|
+
|
28
|
+
def at(path = [])
|
29
|
+
path = [path] unless path.is_a? Array
|
30
|
+
return self if path.empty?
|
31
|
+
|
32
|
+
field = find_field(path[0])
|
33
|
+
|
34
|
+
unless field.respond_to?(:output_definition)
|
35
|
+
raise ArgumentError, "Field #{path[0]} doesn't have nested output definition"
|
36
|
+
end
|
37
|
+
|
38
|
+
field.output_definition.at(path[1..-1])
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear
|
42
|
+
@fields = []
|
13
43
|
end
|
14
44
|
|
15
45
|
def empty?
|
16
46
|
@fields.empty?
|
17
47
|
end
|
18
48
|
|
19
|
-
|
49
|
+
private
|
20
50
|
|
51
|
+
def field_index(field_id)
|
52
|
+
index = @fields.find_index do |f|
|
53
|
+
f.match_id?(field_id)
|
54
|
+
end
|
55
|
+
raise ArgumentError, "Field #{field_id} not found" if index.nil?
|
56
|
+
index
|
57
|
+
end
|
58
|
+
end
|
21
59
|
end
|
@@ -19,8 +19,10 @@ module HammerCLI::Output
|
|
19
19
|
|
20
20
|
def field(key, label, type=nil, options={}, &block)
|
21
21
|
options[:path] = current_path.clone
|
22
|
-
|
23
|
-
|
22
|
+
unless key.nil?
|
23
|
+
options[:path] << key
|
24
|
+
options[:key] = key
|
25
|
+
end
|
24
26
|
options[:label] = label
|
25
27
|
type ||= Fields::Field
|
26
28
|
custom_field type, options, &block
|
@@ -3,9 +3,8 @@ require 'hammer_cli/output/dsl'
|
|
3
3
|
module Fields
|
4
4
|
|
5
5
|
class Field
|
6
|
-
|
7
|
-
attr_reader :label
|
8
6
|
attr_reader :path
|
7
|
+
attr_accessor :label
|
9
8
|
|
10
9
|
def initialize(options={})
|
11
10
|
@hide_blank = options[:hide_blank].nil? ? false : options[:hide_blank]
|
@@ -15,6 +14,14 @@ module Fields
|
|
15
14
|
@options = options
|
16
15
|
end
|
17
16
|
|
17
|
+
def id
|
18
|
+
@options[:id] || @options[:key] || @label
|
19
|
+
end
|
20
|
+
|
21
|
+
def match_id?(field_id)
|
22
|
+
@options[:id] == field_id || @options[:key] == field_id || @label == _(field_id)
|
23
|
+
end
|
24
|
+
|
18
25
|
def hide_blank?
|
19
26
|
@hide_blank
|
20
27
|
end
|
@@ -33,19 +33,19 @@ module HammerCLI
|
|
33
33
|
refute opt.description.end_with?('.'), "Description for option #{opt.long_switch} in #{cmd} ends with '.'"
|
34
34
|
end
|
35
35
|
|
36
|
-
def check_command_messages(cmd)
|
36
|
+
def check_command_messages(cmd, except: [])
|
37
37
|
cmd.recognised_options.each do |opt|
|
38
38
|
check_option_description(cmd, opt)
|
39
39
|
end
|
40
|
-
refute_msg_period(cmd, :desc)
|
41
|
-
assert_msg_period(cmd, :success_message)
|
42
|
-
refute_msg_period(cmd, :failure_message)
|
40
|
+
refute_msg_period(cmd, :desc) unless except.include?(:desc)
|
41
|
+
assert_msg_period(cmd, :success_message) unless except.include?(:success_message)
|
42
|
+
refute_msg_period(cmd, :failure_message) unless except.include?(:failure_message)
|
43
43
|
end
|
44
44
|
|
45
|
-
def check_all_command_messages(main_cmd, parent=HammerCLI::AbstractCommand)
|
45
|
+
def check_all_command_messages(main_cmd, parent=HammerCLI::AbstractCommand, except: {})
|
46
46
|
all_subcommands(main_cmd, parent).each do |cmd|
|
47
47
|
it "test messages of #{cmd}" do
|
48
|
-
check_command_messages(cmd)
|
48
|
+
check_command_messages(cmd, except: (except[cmd.to_s] || []))
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
data/lib/hammer_cli/utils.rb
CHANGED
@@ -96,4 +96,19 @@ module HammerCLI
|
|
96
96
|
end
|
97
97
|
result
|
98
98
|
end
|
99
|
+
|
100
|
+
def self.insert_relative(array, mode, idx, *new_items)
|
101
|
+
case mode
|
102
|
+
when :prepend
|
103
|
+
idx = 0
|
104
|
+
when :append
|
105
|
+
idx = -1
|
106
|
+
when :after
|
107
|
+
idx += 1
|
108
|
+
when :replace
|
109
|
+
array.delete_at(idx)
|
110
|
+
end
|
111
|
+
|
112
|
+
array.insert(idx, *new_items)
|
113
|
+
end
|
99
114
|
end
|
data/lib/hammer_cli/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|