command_kit 0.1.0.pre1 → 0.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,82 +7,52 @@ module CommandKit
7
7
  #
8
8
  class Argument < ArgumentValue
9
9
 
10
+ # The argument's name.
11
+ #
10
12
  # @return [Symbol]
11
13
  attr_reader :name
12
14
 
13
- # @return [Boolean]
14
- attr_reader :repeats
15
-
16
- # @return [String, nil]
15
+ # The argument's description.
16
+ #
17
+ # @return [String]
17
18
  attr_reader :desc
18
19
 
19
- # @return [Regexp, nil]
20
- attr_reader :pattern
21
-
22
- # @return [Proc, nil]
23
- attr_reader :parser
24
-
25
- # @return [Proc, nil]
26
- attr_reader :block
27
-
28
20
  #
29
21
  # Initializes the argument.
30
22
  #
31
23
  # @param [Symbol] name
32
- #
33
- # @param [Class, Hash, Array, Regexp] type
24
+ # The name of the argument.
34
25
  #
35
26
  # @param [String, nil] usage
36
- #
37
- # @param [Object, Proc, nil] default
27
+ # The usage string for the argument. Defaults to the argument's name.
38
28
  #
39
29
  # @param [Boolean] required
30
+ # Specifies whether the argument is required or optional.
40
31
  #
41
32
  # @param [Boolean] repeats
33
+ # Specifies whether the argument can be repeated multiple times.
42
34
  #
43
35
  # @param [String] desc
44
- #
45
- # @note `usage` will be assigned a default value based on `type` and
46
- # `name`.
36
+ # The description for the argument.
47
37
  #
48
38
  # @yield [(value)]
39
+ # If a block is given, it will be used to parse the argument's value.
40
+ # Note: not currently used.
49
41
  #
50
42
  # @yieldparam [Object, nil] value
51
43
  #
52
- def initialize(name, type: String,
53
- usage: name.to_s.upcase,
54
- default: nil,
44
+ def initialize(name, usage: name.to_s.upcase,
55
45
  required: true,
56
46
  repeats: false,
57
- desc: ,
58
- &block)
47
+ desc: )
59
48
  super(
60
- type: type,
61
49
  usage: usage,
62
- default: default,
63
50
  required: required
64
51
  )
65
52
 
66
53
  @name = name
67
54
  @repeats = repeats
68
55
  @desc = desc
69
-
70
- @pattern, @parser = self.class.parser(@type)
71
-
72
- @block = block
73
- end
74
-
75
- #
76
- # Looks up the option parser for the given `OptionParser` type.
77
- #
78
- # @param [Class] type
79
- # The `OptionParser` type class.
80
- #
81
- # @return [(Regexp, Proc), nil]
82
- # The matching pattern and converter proc.
83
- #
84
- def self.parser(type)
85
- OptionParser::DefaultList.search(:atype,type)
86
56
  end
87
57
 
88
58
  #
@@ -5,16 +5,6 @@ module CommandKit
5
5
  #
6
6
  class ArgumentValue
7
7
 
8
- # The desired type of the argument value.
9
- #
10
- # @return [Class, Hash, Array, Regexp, nil]
11
- attr_reader :type
12
-
13
- # The default parsed value for the argument value.
14
- #
15
- # @return [Object, Proc, nil]
16
- attr_reader :default
17
-
18
8
  # Specifies whether the argument value is required or optional.
19
9
  #
20
10
  # @return [Boolean]
@@ -28,22 +18,14 @@ module CommandKit
28
18
  #
29
19
  # Initializes the argument value.
30
20
  #
31
- # @param [Class, Hash, Array, Regexp] type
32
- # The type of the argument value.
33
- #
34
21
  # @param [Boolean] required
35
22
  # Specifies whether the argument value is required or optional.
36
23
  #
37
24
  # @param [String] usage
38
25
  # The usage string to represent the argument value.
39
26
  #
40
- # @param [Object, Proc, nil] default
41
- # The default parsed value for the argument value.
42
- #
43
- def initialize(type: nil, required: true, default: nil, usage: )
44
- @type = type
27
+ def initialize(required: true, usage: )
45
28
  @required = required
46
- @default = default
47
29
  @usage = usage
48
30
  end
49
31
 
@@ -65,17 +47,6 @@ module CommandKit
65
47
  !@required
66
48
  end
67
49
 
68
- #
69
- # Returns a new default value.
70
- #
71
- # @return [Object]
72
- #
73
- def default_value
74
- if @default.respond_to?(:call) then @default.call
75
- else @default.dup
76
- end
77
- end
78
-
79
50
  end
80
51
  end
81
52
  end
@@ -13,16 +13,58 @@ module CommandKit
13
13
  #
14
14
  # The command class base-class.
15
15
  #
16
+ # @note
17
+ # Command classes are not required to inherit from {Command}. If you do not
18
+ # wish to inherit from the {Command} base class, you can instead include
19
+ # the individual modules. This class only exists as a convenience.
20
+ #
16
21
  # ## Examples
17
22
  #
18
23
  # class MyCmd < CommandKit::Command
19
24
  #
20
- # # ...
25
+ # usage '[OPTIONS] [-o OUTPUT] FILE'
26
+ #
27
+ # option :count, short: '-c',
28
+ # value: {
29
+ # type: Integer,
30
+ # default: 1
31
+ # },
32
+ # desc: "Number of times"
33
+ #
34
+ # option :output, short: '-o',
35
+ # value: {
36
+ # type: String,
37
+ # usage: 'FILE'
38
+ # },
39
+ # desc: "Optional output file"
40
+ #
41
+ # argument :file, required: true,
42
+ # usage: 'FILE',
43
+ # desc: "Input file"
44
+ #
45
+ # examples [
46
+ # '-o path/to/output.txt path/to/input.txt',
47
+ # '-v -c 2 -o path/to/output.txt path/to/input.txt',
48
+ # ]
21
49
  #
50
+ # description 'Example command'
51
+ #
52
+ # def run(*files)
53
+ # # ...
54
+ # end
22
55
  # end
23
56
  #
24
- # @note Command classes are not required to inherit from {Command}. This class
25
- # only exists as a convenience.
57
+ # ### initialize and using ivars
58
+ #
59
+ # option :verbose, short: '-v', desc: "Increase verbose level" do
60
+ # @verbose += 1
61
+ # end
62
+ #
63
+ # def initialize(**kwargs)
64
+ # super(**kwargs)
65
+ #
66
+ # @verbose = 0
67
+ # end
26
68
  #
27
69
  class Command
28
70
 
@@ -158,6 +158,12 @@ module CommandKit
158
158
  end
159
159
  end
160
160
 
161
+ #
162
+ # Initializes the command.
163
+ #
164
+ # @note Adds a special rule to the {Options#option_parser #option_parser} to
165
+ # stop parsing options when the first non-option is encountered.
166
+ #
161
167
  def initialize(**kwargs)
162
168
  super(**kwargs)
163
169
 
@@ -3,6 +3,9 @@ require 'command_kit/commands/subcommand'
3
3
  module CommandKit
4
4
  module Commands
5
5
  class AutoLoad < Module
6
+ #
7
+ # Represents a registered subcommand that will be auto-loaded.
8
+ #
6
9
  class Subcommand < Commands::Subcommand
7
10
 
8
11
  # The fully qualified constant of the command class.
@@ -1,5 +1,8 @@
1
1
  module CommandKit
2
2
  module Commands
3
+ #
4
+ # Represents a registered subcommand.
5
+ #
3
6
  class Subcommand
4
7
 
5
8
  # The command class.
@@ -54,7 +54,9 @@ module CommandKit
54
54
  if new_description
55
55
  @description = new_description
56
56
  else
57
- @description || (superclass.description if superclass.kind_of?(ClassMethods))
57
+ @description || if superclass.kind_of?(ClassMethods)
58
+ superclass.description
59
+ end
58
60
  end
59
61
  end
60
62
  end
@@ -61,7 +61,9 @@ module CommandKit
61
61
  if new_examples
62
62
  @examples = Array(new_examples)
63
63
  else
64
- @examples || (superclass.examples if superclass.kind_of?(ClassMethods))
64
+ @examples || if superclass.kind_of?(ClassMethods)
65
+ superclass.examples
66
+ end
65
67
  end
66
68
  end
67
69
  end
@@ -36,6 +36,9 @@ module CommandKit
36
36
 
37
37
  extend ModuleMethods
38
38
 
39
+ #
40
+ # Class-level methods.
41
+ #
39
42
  module ClassMethods
40
43
  #
41
44
  # Prints `--help` information.
@@ -1,16 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'command_kit/command_name'
4
+ require 'command_kit/help'
5
+ require 'command_kit/stdio'
6
+
3
7
  module CommandKit
4
8
  module Help
5
9
  #
6
10
  # Allows displaying a man-page instead of the usual `--help` output.
7
11
  #
8
- # ## Environment Variables
12
+ # ## Examples
13
+ #
14
+ # class Foo < CommandKit::Command
15
+ #
16
+ # include CommandKit::Help::Man
9
17
  #
10
- # * `TERM` - Specifies the type of terminal. When set to `DUMB`, it will
11
- # disable man-page help output.
18
+ # man_dir "#{__dir__}/../../man"
19
+ #
20
+ # end
12
21
  #
13
22
  module Man
23
+ include CommandName
24
+ include Help
25
+ include Stdio
26
+
14
27
  module ModuleMethods
15
28
  #
16
29
  # Extends {ClassMethods} or {ModuleMethods}, depending on whether
@@ -33,7 +46,7 @@ module CommandKit
33
46
  extend ModuleMethods
34
47
 
35
48
  #
36
- # Defines class-level methods.
49
+ # Class-level methods.
37
50
  #
38
51
  module ClassMethods
39
52
  #
@@ -46,74 +59,96 @@ module CommandKit
46
59
  # The class'es or superclass'es man-page directory.
47
60
  #
48
61
  # @example
49
- # man_dir File.expand_path('../../../man',__FILE__)
62
+ # man_dir "#{__dir__}/../../man"
50
63
  #
51
64
  def man_dir(new_man_dir=nil)
52
65
  if new_man_dir
53
- @man_dir = File.expand_path(new_man_dir)
66
+ @man_dir = new_man_dir
54
67
  else
55
- @man_dir || (superclass.man_dir if superclass.kind_of?(ClassMethods))
68
+ @man_dir || if superclass.kind_of?(ClassMethods)
69
+ superclass.man_dir
70
+ end
56
71
  end
57
72
  end
58
- end
59
73
 
60
- #
61
- # Determines if displaying man pages is supported.
62
- #
63
- # @return [Boolean]
64
- # Indicates whether the `TERM` environment variable is not `dumb`
65
- # and `$stdout` is a TTY.
66
- #
67
- def self.supported?
68
- ENV['TERM'] != 'dumb' && $stdout.tty?
74
+ #
75
+ # Gets or sets the class'es man-page file name.
76
+ #
77
+ # @param [String, nil] new_man_page
78
+ # If a String is given, the class'es man-page file name will be set.
79
+ #
80
+ # @return [String]
81
+ # The class'es or superclass'es man-page file name.
82
+ #
83
+ def man_page(new_man_page=nil)
84
+ if new_man_page
85
+ @man_page = new_man_page
86
+ else
87
+ @man_page || "#{command_name}.1"
88
+ end
89
+ end
69
90
  end
70
91
 
71
92
  #
72
- # Returns the man-page file name for the given command name.
93
+ # Displays the given man page.
94
+ #
95
+ # @param [String] page
96
+ # The man page file name.
73
97
  #
74
- # @param [String] command
75
- # The given command name.
98
+ # @param [Integer, String, nil] section
99
+ # The optional section number to specify.
76
100
  #
77
- # @return [String]
78
- # The man-page file name.
101
+ # @return [Boolean, nil]
102
+ # Specifies whether the `man` command was successful or not.
103
+ # Returns `nil` when the `man` command is not installed.
79
104
  #
80
- def man_page(command=command_name)
81
- "#{command}.1"
105
+ def man(page, section: nil)
106
+ if section
107
+ system('man',section.to_s,page.to_s)
108
+ else
109
+ system('man',page.to_s)
110
+ end
82
111
  end
83
112
 
84
113
  #
85
- # Displays the given man page.
114
+ # Provides help information by showing one of the man pages within
115
+ # {ClassMethods#man_dir .man_dir}.
86
116
  #
87
- # @param [String] page
88
- # The man page file name.
117
+ # @param [String] man_page
118
+ # The file name of the man page to display.
89
119
  #
90
120
  # @return [Boolean, nil]
91
121
  # Specifies whether the `man` command was successful or not.
92
122
  # Returns `nil` when the `man` command is not installed.
93
123
  #
94
- def man(page=man_page)
95
- system('man',page)
124
+ # @raise [NotImplementedError]
125
+ # {ClassMethods#man_dir .man_dir} does not have a value.
126
+ #
127
+ def help_man(man_page=self.class.man_page)
128
+ unless self.class.man_dir
129
+ raise(NotImplementedError,"#{self.class}.man_dir not set")
130
+ end
131
+
132
+ man_path = File.join(self.class.man_dir,man_page)
133
+
134
+ man(man_path)
96
135
  end
97
136
 
98
137
  #
99
- # Displays the {#man_page} instead of the usual `--help` output.
138
+ # Displays the {ClassMethods#man_page .man_page} in
139
+ # {ClassMethods#man_dir .man_dir} instead of the usual `--help` output.
100
140
  #
101
141
  # @raise [NotImplementedError]
102
- # {ClassMethods#man_dir man_dir} does not have a value.
142
+ # {ClassMethods#man_dir .man_dir} does not have a value.
103
143
  #
104
144
  # @note
105
145
  # if `TERM` is `dumb` or `$stdout` is not a TTY, fallsback to printing
106
146
  # the usual `--help` output.
107
147
  #
108
148
  def help
109
- if Man.supported?
110
- unless self.class.man_dir
111
- raise(NotImplementedError,"#{self.class}.man_dir not set")
112
- end
113
-
114
- man_path = File.join(self.class.man_dir,man_page)
115
-
116
- if man(man_path).nil?
149
+ if stdout.tty?
150
+ if help_man.nil?
151
+ # the `man` command is not installed
117
152
  super
118
153
  end
119
154
  else