clamp 1.2.1 → 1.3.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/.rubocop.yml +12 -4
- data/.travis.yml +4 -6
- data/CHANGES.md +7 -0
- data/Gemfile +8 -6
- data/Guardfile +3 -1
- data/Rakefile +8 -0
- data/clamp.gemspec +8 -6
- data/examples/admin +3 -2
- data/examples/defaulted +4 -3
- data/examples/flipflop +1 -0
- data/examples/fubar +1 -0
- data/examples/gitdown +2 -1
- data/examples/scoop +3 -2
- data/examples/speak +3 -2
- data/examples/subcommand_missing +1 -0
- data/examples/word +1 -0
- data/lib/clamp.rb +3 -1
- data/lib/clamp/attribute/declaration.rb +5 -0
- data/lib/clamp/attribute/definition.rb +15 -12
- data/lib/clamp/attribute/instance.rb +5 -3
- data/lib/clamp/command.rb +9 -1
- data/lib/clamp/errors.rb +7 -3
- data/lib/clamp/help.rb +8 -6
- data/lib/clamp/messages.rb +21 -14
- data/lib/clamp/option/declaration.rb +4 -0
- data/lib/clamp/option/definition.rb +9 -3
- data/lib/clamp/option/parsing.rb +37 -32
- data/lib/clamp/parameter/declaration.rb +4 -0
- data/lib/clamp/parameter/definition.rb +9 -3
- data/lib/clamp/parameter/parsing.rb +5 -1
- data/lib/clamp/subcommand/declaration.rb +15 -13
- data/lib/clamp/subcommand/definition.rb +2 -0
- data/lib/clamp/subcommand/execution.rb +11 -0
- data/lib/clamp/subcommand/parsing.rb +4 -0
- data/lib/clamp/truthy.rb +4 -2
- data/lib/clamp/version.rb +3 -1
- data/spec/clamp/command_group_spec.rb +27 -9
- data/spec/clamp/command_spec.rb +84 -49
- data/spec/clamp/messages_spec.rb +5 -4
- data/spec/clamp/option/definition_spec.rb +13 -11
- data/spec/clamp/option_module_spec.rb +3 -1
- data/spec/clamp/option_reordering_spec.rb +6 -4
- data/spec/clamp/parameter/definition_spec.rb +14 -12
- data/spec/spec_helper.rb +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8365dad9e1c1555dfddea4d47c063438af94be5
|
4
|
+
data.tar.gz: b618f175a72f08180fb77315cc1a4ceafbbb134e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bec2151d2344efc7fbcd37709646904d20e7456fa83365484aacfa318bb23207a8e3ae9e813457d26d791f56b8c890eb863ccb59a85724a53b542193af26384
|
7
|
+
data.tar.gz: 0be7bb668484292023495887a581e8e887e0d3f10f2fac89353f6e6a6d091a2f3e9a308902a3f8548c169dd138c0aec7a90e28fac950e36999f9524b1ffab886
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.1
|
3
|
+
|
1
4
|
Eval:
|
2
5
|
Exclude:
|
3
6
|
- "Rakefile"
|
@@ -14,6 +17,10 @@ Layout/EmptyLinesAroundModuleBody:
|
|
14
17
|
Metrics/AbcSize:
|
15
18
|
Enabled: false
|
16
19
|
|
20
|
+
Metrics/BlockLength:
|
21
|
+
Exclude:
|
22
|
+
- "spec/**/*"
|
23
|
+
|
17
24
|
Metrics/LineLength:
|
18
25
|
Max: 120
|
19
26
|
|
@@ -27,6 +34,9 @@ Naming/FileName:
|
|
27
34
|
Exclude:
|
28
35
|
- "bin/*"
|
29
36
|
|
37
|
+
Naming/PredicateName:
|
38
|
+
Enabled: false
|
39
|
+
|
30
40
|
Style/ClassAndModuleChildren:
|
31
41
|
EnforcedStyle: nested
|
32
42
|
Exclude:
|
@@ -35,21 +45,19 @@ Style/ClassAndModuleChildren:
|
|
35
45
|
Style/Documentation:
|
36
46
|
Exclude:
|
37
47
|
- "lib/**/version.rb"
|
48
|
+
- "examples/*"
|
38
49
|
- "spec/**/*"
|
39
50
|
|
40
51
|
Style/Encoding:
|
41
52
|
Enabled: true
|
42
53
|
|
43
|
-
Style/HashSyntax:
|
44
|
-
EnforcedStyle: hash_rockets
|
45
|
-
|
46
54
|
Style/Lambda:
|
47
55
|
Enabled: false
|
48
56
|
|
49
57
|
Style/NumericLiterals:
|
50
58
|
Enabled: false
|
51
59
|
|
52
|
-
|
60
|
+
Style/StderrPuts:
|
53
61
|
Enabled: false
|
54
62
|
|
55
63
|
Style/StringLiterals:
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.3.0 (2018-06-17)
|
4
|
+
|
5
|
+
* Add `.execute` DSL method.
|
6
|
+
* Append '(required)' to the description of required options.
|
7
|
+
* Fix issue#75: don't generate `default_XXX` method unless a default is specified.
|
8
|
+
* Fix issue#90: allow required options to be provided after subcommands.
|
9
|
+
|
3
10
|
## 1.2.0 (2018-02-12)
|
4
11
|
|
5
12
|
* Add option to `Clamp.allow_options_after_parameters`.
|
data/Gemfile
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "http://rubygems.org"
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
7
|
group :development do
|
6
|
-
gem "guard-rspec", "~> 4.
|
7
|
-
gem "
|
8
|
-
gem "
|
9
|
-
gem "
|
8
|
+
gem "guard-rspec", "~> 4.7", require: false
|
9
|
+
gem "highline"
|
10
|
+
gem "listen", "~> 3.0"
|
11
|
+
gem "rake", "~> 12.3"
|
12
|
+
gem "rubocop", require: false
|
10
13
|
end
|
11
14
|
|
12
15
|
group :test do
|
13
|
-
gem "rspec", "~> 3.
|
14
|
-
gem "rr", "~> 1.2.0"
|
16
|
+
gem "rspec", "~> 3.7"
|
15
17
|
end
|
data/Guardfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# A sample Guardfile
|
2
4
|
# More info at https://github.com/guard/guard#readme
|
3
5
|
|
@@ -24,7 +26,7 @@
|
|
24
26
|
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
27
|
# * 'just' rspec: 'rspec'
|
26
28
|
|
27
|
-
guard :rspec, :
|
29
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
30
|
require "guard/rspec/dsl"
|
29
31
|
dsl = Guard::RSpec::Dsl.new(self)
|
30
32
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler"
|
2
4
|
|
3
5
|
Bundler::GemHelper.install_tasks
|
@@ -10,3 +12,9 @@ RSpec::Core::RakeTask.new do |t|
|
|
10
12
|
t.pattern = "spec/**/*_spec.rb"
|
11
13
|
t.rspec_opts = ["--colour", "--format", "documentation"]
|
12
14
|
end
|
15
|
+
|
16
|
+
require "rubocop/rake_task"
|
17
|
+
|
18
|
+
RuboCop::RakeTask.new
|
19
|
+
|
20
|
+
task "default" => "rubocop"
|
data/clamp.gemspec
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path("lib", __dir__)
|
2
4
|
require "clamp/version"
|
3
5
|
|
4
6
|
Gem::Specification.new do |s|
|
@@ -8,15 +10,15 @@ Gem::Specification.new do |s|
|
|
8
10
|
s.platform = Gem::Platform::RUBY
|
9
11
|
s.authors = ["Mike Williams"]
|
10
12
|
s.email = "mdub@dogbiscuit.org"
|
11
|
-
s.homepage = "
|
13
|
+
s.homepage = "https://github.com/mdub/clamp"
|
12
14
|
|
13
15
|
s.license = "MIT"
|
14
16
|
|
15
17
|
s.summary = "a minimal framework for command-line utilities"
|
16
|
-
s.description =
|
17
|
-
Clamp provides an object-model for command-line utilities.
|
18
|
-
It handles parsing of command-line options, and generation of usage help.
|
19
|
-
|
18
|
+
s.description = <<-TEXT.gsub(/^\s+/, "")
|
19
|
+
Clamp provides an object-model for command-line utilities.
|
20
|
+
It handles parsing of command-line options, and generation of usage help.
|
21
|
+
TEXT
|
20
22
|
|
21
23
|
s.files = `git ls-files`.split("\n")
|
22
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/examples/admin
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# An example of options and parameters
|
4
5
|
|
@@ -6,12 +7,12 @@ require "clamp"
|
|
6
7
|
|
7
8
|
Clamp do
|
8
9
|
|
9
|
-
option "--timeout", "SECONDS", "connection timeout", :
|
10
|
+
option "--timeout", "SECONDS", "connection timeout", default: 5, environment_variable: "MYAPP_TIMEOUT" do |x|
|
10
11
|
Integer(x)
|
11
12
|
end
|
12
13
|
|
13
14
|
parameter "HOST", "server address"
|
14
|
-
parameter "[PORT]", "server port", :
|
15
|
+
parameter "[PORT]", "server port", default: 80, environment_variable: "MYAPP_PORT"
|
15
16
|
|
16
17
|
def execute
|
17
18
|
puts "trying to connect to #{host} on port #{port} (waiting up to #{timeout} seconds)"
|
data/examples/defaulted
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# An example of default values and methods
|
4
5
|
|
@@ -8,10 +9,10 @@ require "highline"
|
|
8
9
|
Clamp do
|
9
10
|
|
10
11
|
option ["-U", "--user"], "USER", "user name",
|
11
|
-
:
|
12
|
-
:
|
12
|
+
environment_variable: "THE_USER",
|
13
|
+
default: "bob"
|
13
14
|
option ["-P", "--password"], "PASSWORD", "password",
|
14
|
-
:
|
15
|
+
environment_variable: "THE_PASSWORD"
|
15
16
|
|
16
17
|
def execute
|
17
18
|
puts "User: #{user}, Password: #{password}"
|
data/examples/flipflop
CHANGED
data/examples/fubar
CHANGED
data/examples/gitdown
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# Demonstrate how subcommands can be declared as classes
|
4
5
|
|
@@ -25,7 +26,7 @@ module GitDown
|
|
25
26
|
class CloneCommand < AbstractCommand
|
26
27
|
|
27
28
|
parameter "REPOSITORY", "repository to clone"
|
28
|
-
parameter "[DIR]", "working directory", :
|
29
|
+
parameter "[DIR]", "working directory", default: "."
|
29
30
|
|
30
31
|
def execute
|
31
32
|
say "cloning to #{dir}"
|
data/examples/scoop
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# An example of multi-valued options
|
4
5
|
|
@@ -7,8 +8,8 @@ require "clamp"
|
|
7
8
|
Clamp do
|
8
9
|
|
9
10
|
option ["-f", "--flavour"], "FLAVOUR", "flavour",
|
10
|
-
:
|
11
|
-
:
|
11
|
+
multivalued: true, default: ["chocolate"],
|
12
|
+
attribute_name: :flavours
|
12
13
|
|
13
14
|
def execute
|
14
15
|
puts "one #{flavours.join(' and ')} ice-cream"
|
data/examples/speak
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# A simple Clamp command, with options and parameters
|
4
5
|
|
@@ -11,11 +12,11 @@ Clamp do
|
|
11
12
|
)
|
12
13
|
|
13
14
|
option "--loud", :flag, "say it loud"
|
14
|
-
option ["-n", "--iterations"], "N", "say it N times", :
|
15
|
+
option ["-n", "--iterations"], "N", "say it N times", default: 1 do |s|
|
15
16
|
Integer(s)
|
16
17
|
end
|
17
18
|
|
18
|
-
parameter "WORDS ...", "the thing to say", :
|
19
|
+
parameter "WORDS ...", "the thing to say", attribute_name: :words
|
19
20
|
|
20
21
|
def execute
|
21
22
|
the_truth = words.join(" ")
|
data/examples/subcommand_missing
CHANGED
data/examples/word
CHANGED
data/lib/clamp.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clamp
|
2
4
|
module Attribute
|
3
5
|
|
6
|
+
# Methods to generate attribute accessors.
|
7
|
+
#
|
4
8
|
module Declaration
|
5
9
|
|
6
10
|
protected
|
@@ -25,6 +29,7 @@ module Clamp
|
|
25
29
|
end
|
26
30
|
|
27
31
|
def define_default_for(attribute)
|
32
|
+
return false if attribute.default_value.nil?
|
28
33
|
define_method(attribute.default_method) do
|
29
34
|
attribute.default_value
|
30
35
|
end
|
@@ -1,25 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "clamp/attribute/instance"
|
2
4
|
|
3
5
|
module Clamp
|
4
6
|
module Attribute
|
5
7
|
|
8
|
+
# Represents an attribute of a Clamp::Command class.
|
9
|
+
#
|
6
10
|
class Definition
|
7
11
|
|
8
12
|
def initialize(options)
|
9
|
-
if options.key?(:attribute_name)
|
10
|
-
@attribute_name = options[:attribute_name].to_s
|
11
|
-
end
|
13
|
+
@attribute_name = options[:attribute_name].to_s if options.key?(:attribute_name)
|
12
14
|
@default_value = options[:default] if options.key?(:default)
|
13
|
-
if options.key?(:environment_variable)
|
14
|
-
@environment_variable = options[:environment_variable]
|
15
|
-
end
|
15
|
+
@environment_variable = options[:environment_variable] if options.key?(:environment_variable)
|
16
16
|
@hidden = options[:hidden] if options.key?(:hidden)
|
17
17
|
end
|
18
18
|
|
19
19
|
attr_reader :description, :environment_variable
|
20
20
|
|
21
21
|
def help_rhs
|
22
|
-
|
22
|
+
rhs = description
|
23
|
+
comments = required_indicator || default_description
|
24
|
+
rhs += " (#{comments})" if comments
|
25
|
+
rhs
|
23
26
|
end
|
24
27
|
|
25
28
|
def help
|
@@ -77,11 +80,11 @@ module Clamp
|
|
77
80
|
def option_missing_message
|
78
81
|
if environment_variable
|
79
82
|
Clamp.message(:option_or_env_required,
|
80
|
-
:
|
81
|
-
:
|
83
|
+
option: switches.first,
|
84
|
+
env: environment_variable)
|
82
85
|
else
|
83
86
|
Clamp.message(:option_required,
|
84
|
-
:
|
87
|
+
option: switches.first)
|
85
88
|
end
|
86
89
|
end
|
87
90
|
|
@@ -92,8 +95,8 @@ module Clamp
|
|
92
95
|
("$#{@environment_variable}" if defined?(@environment_variable)),
|
93
96
|
(@default_value.inspect if defined?(@default_value))
|
94
97
|
].compact
|
95
|
-
return
|
96
|
-
"
|
98
|
+
return nil if default_sources.empty?
|
99
|
+
"#{Clamp.message(:default)}: " + default_sources.join(", #{Clamp.message(:or)} ")
|
97
100
|
end
|
98
101
|
|
99
102
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clamp
|
2
4
|
module Attribute
|
3
5
|
|
4
|
-
# Represents an
|
6
|
+
# Represents an attribute of a Clamp::Command instance.
|
5
7
|
#
|
6
8
|
class Instance
|
7
9
|
|
@@ -27,7 +29,7 @@ module Clamp
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def default
|
30
|
-
command.send(attribute.default_method)
|
32
|
+
command.send(attribute.default_method) if command.respond_to?(attribute.default_method, true)
|
31
33
|
end
|
32
34
|
|
33
35
|
# default implementation of read_method
|
@@ -73,7 +75,7 @@ module Clamp
|
|
73
75
|
begin
|
74
76
|
take(value)
|
75
77
|
rescue ArgumentError => e
|
76
|
-
signal_usage_error Clamp.message(:env_argument_error, :
|
78
|
+
signal_usage_error Clamp.message(:env_argument_error, env: attribute.environment_variable, message: e.message)
|
77
79
|
end
|
78
80
|
end
|
79
81
|
|
data/lib/clamp/command.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "clamp/messages"
|
2
4
|
require "clamp/errors"
|
3
5
|
require "clamp/help"
|
@@ -48,6 +50,7 @@ module Clamp
|
|
48
50
|
parse_options
|
49
51
|
parse_parameters
|
50
52
|
parse_subcommand
|
53
|
+
verify_required_options_are_set
|
51
54
|
handle_remaining_arguments
|
52
55
|
end
|
53
56
|
|
@@ -81,7 +84,7 @@ module Clamp
|
|
81
84
|
#
|
82
85
|
# @ param [String] name subcommand_name
|
83
86
|
def subcommand_missing(name)
|
84
|
-
signal_usage_error(Clamp.message(:no_such_subcommand, :
|
87
|
+
signal_usage_error(Clamp.message(:no_such_subcommand, name: name))
|
85
88
|
end
|
86
89
|
|
87
90
|
include Clamp::Option::Parsing
|
@@ -122,6 +125,11 @@ module Clamp
|
|
122
125
|
include Clamp::Subcommand::Declaration
|
123
126
|
include Help
|
124
127
|
|
128
|
+
# An alternative to "def execute"
|
129
|
+
def execute(&block)
|
130
|
+
define_method(:execute, &block)
|
131
|
+
end
|
132
|
+
|
125
133
|
# Create an instance of this command class, and run it.
|
126
134
|
#
|
127
135
|
# @param [String] invocation_path the path used to invoke the command
|