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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8d58bd5db9ac6b414b75d34a947149720909757
4
- data.tar.gz: d61add398880941423c32234e2e9c1d57a1c38f3
3
+ metadata.gz: 2fb0beef002d49c64a0b25483def9f7f462e8798
4
+ data.tar.gz: f559b2abacf6f5323b7d168760516eb8a44145df
5
5
  SHA512:
6
- metadata.gz: 7df1c2418b54a047af268ca936cabc828ecc2ac2f24bb9ca7a0b8a83768dd9b03679178d61ae79b18cd5a932626c5ae5da3d98d353d8517f2f668b00f4971cb4
7
- data.tar.gz: 9298c454fd95f1ad91e4a852fabf51bc0ebb3b915c6164a0f2e012625b2ed1a8e170244c376ec6a54580583c471d3b7a0bd1cab45d5ac1a0437bc739989b819a
6
+ metadata.gz: 69b29bbdac7c60a424600633a20fe753bd0fe65d872d07e19bcfb482b9218107ec1bba2912d8daf2778604bdaa36b361a107d895fd45b3d69e0b0686c71f6d88
7
+ data.tar.gz: 946e33f41aa952bcb9ae955621018f0d91843a2771151ba3d4b38661e107c88a0ee857e81d75f565efa6eced4bac8b29d3a7ceab7de93e9010f097e3b84d31ab
data/CHANGES.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0 (2015-06-08)
4
+
5
+ * Allow options to be `:hidden`.
6
+ * I18N support.
7
+
3
8
  ## 0.6.5 (2015-05-02)
4
9
 
5
10
  * Catch signals and exit appropriately.
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, "$#{attribute.environment_variable}: #{e.message}")
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
 
@@ -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 "too many arguments"
95
+ signal_usage_error Clamp.message(:too_many_arguments)
95
96
  end
96
97
  end
97
98
 
@@ -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("Parameters", parameters)
45
+ help.add_list(Clamp.message(:parameters_heading), parameters)
45
46
  end
46
47
  if has_subcommands?
47
- help.add_list("Subcommands", recognised_subcommands)
48
+ help.add_list(Clamp.message(:subcommands_heading), recognised_subcommands)
48
49
  end
49
- help.add_list("Options", recognised_options)
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 "Usage:"
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
@@ -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 "option '#{switch}': #{e.message}"
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 += " (or env #{option.environment_variable})"
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("Unrecognised option '#{switch}'")
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, "no value provided" if required? && arguments.empty?
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 "parameter '#{parameter.name}': #{e.message}"
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("No such sub-command '#{name}'")
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
 
@@ -1,3 +1,3 @@
1
1
  module Clamp
2
- VERSION = "0.6.5".freeze
2
+ VERSION = "1.0.0".freeze
3
3
  end
@@ -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.6.5
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-05-02 00:00:00.000000000 Z
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.2.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