clamp 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ea677c27d0df2e7b29b4423234f6095c1aafb8b
4
- data.tar.gz: a98836b37b03bd4d72e3fe77ac292be2dda6bb14
3
+ metadata.gz: 4bd2b8653f1a6c24e26a9ec5d84f655721cecdee
4
+ data.tar.gz: 776fa8ff95cf73971de85be5e6f30915bd40df09
5
5
  SHA512:
6
- metadata.gz: f39366b518b4705bf367f7403ff1b5837c7eb984325b96029bb14737b9c02cbcea754abe39c934fc0967de2b4e6cc46516fba66ff5ab4da9493f3627d0bb939b
7
- data.tar.gz: b75b6fcda33eb33fec53153c255d8166b3ca131afc7fae36b1a8ecf172633f8bef03583ff55d4a58913ee779f01d03e497572f6528a40410169329f3eef9814a
6
+ metadata.gz: 51397540a6660a9f10bd1fae184b16d3cac69a64ce17a5f65d4e5bc3d9f3c60140f7a16ae868393372f541c147a1459ef78eaa402a65203e77833ae829d54051
7
+ data.tar.gz: 27c409d2ebbe33d768b884cff979d33df4099008506c24dbe0080249466610928cd705b88a7f7b76dc10eb4ed7cf2fc2e5be0f2e8919ff74ce8015f2403965d1
data/.rubocop.yml ADDED
@@ -0,0 +1,60 @@
1
+ Eval:
2
+ Exclude:
3
+ - "Rakefile"
4
+
5
+ Metrics/AbcSize:
6
+ Enabled: false
7
+
8
+ Metrics/LineLength:
9
+ Max: 120
10
+
11
+ Metrics/MethodLength:
12
+ Max: 30
13
+
14
+ Style/AccessorMethodName:
15
+ Enabled: false
16
+
17
+ Style/ClassAndModuleChildren:
18
+ EnforcedStyle: nested
19
+ Exclude:
20
+ - "spec/**/*"
21
+
22
+ Style/Documentation:
23
+ Exclude:
24
+ - "lib/**/version.rb"
25
+ - "spec/**/*"
26
+
27
+ Style/EmptyLinesAroundBlockBody:
28
+ Enabled: false
29
+
30
+ Style/EmptyLinesAroundClassBody:
31
+ EnforcedStyle: empty_lines
32
+
33
+ Style/EmptyLinesAroundModuleBody:
34
+ Enabled: false
35
+
36
+ Style/Encoding:
37
+ EnforcedStyle: when_needed
38
+ Enabled: true
39
+
40
+ Style/FileName:
41
+ Exclude:
42
+ - "bin/*"
43
+
44
+ Style/HashSyntax:
45
+ EnforcedStyle: hash_rockets
46
+
47
+ Style/Lambda:
48
+ Enabled: false
49
+
50
+ Style/NumericLiterals:
51
+ Enabled: false
52
+
53
+ Style/PredicateName:
54
+ Enabled: false
55
+
56
+ Style/StringLiterals:
57
+ EnforcedStyle: double_quotes
58
+
59
+ Style/WordArray:
60
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,10 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.5
6
- - 2.2.0
7
- - 2.3.0
3
+ - 2.1.8
4
+ - 2.2.4
5
+ - 2.3.1
8
6
  before_install:
9
7
  - gem update --system
10
8
  - gem install bundler
data/CHANGES.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0 (2016-10-17)
4
+
5
+ * Add `#subcommand_missing`.
6
+ * Fix issue#66: pass parameter values down to nested subcommands.
7
+ * Drop support for Ruby 1.9 and 2.0.
8
+
3
9
  ## 1.0.1 (2016-10-01)
4
10
 
5
11
  * Minor bug-fixes.
data/Gemfile CHANGED
@@ -6,9 +6,10 @@ group :development do
6
6
  gem "guard-rspec", "~> 4.6.5", :require => false
7
7
  gem "listen", "~> 3.0.2"
8
8
  gem "rake", "~> 10.4"
9
+ gem "rubocop", "~> 0.43.0", :require => false
9
10
  end
10
11
 
11
12
  group :test do
12
- gem "rspec", "~> 3.1.0"
13
- gem "rr", "~> 1.1.2"
13
+ gem "rspec", "~> 3.5.0"
14
+ gem "rr", "~> 1.2.0"
14
15
  end
data/Guardfile CHANGED
@@ -24,7 +24,7 @@
24
24
  # * zeus: 'zeus rspec' (requires the server to be started separately)
25
25
  # * 'just' rspec: 'rspec'
26
26
 
27
- guard :rspec, cmd: "bundle exec rspec" do
27
+ guard :rspec, :cmd => "bundle exec rspec" do
28
28
  require "guard/rspec/dsl"
29
29
  dsl = Guard::RSpec::Dsl.new(self)
30
30
 
data/README.md CHANGED
@@ -137,7 +137,7 @@ Clamp will handle both "`--force`" and "`--no-force`" options, setting the value
137
137
 
138
138
  ### Required options
139
139
 
140
- Although 'required option' is a an oxymoron, Clamp lets you mark an option as required, and will verify that a value is provided:
140
+ Although "required option" is an oxymoron, Clamp lets you mark an option as required, and will verify that a value is provided:
141
141
 
142
142
  ```ruby
143
143
  option "--password", "PASSWORD", "the secret password", :required => true
@@ -365,6 +365,19 @@ Options are inheritable, so any options declared for a command are supported by
365
365
 
366
366
  Note that, if a subcommand accepts options, they must be specified on the command-line _after_ the subcommand name.
367
367
 
368
+ You can define a `subcommand_missing` method that is called when user tries to run an unknown subcommand:
369
+
370
+ ```ruby
371
+ Clamp do
372
+ def subcommand_missing(name)
373
+ if name == "foo"
374
+ return Object.const_get(:FooPlugin) if Object.const_defined?(:FooPlugin)
375
+ abort "Subcommand 'foo' requires plugin X"
376
+ end
377
+ end
378
+ end
379
+ ```
380
+
368
381
  Getting help
369
382
  ------------
370
383
 
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require 'bundler'
1
+ require "bundler"
2
2
 
3
3
  Bundler::GemHelper.install_tasks
4
4
 
@@ -7,6 +7,6 @@ require "rspec/core/rake_task"
7
7
  task "default" => "spec"
8
8
 
9
9
  RSpec::Core::RakeTask.new do |t|
10
- t.pattern = 'spec/**/*_spec.rb'
10
+ t.pattern = "spec/**/*_spec.rb"
11
11
  t.rspec_opts = ["--colour", "--format", "documentation"]
12
12
  end
data/clamp.gemspec CHANGED
@@ -1,5 +1,4 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
3
2
  require "clamp/version"
4
3
 
5
4
  Gem::Specification.new do |s|
@@ -11,9 +10,9 @@ Gem::Specification.new do |s|
11
10
  s.email = "mdub@dogbiscuit.org"
12
11
  s.homepage = "http://github.com/mdub/clamp"
13
12
 
14
- s.license = 'MIT'
13
+ s.license = "MIT"
15
14
 
16
- s.summary = %q{a minimal framework for command-line utilities}
15
+ s.summary = "a minimal framework for command-line utilities"
17
16
  s.description = <<EOF
18
17
  Clamp provides an object-model for command-line utilities.
19
18
  It handles parsing of command-line options, and generation of usage help.
data/examples/defaulted CHANGED
@@ -20,7 +20,7 @@ Clamp do
20
20
  private
21
21
 
22
22
  def default_password
23
- terminal.ask("Password [#{user}]: ") { |q| q.echo = '*' }
23
+ terminal.ask("Password [#{user}]: ") { |q| q.echo = "*" }
24
24
  end
25
25
 
26
26
  def terminal
data/examples/scoop CHANGED
@@ -7,8 +7,8 @@ require "clamp"
7
7
  Clamp do
8
8
 
9
9
  option ["-f", "--flavour"], "FLAVOUR", "flavour",
10
- :multivalued => true, :default => ['chocolate'],
11
- :attribute_name => :flavours
10
+ :multivalued => true, :default => ["chocolate"],
11
+ :attribute_name => :flavours
12
12
 
13
13
  def execute
14
14
  puts "one #{flavours.join(' and ')} ice-cream"
data/examples/speak CHANGED
@@ -6,9 +6,9 @@ require "clamp"
6
6
 
7
7
  Clamp do
8
8
 
9
- banner %{
9
+ banner %(
10
10
  Say something.
11
- }
11
+ )
12
12
 
13
13
  option "--loud", :flag, "say it loud"
14
14
  option ["-n", "--iterations"], "N", "say it N times", :default => 1 do |s|
@@ -18,14 +18,12 @@ Clamp do
18
18
  parameter "WORDS ...", "the thing to say", :attribute_name => :words
19
19
 
20
20
  def execute
21
-
22
21
  the_truth = words.join(" ")
23
22
  the_truth.upcase! if loud?
24
23
 
25
24
  iterations.times do
26
25
  puts the_truth
27
26
  end
28
-
29
27
  end
30
28
 
31
29
  end
@@ -0,0 +1,18 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require "clamp"
4
+
5
+ Clamp do
6
+
7
+ subcommand "hello", "Say hello" do
8
+ def execute
9
+ puts "Hello"
10
+ end
11
+ end
12
+
13
+ def subcommand_missing(name)
14
+ abort "Install bye plugin first" if name == "bye"
15
+ super
16
+ end
17
+
18
+ end
data/lib/clamp.rb CHANGED
@@ -1,6 +1,6 @@
1
- require 'clamp/version'
1
+ require "clamp/version"
2
2
 
3
- require 'clamp/command'
3
+ require "clamp/command"
4
4
 
5
5
  def Clamp(&block)
6
6
  Class.new(Clamp::Command, &block).run
@@ -5,7 +5,7 @@ module Clamp
5
5
 
6
6
  protected
7
7
 
8
- def define_accessors_for(attribute, &block)
8
+ def declare_attribute(attribute, &block)
9
9
  define_reader_for(attribute)
10
10
  define_default_for(attribute)
11
11
  if attribute.multivalued?
@@ -16,6 +16,8 @@ module Clamp
16
16
  end
17
17
  end
18
18
 
19
+ private
20
+
19
21
  def define_reader_for(attribute)
20
22
  define_method(attribute.read_method) do
21
23
  attribute.of(self)._read
@@ -1,4 +1,4 @@
1
- require 'clamp/attribute/instance'
1
+ require "clamp/attribute/instance"
2
2
 
3
3
  module Clamp
4
4
  module Attribute
@@ -6,18 +6,14 @@ module Clamp
6
6
  class Definition
7
7
 
8
8
  def initialize(options)
9
- if options.has_key?(:attribute_name)
9
+ if options.key?(:attribute_name)
10
10
  @attribute_name = options[:attribute_name].to_s
11
11
  end
12
- if options.has_key?(:default)
13
- @default_value = options[:default]
14
- end
15
- if options.has_key?(:environment_variable)
12
+ @default_value = options[:default] if options.key?(:default)
13
+ if options.key?(:environment_variable)
16
14
  @environment_variable = options[:environment_variable]
17
15
  end
18
- if options.has_key?(:hidden)
19
- @hidden = options[:hidden]
20
- end
16
+ @hidden = options[:hidden] if options.key?(:hidden)
21
17
  end
22
18
 
23
19
  attr_reader :description, :environment_variable
@@ -47,9 +43,7 @@ module Clamp
47
43
  end
48
44
 
49
45
  def append_method
50
- if multivalued?
51
- "append_to_#{attribute_name}"
52
- end
46
+ "append_to_#{attribute_name}" if multivalued?
53
47
  end
54
48
 
55
49
  def multivalued?
@@ -63,7 +63,7 @@ module Clamp
63
63
  def default_from_environment
64
64
  return if self.defined?
65
65
  return if attribute.environment_variable.nil?
66
- return unless ENV.has_key?(attribute.environment_variable)
66
+ return unless ENV.key?(attribute.environment_variable)
67
67
  # Set the parameter value if it's environment variable is present
68
68
  value = ENV[attribute.environment_variable]
69
69
  begin
data/lib/clamp/command.rb CHANGED
@@ -1,12 +1,12 @@
1
- require 'clamp/messages'
2
- require 'clamp/errors'
3
- require 'clamp/help'
4
- require 'clamp/option/declaration'
5
- require 'clamp/option/parsing'
6
- require 'clamp/parameter/declaration'
7
- require 'clamp/parameter/parsing'
8
- require 'clamp/subcommand/declaration'
9
- require 'clamp/subcommand/parsing'
1
+ require "clamp/messages"
2
+ require "clamp/errors"
3
+ require "clamp/help"
4
+ require "clamp/option/declaration"
5
+ require "clamp/option/parsing"
6
+ require "clamp/parameter/declaration"
7
+ require "clamp/parameter/parsing"
8
+ require "clamp/subcommand/declaration"
9
+ require "clamp/subcommand/parsing"
10
10
 
11
11
  module Clamp
12
12
 
@@ -25,12 +25,9 @@ module Clamp
25
25
  # @param [String] invocation_path the path used to invoke the command
26
26
  # @param [Hash] context additional data the command may need
27
27
  #
28
- def initialize(invocation_path, context = {}, parent_attribute_values = {})
28
+ def initialize(invocation_path, context = {})
29
29
  @invocation_path = invocation_path
30
30
  @context = context
31
- parent_attribute_values.each do |attribute, value|
32
- attribute.of(self).set(value)
33
- end
34
31
  end
35
32
 
36
33
  # @return [String] the path used to invoke this command
@@ -39,9 +36,7 @@ module Clamp
39
36
 
40
37
  # @return [Array<String>] unconsumed command-line arguments
41
38
  #
42
- def remaining_arguments
43
- @remaining_arguments
44
- end
39
+ attr_reader :remaining_arguments
45
40
 
46
41
  # Parse command-line arguments.
47
42
  #
@@ -82,6 +77,13 @@ module Clamp
82
77
  self.class.help(invocation_path)
83
78
  end
84
79
 
80
+ # Abort with subcommand missing usage error
81
+ #
82
+ # @ param [String] name subcommand_name
83
+ def subcommand_missing(name)
84
+ signal_usage_error(Clamp.message(:no_such_subcommand, :name => name))
85
+ end
86
+
85
87
  include Clamp::Option::Parsing
86
88
  include Clamp::Parameter::Parsing
87
89
  include Clamp::Subcommand::Parsing
@@ -91,9 +93,7 @@ module Clamp
91
93
  attr_accessor :context
92
94
 
93
95
  def handle_remaining_arguments
94
- unless remaining_arguments.empty?
95
- signal_usage_error Clamp.message(:too_many_arguments)
96
- end
96
+ signal_usage_error Clamp.message(:too_many_arguments) unless remaining_arguments.empty?
97
97
  end
98
98
 
99
99
  private
@@ -128,22 +128,20 @@ module Clamp
128
128
  # @param [Array<String>] arguments command-line arguments
129
129
  # @param [Hash] context additional data the command may need
130
130
  #
131
- def run(invocation_path = File.basename($0), arguments = ARGV, context = {})
132
- begin
133
- new(invocation_path, context).run(arguments)
134
- rescue Clamp::UsageError => e
135
- $stderr.puts "ERROR: #{e.message}"
136
- $stderr.puts ""
137
- $stderr.puts "See: '#{e.command.invocation_path} --help'"
138
- exit(1)
139
- rescue Clamp::HelpWanted => e
140
- puts e.command.help
141
- rescue Clamp::ExecutionError => e
142
- $stderr.puts "ERROR: #{e.message}"
143
- exit(e.status)
144
- rescue SignalException => e
145
- exit(128 + e.signo)
146
- end
131
+ def run(invocation_path = File.basename($PROGRAM_NAME), arguments = ARGV, context = {})
132
+ new(invocation_path, context).run(arguments)
133
+ rescue Clamp::UsageError => e
134
+ $stderr.puts "ERROR: #{e.message}"
135
+ $stderr.puts ""
136
+ $stderr.puts "See: '#{e.command.invocation_path} --help'"
137
+ exit(1)
138
+ rescue Clamp::HelpWanted => e
139
+ puts e.command.help
140
+ rescue Clamp::ExecutionError => e
141
+ $stderr.puts "ERROR: #{e.message}"
142
+ exit(e.status)
143
+ rescue SignalException => e
144
+ exit(128 + e.signo)
147
145
  end
148
146
 
149
147
  end