clamp 0.6.5 → 1.0.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/CHANGES.md +5 -0
- data/README.md +28 -0
- data/lib/clamp/attribute/definition.rb +7 -0
- data/lib/clamp/attribute/instance.rb +1 -1
- data/lib/clamp/command.rb +2 -1
- data/lib/clamp/help.rb +6 -5
- data/lib/clamp/messages.rb +71 -0
- data/lib/clamp/option/parsing.rb +5 -5
- data/lib/clamp/parameter/definition.rb +1 -1
- data/lib/clamp/parameter/parsing.rb +1 -1
- data/lib/clamp/subcommand/execution.rb +1 -1
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/messages_spec.rb +44 -0
- data/spec/clamp/option/definition_spec.rb +29 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fb0beef002d49c64a0b25483def9f7f462e8798
|
4
|
+
data.tar.gz: f559b2abacf6f5323b7d168760516eb8a44145df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69b29bbdac7c60a424600633a20fe753bd0fe65d872d07e19bcfb482b9218107ec1bba2912d8daf2778604bdaa36b361a107d895fd45b3d69e0b0686c71f6d88
|
7
|
+
data.tar.gz: 946e33f41aa952bcb9ae955621018f0d91843a2771151ba3d4b38661e107c88a0ee857e81d75f565efa6eced4bac8b29d3a7ceab7de93e9010f097e3b84d31ab
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -155,6 +155,15 @@ option "--format", "FORMAT", "output format", :multivalued => true
|
|
155
155
|
|
156
156
|
The underlying attribute becomes an Array, and the suffix "`_list`" is appended to the default attribute name. In this case, an attribute called "`format_list`" would be generated (unless you override the default by specifying an `:attribute_name`).
|
157
157
|
|
158
|
+
### Hidden options
|
159
|
+
|
160
|
+
Declaring an option "`:hidden`" will cause it to be hidden from `--help` output.
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
option "--some-option", "VALUE", "Just a little option", :hidden => true
|
164
|
+
```
|
165
|
+
|
166
|
+
|
158
167
|
Declaring parameters
|
159
168
|
--------------------
|
160
169
|
|
@@ -375,6 +384,25 @@ Options:
|
|
375
384
|
-h, --help print help
|
376
385
|
```
|
377
386
|
|
387
|
+
Localization
|
388
|
+
------------
|
389
|
+
|
390
|
+
Clamp comes with support for overriding strings with custom translations. You can use localization library of your choice and override the strings at startup.
|
391
|
+
|
392
|
+
Example usage:
|
393
|
+
```ruby
|
394
|
+
require 'gettext'
|
395
|
+
|
396
|
+
Clamp.messages = {
|
397
|
+
:too_many_arguments => _("too many arguments"),
|
398
|
+
:option_required => _("option '%<option>s' is required"),
|
399
|
+
:option_or_env_required => _("option '%<option>s' (or env %<env>s) is required"),
|
400
|
+
:option_argument_error => _("option '%<switch>s': %<message>s")
|
401
|
+
# ...
|
402
|
+
}
|
403
|
+
```
|
404
|
+
See [messages.rb](https://github.com/mdub/clamp/blob/master/lib/clamp/messages.rb) for full list of available messages.
|
405
|
+
|
378
406
|
License
|
379
407
|
-------
|
380
408
|
|
@@ -15,6 +15,9 @@ module Clamp
|
|
15
15
|
if options.has_key?(:environment_variable)
|
16
16
|
@environment_variable = options[:environment_variable]
|
17
17
|
end
|
18
|
+
if options.has_key?(:hidden)
|
19
|
+
@hidden = options[:hidden]
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
20
23
|
attr_reader :description, :environment_variable
|
@@ -57,6 +60,10 @@ module Clamp
|
|
57
60
|
@required
|
58
61
|
end
|
59
62
|
|
63
|
+
def hidden?
|
64
|
+
@hidden
|
65
|
+
end
|
66
|
+
|
60
67
|
def attribute_name
|
61
68
|
@attribute_name ||= infer_attribute_name
|
62
69
|
end
|
@@ -69,7 +69,7 @@ module Clamp
|
|
69
69
|
begin
|
70
70
|
take(value)
|
71
71
|
rescue ArgumentError => e
|
72
|
-
command.send(:signal_usage_error,
|
72
|
+
command.send(:signal_usage_error, Clamp.message(:env_argument_error, :env => attribute.environment_variable, :message => e.message))
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
data/lib/clamp/command.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'clamp/messages'
|
1
2
|
require 'clamp/errors'
|
2
3
|
require 'clamp/help'
|
3
4
|
require 'clamp/option/declaration'
|
@@ -91,7 +92,7 @@ module Clamp
|
|
91
92
|
|
92
93
|
def handle_remaining_arguments
|
93
94
|
unless remaining_arguments.empty?
|
94
|
-
signal_usage_error
|
95
|
+
signal_usage_error Clamp.message(:too_many_arguments)
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
data/lib/clamp/help.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stringio'
|
2
|
+
require 'clamp/messages'
|
2
3
|
|
3
4
|
module Clamp
|
4
5
|
|
@@ -41,12 +42,12 @@ module Clamp
|
|
41
42
|
help.add_usage(invocation_path, usage_descriptions)
|
42
43
|
help.add_description(description)
|
43
44
|
if has_parameters?
|
44
|
-
help.add_list(
|
45
|
+
help.add_list(Clamp.message(:parameters_heading), parameters)
|
45
46
|
end
|
46
47
|
if has_subcommands?
|
47
|
-
help.add_list(
|
48
|
+
help.add_list(Clamp.message(:subcommands_heading), recognised_subcommands)
|
48
49
|
end
|
49
|
-
help.add_list(
|
50
|
+
help.add_list(Clamp.message(:options_heading), recognised_options)
|
50
51
|
help.string
|
51
52
|
end
|
52
53
|
|
@@ -61,7 +62,7 @@ module Clamp
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def add_usage(invocation_path, usage_descriptions)
|
64
|
-
puts "
|
65
|
+
puts Clamp.message(:usage_heading) + ":"
|
65
66
|
usage_descriptions.each do |usage|
|
66
67
|
puts " #{invocation_path} #{usage}".rstrip
|
67
68
|
end
|
@@ -78,7 +79,7 @@ module Clamp
|
|
78
79
|
|
79
80
|
def add_list(heading, items)
|
80
81
|
puts "\n#{heading}:"
|
81
|
-
items.each do |item|
|
82
|
+
items.reject { |i| i.respond_to?(:hidden?) && i.hidden? }.each do |item|
|
82
83
|
label, description = item.help
|
83
84
|
description.each_line do |line|
|
84
85
|
puts DETAIL_FORMAT % [label, line]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Clamp
|
2
|
+
|
3
|
+
module Messages
|
4
|
+
|
5
|
+
def messages=(new_messages)
|
6
|
+
messages.merge!(new_messages)
|
7
|
+
end
|
8
|
+
|
9
|
+
def message(key, options={})
|
10
|
+
format_string(messages.fetch(key), options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_messages!
|
14
|
+
init_default_messages
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
DEFAULTS = {
|
20
|
+
:too_many_arguments => "too many arguments",
|
21
|
+
:option_required => "option '%<option>s' is required",
|
22
|
+
:option_or_env_required => "option '%<option>s' (or env %<env>s) is required",
|
23
|
+
:option_argument_error => "option '%<switch>s': %<message>s",
|
24
|
+
:parameter_argument_error => "parameter '%<param>s': %<message>s",
|
25
|
+
:env_argument_error => "$%<env>s: %<message>s",
|
26
|
+
:unrecognised_option => "Unrecognised option '%<switch>s'",
|
27
|
+
:no_such_subcommand => "No such sub-command '%<name>s'",
|
28
|
+
:no_value_provided => "no value provided",
|
29
|
+
:usage_heading => "Usage",
|
30
|
+
:parameters_heading => "Parameters",
|
31
|
+
:subcommands_heading => "Subcommands",
|
32
|
+
:options_heading => "Options"
|
33
|
+
}
|
34
|
+
|
35
|
+
def messages
|
36
|
+
unless defined?(@messages)
|
37
|
+
init_default_messages
|
38
|
+
end
|
39
|
+
@messages
|
40
|
+
end
|
41
|
+
|
42
|
+
def init_default_messages
|
43
|
+
@messages = DEFAULTS.clone
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
|
48
|
+
("%{foo}" % {:foo => "bar"}) # test Ruby 1.9 string interpolation
|
49
|
+
|
50
|
+
def format_string(format, params = {})
|
51
|
+
format % params
|
52
|
+
end
|
53
|
+
|
54
|
+
rescue ArgumentError
|
55
|
+
|
56
|
+
# string formatting for ruby 1.8
|
57
|
+
def format_string(format, params = {})
|
58
|
+
array_params = format.scan(/%[<{]([^>}]*)[>}]/).collect do |name|
|
59
|
+
name = name[0]
|
60
|
+
params[name.to_s] || params[name.to_sym]
|
61
|
+
end
|
62
|
+
format.gsub(/%[<]([^>]*)[>]/, '%').gsub(/%[{]([^}]*)[}]/, '%s') % array_params
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
extend Messages
|
70
|
+
|
71
|
+
end
|
data/lib/clamp/option/parsing.rb
CHANGED
@@ -31,7 +31,7 @@ module Clamp
|
|
31
31
|
begin
|
32
32
|
option.of(self).take(value)
|
33
33
|
rescue ArgumentError => e
|
34
|
-
signal_usage_error
|
34
|
+
signal_usage_error Clamp.message(:option_argument_error, :switch => switch, :message => e.message)
|
35
35
|
end
|
36
36
|
|
37
37
|
end
|
@@ -45,11 +45,11 @@ module Clamp
|
|
45
45
|
self.class.recognised_options.each do |option|
|
46
46
|
# If this option is required and the value is nil, there's an error.
|
47
47
|
if option.required? and send(option.attribute_name).nil?
|
48
|
-
message = "option '#{option.switches.first}'"
|
49
48
|
if option.environment_variable
|
50
|
-
message
|
49
|
+
message = Clamp.message(:option_or_env_required, :option => option.switches.first, :env => option.environment_variable)
|
50
|
+
else
|
51
|
+
message = Clamp.message(:option_required, :option => option.switches.first)
|
51
52
|
end
|
52
|
-
message += " is required"
|
53
53
|
signal_usage_error message
|
54
54
|
end
|
55
55
|
end
|
@@ -59,7 +59,7 @@ module Clamp
|
|
59
59
|
|
60
60
|
def find_option(switch)
|
61
61
|
self.class.find_option(switch) ||
|
62
|
-
signal_usage_error(
|
62
|
+
signal_usage_error(Clamp.message(:unrecognised_option, :switch => switch))
|
63
63
|
end
|
64
64
|
|
65
65
|
end
|
@@ -22,7 +22,7 @@ module Clamp
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def consume(arguments)
|
25
|
-
raise ArgumentError,
|
25
|
+
raise ArgumentError, Clamp.message(:no_value_provided) if required? && arguments.empty?
|
26
26
|
arguments.shift(multivalued? ? arguments.length : 1)
|
27
27
|
end
|
28
28
|
|
@@ -13,7 +13,7 @@ module Clamp
|
|
13
13
|
parameter.of(self).take(value)
|
14
14
|
end
|
15
15
|
rescue ArgumentError => e
|
16
|
-
signal_usage_error
|
16
|
+
signal_usage_error Clamp.message(:parameter_argument_error, :param => parameter.name, :message => e.message)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ module Clamp
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def find_subcommand_class(name)
|
28
|
-
subcommand_def = self.class.find_subcommand(name) || signal_usage_error(
|
28
|
+
subcommand_def = self.class.find_subcommand(name) || signal_usage_error(Clamp.message(:no_such_subcommand, :name => name))
|
29
29
|
subcommand_def.subcommand_class
|
30
30
|
end
|
31
31
|
|
data/lib/clamp/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Clamp::Messages do
|
5
|
+
|
6
|
+
describe "message" do
|
7
|
+
before do
|
8
|
+
Clamp.messages = {
|
9
|
+
:too_many_arguments => "Way too many!",
|
10
|
+
:custom_message => "Say %<what>s to %<whom>s"
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
Clamp.clear_messages!
|
16
|
+
end
|
17
|
+
|
18
|
+
it "allows setting custom messages" do
|
19
|
+
expect(Clamp.message(:too_many_arguments)).to eql "Way too many!"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "fallbacks to a default message" do
|
23
|
+
expect(Clamp.message(:no_value_provided)).to eql "no value provided"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "formats the message" do
|
27
|
+
expect(Clamp.message(:custom_message, :what => "hello", :whom => "Clamp")).to eql "Say hello to Clamp"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "clear_messages!" do
|
32
|
+
it "clears messages to the defualt state" do
|
33
|
+
default_msg = Clamp.message(:too_many_arguments).clone
|
34
|
+
|
35
|
+
Clamp.messages = {
|
36
|
+
:too_many_arguments => "Way too many!"
|
37
|
+
}
|
38
|
+
Clamp.clear_messages!
|
39
|
+
|
40
|
+
expect(Clamp.message(:too_many_arguments)).to eql default_msg
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -257,4 +257,33 @@ describe Clamp::Option::Definition do
|
|
257
257
|
end.to raise_error(ArgumentError)
|
258
258
|
end
|
259
259
|
end
|
260
|
+
|
261
|
+
describe "a hidden option" do
|
262
|
+
let(:option) { described_class.new("--unseen", :flag, "Something", :hidden => true) }
|
263
|
+
it "is hidden" do
|
264
|
+
expect(option).to be_hidden
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "a hidden option in a command" do
|
269
|
+
let(:command_class) do
|
270
|
+
Class.new(Clamp::Command) do
|
271
|
+
option "--unseen", :flag, "Something", :hidden => true
|
272
|
+
|
273
|
+
def execute
|
274
|
+
# this space intentionally left blank
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
it "is not shown in the help" do
|
280
|
+
expect(command_class.help("foo")).not_to match /^ +--unseen +Something$/
|
281
|
+
end
|
282
|
+
|
283
|
+
it "sets the expected accessor" do
|
284
|
+
command = command_class.new("foo")
|
285
|
+
command.run(["--unseen"])
|
286
|
+
expect(command.unseen?).to be_truthy
|
287
|
+
end
|
288
|
+
end
|
260
289
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Clamp provides an object-model for command-line utilities.
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- lib/clamp/command.rb
|
42
42
|
- lib/clamp/errors.rb
|
43
43
|
- lib/clamp/help.rb
|
44
|
+
- lib/clamp/messages.rb
|
44
45
|
- lib/clamp/option/declaration.rb
|
45
46
|
- lib/clamp/option/definition.rb
|
46
47
|
- lib/clamp/option/parsing.rb
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- lib/clamp/version.rb
|
56
57
|
- spec/clamp/command_group_spec.rb
|
57
58
|
- spec/clamp/command_spec.rb
|
59
|
+
- spec/clamp/messages_spec.rb
|
58
60
|
- spec/clamp/option/definition_spec.rb
|
59
61
|
- spec/clamp/option_module_spec.rb
|
60
62
|
- spec/clamp/parameter/definition_spec.rb
|
@@ -79,13 +81,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
81
|
version: '0'
|
80
82
|
requirements: []
|
81
83
|
rubyforge_project:
|
82
|
-
rubygems_version: 2.
|
84
|
+
rubygems_version: 2.4.5
|
83
85
|
signing_key:
|
84
86
|
specification_version: 4
|
85
87
|
summary: a minimal framework for command-line utilities
|
86
88
|
test_files:
|
87
89
|
- spec/clamp/command_group_spec.rb
|
88
90
|
- spec/clamp/command_spec.rb
|
91
|
+
- spec/clamp/messages_spec.rb
|
89
92
|
- spec/clamp/option/definition_spec.rb
|
90
93
|
- spec/clamp/option_module_spec.rb
|
91
94
|
- spec/clamp/parameter/definition_spec.rb
|