command_kit 0.1.0.pre1 → 0.1.0.pre2

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.
@@ -82,6 +82,8 @@ module CommandKit
82
82
  # @return [Integer]
83
83
  # The exit status code.
84
84
  #
85
+ # @note `argv` is splatted into {#run}.
86
+ #
85
87
  def main(argv=[])
86
88
  run(*argv)
87
89
  return 0
@@ -9,24 +9,28 @@ module CommandKit
9
9
  #
10
10
  # include CommandKit::Options
11
11
  #
12
- # option :foo, type: String,
13
- # short: '-f',
14
- # desc: "Foo option"
12
+ # option :foo, short: '-f',
13
+ # value: {type: String},
14
+ # desc: "Foo option"
15
15
  #
16
- # option :bar, type: String,
17
- # short: '-b',
18
- # usage: 'STR:STR:...',
16
+ # option :bar, short: '-b',
17
+ # value: {
18
+ # type: String,
19
+ # usage: 'STR:STR:...'
20
+ # },
19
21
  # desc: "Bar option" do |arg|
20
22
  # @bar = arg.split(':')
21
23
  # end
24
+ #
25
+ # ### initialize and using ivars
22
26
  #
23
- # option :number, type: Integer,
27
+ # option :number, value: {type: Integer},
24
28
  # desc: 'Numbers' do |num|
25
29
  # @numbers << num
26
30
  # end
27
31
  #
28
- # def initialize
29
- # super
32
+ # def initialize(**kwargs)
33
+ # super(**kwargs)
30
34
  #
31
35
  # @numbers = []
32
36
  # end
@@ -78,6 +82,31 @@ module CommandKit
78
82
  # @param [Symbol] name
79
83
  # The option name.
80
84
  #
85
+ # @param [Hash{Symbol => Object}] kwargs
86
+ # Keyword arguments.
87
+ #
88
+ # @option kwargs [String, nil] short
89
+ # Optional short-flag for the option.
90
+ #
91
+ # @option kwargs [String, nil] long
92
+ # Optional explicit long-flag for the option.
93
+ #
94
+ # @option kwargs [Boolean] equals
95
+ # Specifies whether the option is of the form (`--opt=value`).
96
+ #
97
+ # @option kwargs [Hash{Symbol => Object}, true, false, nil] value
98
+ # Keyword arguments for {OptionValue#initialize}, or `nil` if the option
99
+ # has no additional value.
100
+ #
101
+ # @option value [Class, Hash, Array, Regexp] type
102
+ # The type of the option's value.
103
+ #
104
+ # @option value [String, nil] usage
105
+ # The usage string for the option's value.
106
+ #
107
+ # @option kwargs [String] desc
108
+ # The description for the option.
109
+ #
81
110
  # @yield [(value)]
82
111
  # If a block is given, it will be passed the parsed option value.
83
112
  #
@@ -86,6 +115,10 @@ module CommandKit
86
115
  #
87
116
  # @return [Option]
88
117
  #
118
+ # @raise [TypeError]
119
+ # The `value` keyword argument was not a `Hash`, `true`, `false`, or
120
+ # `nil`.
121
+ #
89
122
  # @example Define an option:
90
123
  # option :foo, desc: "Foo option"
91
124
  #
@@ -156,6 +189,10 @@ module CommandKit
156
189
  # @param [Hash{Symbol => Object}] options
157
190
  # Optional pre-populated options hash.
158
191
  #
192
+ # @note
193
+ # The {#option_parser} will populate {#options} and also call any
194
+ # {ClassMethods#option option} blocks with the parsed option values.
195
+ #
159
196
  def initialize(options: {}, **kwargs)
160
197
  @options = options
161
198
 
@@ -13,24 +13,33 @@ module CommandKit
13
13
  #
14
14
  class Option
15
15
 
16
+ # The option's name.
17
+ #
16
18
  # @return [Symbol]
17
19
  attr_reader :name
18
20
 
21
+ # The option's optional short-flag.
22
+ #
19
23
  # @return [String, nil]
20
24
  attr_reader :short
21
25
 
26
+ # The option's long-flag.
27
+ #
22
28
  # @return [String]
23
29
  attr_reader :long
24
30
 
25
- # @return [Boolean]
26
- attr_reader :equals
27
-
31
+ # The option value's type.
32
+ #
28
33
  # @return [OptionValue, nil]
29
34
  attr_reader :value
30
35
 
36
+ # The option's description.
37
+ #
31
38
  # @return [String]
32
39
  attr_reader :desc
33
40
 
41
+ # The optional block that will receive the parsed option value.
42
+ #
34
43
  # @return [Proc, nil]
35
44
  attr_reader :block
36
45
 
@@ -38,26 +47,39 @@ module CommandKit
38
47
  # Initializes the option.
39
48
  #
40
49
  # @param [Symbol] name
50
+ # The name of the option.
41
51
  #
42
52
  # @param [String, nil] short
53
+ # Optional short-flag for the option.
43
54
  #
44
55
  # @param [String, nil] long
56
+ # Optional explicit long-flag for the option.
45
57
  #
46
58
  # @param [Boolean] equals
59
+ # Specifies whether the option is of the form (`--opt=value`).
47
60
  #
48
- # @param [Hash{Symbol => Object}, nil] value
61
+ # @param [Hash{Symbol => Object}, true, false, nil] value
49
62
  # Keyword arguments for {OptionValue#initialize}, or `nil` if the option
50
63
  # has no additional value.
51
64
  #
52
65
  # @option value [Class, Hash, Array, Regexp] type
66
+ # The type of the option's value.
53
67
  #
54
68
  # @option value [String, nil] usage
69
+ # The usage string for the option's value.
55
70
  #
56
71
  # @param [String] desc
72
+ # The description for the option.
57
73
  #
58
74
  # @yield [(value)]
75
+ # If a block is given, it will be called when the option is parsed.
59
76
  #
60
77
  # @yieldparam [Object, nil] value
78
+ # The given block will be passed the parsed option's value.
79
+ #
80
+ # @raise [TypeError]
81
+ # The `value` keyword argument was not a `Hash`, `true`, `false`, or
82
+ # `nil`.
61
83
  #
62
84
  def initialize(name, short: nil,
63
85
  long: self.class.default_long_opt(name),
@@ -69,7 +91,13 @@ module CommandKit
69
91
  @short = short
70
92
  @long = long
71
93
  @equals = equals
72
- @value = OptionValue.new(**value) if value
94
+ @value = case value
95
+ when Hash then OptionValue.new(**value)
96
+ when true then OptionValue.new()
97
+ when false, nil then nil
98
+ else
99
+ raise(TypeError,"value: keyword must be Hash, true, false, or nil")
100
+ end
73
101
  @desc = desc
74
102
  @block = block
75
103
  end
@@ -79,8 +107,10 @@ module CommandKit
79
107
  # (ex: `:long_opt`).
80
108
  #
81
109
  # @param [Symbol] name
110
+ # The option name.
82
111
  #
83
112
  # @return [String]
113
+ # The long-flag for the option.
84
114
  #
85
115
  def self.default_long_opt(name)
86
116
  "--#{Inflector.dasherize(name)}"
@@ -16,6 +16,7 @@ module CommandKit
16
16
  #
17
17
  class OptionValue < Arguments::ArgumentValue
18
18
 
19
+ # Maps OptionParser types to USAGE strings.
19
20
  USAGES = {
20
21
  # NOTE: NilClass and Object are intentionally omitted
21
22
  Date => 'DATE',
@@ -36,27 +37,52 @@ module CommandKit
36
37
  Regexp => '/REGEXP/'
37
38
  }
38
39
 
40
+ # The desired type of the argument value.
41
+ #
42
+ # @return [Class, Hash, Array, Regexp, nil]
43
+ attr_reader :type
44
+
45
+ # The default parsed value for the argument value.
46
+ #
47
+ # @return [Object, Proc, nil]
48
+ attr_reader :default
49
+
39
50
  #
40
51
  # Initializes the option value.
41
52
  #
42
53
  # @param [Class, Hash, Array, Regexp] type
54
+ # The type of the option value.
55
+ #
56
+ # @param [Object, Proc, nil] default
57
+ # The default parsed value for the option value.
43
58
  #
44
59
  # @param [String, nil] usage
60
+ # The optional usage string for the option value.
45
61
  #
46
62
  # @param [Hash{Symbol => Object}] kwargs
63
+ # Additional keyword arguments.
64
+ #
65
+ # @option kwargs [Boolean] required
66
+ # Specifies whether the option value is required or optional.
47
67
  #
48
- def initialize(type: String,
49
- usage: self.class.default_usage(type),
68
+ def initialize(type: String,
69
+ default: nil,
70
+ usage: self.class.default_usage(type),
50
71
  **kwargs)
51
- super(type: type, usage: usage, **kwargs)
72
+ super(usage: usage, **kwargs)
73
+
74
+ @type = type
75
+ @default = default
52
76
  end
53
77
 
54
78
  #
55
79
  # Returns the default option value usage for the given type.
56
80
  #
57
81
  # @param [Class, Hash, Array, Regexp] type
82
+ # The option value type.
58
83
  #
59
84
  # @return [String, nil]
85
+ # A default usage string based on the option value type.
60
86
  #
61
87
  # @raise [TypeError]
62
88
  # The given type was not a Class, Hash, Array, or Regexp.
@@ -85,6 +111,17 @@ module CommandKit
85
111
  string
86
112
  end
87
113
 
114
+ #
115
+ # Returns a new default value.
116
+ #
117
+ # @return [Object]
118
+ #
119
+ def default_value
120
+ if @default.respond_to?(:call) then @default.call
121
+ else @default.dup
122
+ end
123
+ end
124
+
88
125
  end
89
126
  end
90
127
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'command_kit/stdio'
4
+ require 'command_kit/console'
4
5
  require 'command_kit/env'
5
6
  require 'command_kit/env/path'
6
7
 
@@ -16,6 +17,7 @@ module CommandKit
16
17
  #
17
18
  # def run
18
19
  # pager do |io|
20
+ # io.puts "This goes into the pager screen"
19
21
  # end
20
22
  # end
21
23
  #
@@ -34,6 +36,7 @@ module CommandKit
34
36
  #
35
37
  module Pager
36
38
  include Stdio
39
+ include Console
37
40
  include Env
38
41
  include Env::Path
39
42
 
@@ -43,6 +46,9 @@ module CommandKit
43
46
  #
44
47
  # Initializes the pager.
45
48
  #
49
+ # @param [Hash{Symbol => Object}] kwargs
50
+ # Keyword arguments.
51
+ #
46
52
  # @note
47
53
  # Respects the `PAGER` env variable, or attemps to find `less` or
48
54
  # `more` by searching the `PATH` env variable.
@@ -1,4 +1,4 @@
1
1
  module CommandKit
2
2
  # command_kit version
3
- VERSION = "0.1.0.pre1"
3
+ VERSION = "0.1.0.pre2"
4
4
  end
@@ -45,6 +45,9 @@ module CommandKit
45
45
 
46
46
  extend ModuleMethods
47
47
 
48
+ #
49
+ # Class-level methods.
50
+ #
48
51
  module ClassMethods
49
52
  #
50
53
  # Gets or sets the XDG sub-directory name used by the command.
@@ -62,7 +65,11 @@ module CommandKit
62
65
  if new_namespace
63
66
  @xdg_namespace = new_namespace.to_s
64
67
  else
65
- @xdg_namespace || (superclass.xdg_namespace if superclass.kind_of?(ClassMethods)) || command_name
68
+ @xdg_namespace || if superclass.kind_of?(ClassMethods)
69
+ superclass.xdg_namespace
70
+ else
71
+ command_name
72
+ end
66
73
  end
67
74
  end
68
75
  end
@@ -3,39 +3,19 @@ require 'command_kit/arguments/argument'
3
3
 
4
4
  describe Arguments::Argument do
5
5
  let(:name) { :foo }
6
- let(:type) { String }
7
6
  let(:usage) { 'FOO' }
8
- let(:default) { 'foo' }
9
7
  let(:required) { true }
10
8
  let(:repeats) { false }
11
9
  let(:desc) { 'Foo argument' }
12
10
 
13
11
  subject do
14
- described_class.new name, type: type,
15
- usage: usage,
16
- default: default,
12
+ described_class.new name, usage: usage,
17
13
  required: required,
18
14
  repeats: repeats,
19
15
  desc: desc
20
16
  end
21
17
 
22
18
  describe "#initialize" do
23
- context "when the type: keyword is given" do
24
- subject { described_class.new(name, type: type, desc: desc) }
25
-
26
- it "must set #type" do
27
- expect(subject.type).to eq(type)
28
- end
29
- end
30
-
31
- context "when the type: keyword is not given" do
32
- subject { described_class.new(name, desc: desc) }
33
-
34
- it "default #type to String" do
35
- expect(subject.type).to eq(String)
36
- end
37
- end
38
-
39
19
  context "when the usage: keyword is given" do
40
20
  subject { described_class.new(name, usage: usage, desc: desc) }
41
21
 
@@ -52,22 +32,6 @@ describe Arguments::Argument do
52
32
  end
53
33
  end
54
34
 
55
- context "when the default: keyword is given" do
56
- subject { described_class.new(name, default: default, desc: desc) }
57
-
58
- it "must set #default" do
59
- expect(subject.default).to eq(default)
60
- end
61
- end
62
-
63
- context "when the default: keyword is not given" do
64
- subject { described_class.new(name, desc: desc) }
65
-
66
- it "default #default to String" do
67
- expect(subject.default).to eq(nil)
68
- end
69
- end
70
-
71
35
  context "when the required: keyword is given" do
72
36
  subject { described_class.new(name, required: required, desc: desc) }
73
37
 
@@ -88,7 +52,7 @@ describe Arguments::Argument do
88
52
  subject { described_class.new(name, repeats: repeats, desc: desc) }
89
53
 
90
54
  it "must set #repeats" do
91
- expect(subject.repeats).to eq(repeats)
55
+ expect(subject.repeats?).to eq(repeats)
92
56
  end
93
57
  end
94
58
 
@@ -96,7 +60,7 @@ describe Arguments::Argument do
96
60
  subject { described_class.new(name, desc: desc) }
97
61
 
98
62
  it "default #repeats to String" do
99
- expect(subject.repeats).to eq(false)
63
+ expect(subject.repeats?).to eq(false)
100
64
  end
101
65
  end
102
66
 
@@ -2,16 +2,12 @@ require 'spec_helper'
2
2
  require 'command_kit/arguments/argument_value'
3
3
 
4
4
  describe CommandKit::Arguments::ArgumentValue do
5
- let(:type) { String }
6
5
  let(:required) { false }
7
- let(:default) { "foo" }
8
6
  let(:usage) { 'FOO' }
9
7
 
10
8
  subject do
11
9
  described_class.new(
12
- type: type,
13
10
  required: required,
14
- default: default,
15
11
  usage: usage
16
12
  )
17
13
  end
@@ -19,26 +15,10 @@ describe CommandKit::Arguments::ArgumentValue do
19
15
  describe "#initialize" do
20
16
  it "must require a usage: keyword"do
21
17
  expect {
22
- described_class.new(type: type, required: required, default: default)
18
+ described_class.new(required: required)
23
19
  }.to raise_error(ArgumentError)
24
20
  end
25
21
 
26
- context "when type: is given" do
27
- subject { described_class.new(type: type, usage: usage) }
28
-
29
- it "must set #type" do
30
- expect(subject.type).to eq(type)
31
- end
32
- end
33
-
34
- context "when type: is not given" do
35
- subject { described_class.new(usage: usage) }
36
-
37
- it "must default to nil" do
38
- expect(subject.type).to be_nil
39
- end
40
- end
41
-
42
22
  context "when required: is given" do
43
23
  subject { described_class.new(required: required, usage: usage) }
44
24
 
@@ -54,22 +34,6 @@ describe CommandKit::Arguments::ArgumentValue do
54
34
  expect(subject.required).to be(true)
55
35
  end
56
36
  end
57
-
58
- context "when default: is given" do
59
- subject { described_class.new(default: default, usage: usage) }
60
-
61
- it "must set #default" do
62
- expect(subject.default).to eq(default)
63
- end
64
- end
65
-
66
- context "when default: is not given" do
67
- subject { described_class.new(usage: usage) }
68
-
69
- it "must default to nil" do
70
- expect(subject.default).to be_nil
71
- end
72
- end
73
37
  end
74
38
 
75
39
  describe "#required?" do
@@ -99,28 +63,4 @@ describe CommandKit::Arguments::ArgumentValue do
99
63
  it { expect(subject.optional?).to be(true) }
100
64
  end
101
65
  end
102
-
103
- describe "#default_value" do
104
- context "when initialized with a default: that responded to #call" do
105
- let(:default) do
106
- ->{ [] }
107
- end
108
-
109
- it "must call the default #call method" do
110
- expect(subject.default_value).to eq(default.call)
111
- end
112
- end
113
-
114
- context "when initialized with a default: that it's an Object" do
115
- let(:default) { "" }
116
-
117
- it "must return the default: object" do
118
- expect(subject.default_value).to eq(default)
119
- end
120
-
121
- it "must duplicate the default: object each time" do
122
- expect(subject.default_value).to_not be(subject.default_value)
123
- end
124
- end
125
- end
126
66
  end