command_kit 0.1.0.pre1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +15 -0
  3. data/.rubocop.yml +138 -0
  4. data/ChangeLog.md +34 -2
  5. data/Gemfile +3 -0
  6. data/README.md +135 -214
  7. data/Rakefile +3 -2
  8. data/command_kit.gemspec +4 -4
  9. data/examples/colors.rb +30 -0
  10. data/examples/command.rb +65 -0
  11. data/examples/pager.rb +30 -0
  12. data/gemspec.yml +10 -2
  13. data/lib/command_kit/arguments/argument.rb +16 -44
  14. data/lib/command_kit/arguments/argument_value.rb +3 -30
  15. data/lib/command_kit/arguments.rb +66 -20
  16. data/lib/command_kit/colors.rb +253 -45
  17. data/lib/command_kit/command.rb +50 -3
  18. data/lib/command_kit/command_name.rb +9 -0
  19. data/lib/command_kit/commands/auto_load/subcommand.rb +3 -0
  20. data/lib/command_kit/commands/auto_load.rb +16 -0
  21. data/lib/command_kit/commands/auto_require.rb +16 -0
  22. data/lib/command_kit/commands/command.rb +3 -0
  23. data/lib/command_kit/commands/help.rb +2 -0
  24. data/lib/command_kit/commands/parent_command.rb +7 -0
  25. data/lib/command_kit/commands/subcommand.rb +15 -0
  26. data/lib/command_kit/commands.rb +40 -4
  27. data/lib/command_kit/description.rb +15 -2
  28. data/lib/command_kit/env/home.rb +9 -0
  29. data/lib/command_kit/env/path.rb +15 -0
  30. data/lib/command_kit/env.rb +4 -0
  31. data/lib/command_kit/examples.rb +15 -2
  32. data/lib/command_kit/exception_handler.rb +4 -0
  33. data/lib/command_kit/help/man.rb +74 -47
  34. data/lib/command_kit/help.rb +10 -1
  35. data/lib/command_kit/inflector.rb +49 -17
  36. data/lib/command_kit/interactive.rb +239 -0
  37. data/lib/command_kit/main.rb +20 -9
  38. data/lib/command_kit/man.rb +44 -0
  39. data/lib/command_kit/open_app.rb +69 -0
  40. data/lib/command_kit/options/option.rb +36 -9
  41. data/lib/command_kit/options/option_value.rb +42 -3
  42. data/lib/command_kit/options/parser.rb +44 -17
  43. data/lib/command_kit/options/quiet.rb +3 -0
  44. data/lib/command_kit/options/verbose.rb +5 -0
  45. data/lib/command_kit/options/version.rb +6 -0
  46. data/lib/command_kit/options.rb +59 -10
  47. data/lib/command_kit/os/linux.rb +157 -0
  48. data/lib/command_kit/os.rb +165 -11
  49. data/lib/command_kit/package_manager.rb +200 -0
  50. data/lib/command_kit/pager.rb +84 -9
  51. data/lib/command_kit/printing/indent.rb +25 -2
  52. data/lib/command_kit/printing.rb +23 -0
  53. data/lib/command_kit/program_name.rb +7 -0
  54. data/lib/command_kit/stdio.rb +24 -0
  55. data/lib/command_kit/sudo.rb +40 -0
  56. data/lib/command_kit/terminal.rb +159 -0
  57. data/lib/command_kit/usage.rb +14 -0
  58. data/lib/command_kit/version.rb +1 -1
  59. data/lib/command_kit/xdg.rb +21 -1
  60. data/lib/command_kit.rb +1 -0
  61. data/spec/arguments/argument_spec.rb +5 -41
  62. data/spec/arguments/argument_value_spec.rb +1 -61
  63. data/spec/arguments_spec.rb +8 -25
  64. data/spec/colors_spec.rb +277 -13
  65. data/spec/command_name_spec.rb +1 -1
  66. data/spec/command_spec.rb +4 -1
  67. data/spec/commands/auto_load/subcommand_spec.rb +1 -1
  68. data/spec/commands/auto_load_spec.rb +1 -1
  69. data/spec/commands/auto_require_spec.rb +2 -2
  70. data/spec/commands/help_spec.rb +1 -1
  71. data/spec/commands/parent_command_spec.rb +1 -1
  72. data/spec/commands/subcommand_spec.rb +1 -1
  73. data/spec/commands_spec.rb +2 -2
  74. data/spec/description_spec.rb +1 -25
  75. data/spec/env/home_spec.rb +1 -1
  76. data/spec/env/path_spec.rb +1 -1
  77. data/spec/examples_spec.rb +1 -25
  78. data/spec/exception_handler_spec.rb +1 -1
  79. data/spec/help/man_spec.rb +316 -0
  80. data/spec/help_spec.rb +0 -25
  81. data/spec/inflector_spec.rb +71 -9
  82. data/spec/interactive_spec.rb +415 -0
  83. data/spec/main_spec.rb +7 -7
  84. data/spec/man_spec.rb +46 -0
  85. data/spec/open_app_spec.rb +85 -0
  86. data/spec/options/option_spec.rb +48 -9
  87. data/spec/options/option_value_spec.rb +53 -4
  88. data/spec/options_spec.rb +1 -1
  89. data/spec/os/linux_spec.rb +154 -0
  90. data/spec/os_spec.rb +201 -14
  91. data/spec/package_manager_spec.rb +806 -0
  92. data/spec/pager_spec.rb +78 -15
  93. data/spec/printing/indent_spec.rb +1 -1
  94. data/spec/printing_spec.rb +10 -2
  95. data/spec/program_name_spec.rb +1 -1
  96. data/spec/spec_helper.rb +0 -3
  97. data/spec/sudo_spec.rb +51 -0
  98. data/spec/{console_spec.rb → terminal_spec.rb} +65 -35
  99. data/spec/usage_spec.rb +2 -2
  100. data/spec/xdg_spec.rb +1 -1
  101. metadata +32 -13
  102. data/lib/command_kit/arguments/usage.rb +0 -6
  103. data/lib/command_kit/console.rb +0 -141
  104. data/lib/command_kit/options/usage.rb +0 -6
@@ -18,6 +18,9 @@ module CommandKit
18
18
  module Quiet
19
19
  include Options
20
20
 
21
+ #
22
+ # @api private
23
+ #
21
24
  module ModuleMethods
22
25
  #
23
26
  # Defines a `-q, --quiet` option.
@@ -18,6 +18,9 @@ module CommandKit
18
18
  module Verbose
19
19
  include Options
20
20
 
21
+ #
22
+ # @api private
23
+ #
21
24
  module ModuleMethods
22
25
  #
23
26
  # Defines a `-v, --verbose` option or extends {ModuleMethods}, depending
@@ -47,6 +50,8 @@ module CommandKit
47
50
  #
48
51
  # @return [Boolean]
49
52
  #
53
+ # @api public
54
+ #
50
55
  def verbose?
51
56
  @verbose
52
57
  end
@@ -35,6 +35,8 @@ module CommandKit
35
35
  # @return [String, nil]
36
36
  # The classes version string.
37
37
  #
38
+ # @api public
39
+ #
38
40
  def version(new_version=nil)
39
41
  if new_version
40
42
  @version = new_version
@@ -47,6 +49,8 @@ module CommandKit
47
49
  #
48
50
  # @see ClassMethods#version
49
51
  #
52
+ # @api public
53
+ #
50
54
  def version
51
55
  self.class.version
52
56
  end
@@ -54,6 +58,8 @@ module CommandKit
54
58
  #
55
59
  # Prints the version.
56
60
  #
61
+ # @api public
62
+ #
57
63
  def print_version
58
64
  puts "#{command_name} #{version}"
59
65
  end
@@ -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 instance variables
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
@@ -34,6 +38,9 @@ module CommandKit
34
38
  module Options
35
39
  include Parser
36
40
 
41
+ #
42
+ # @api private
43
+ #
37
44
  module ModuleMethods
38
45
  #
39
46
  # Extends {ClassMethods} or {ModuleMethods}, depending on whether
@@ -64,6 +71,8 @@ module CommandKit
64
71
  #
65
72
  # @return [Hash{Symbol => Option}]
66
73
  #
74
+ # @api semipublic
75
+ #
67
76
  def options
68
77
  @options ||= if superclass.kind_of?(ClassMethods)
69
78
  superclass.options.dup
@@ -78,6 +87,31 @@ module CommandKit
78
87
  # @param [Symbol] name
79
88
  # The option name.
80
89
  #
90
+ # @param [Hash{Symbol => Object}] kwargs
91
+ # Keyword arguments.
92
+ #
93
+ # @option kwargs [String, nil] short
94
+ # Optional short-flag for the option.
95
+ #
96
+ # @option kwargs [String, nil] long
97
+ # Optional explicit long-flag for the option.
98
+ #
99
+ # @option kwargs [Boolean] equals
100
+ # Specifies whether the option is of the form (`--opt=value`).
101
+ #
102
+ # @option kwargs [Hash{Symbol => Object}, true, false, nil] value
103
+ # Keyword arguments for {OptionValue#initialize}, or `nil` if the option
104
+ # has no additional value.
105
+ #
106
+ # @option value [Class, Hash, Array, Regexp] type
107
+ # The type of the option's value.
108
+ #
109
+ # @option value [String, nil] usage
110
+ # The usage string for the option's value.
111
+ #
112
+ # @option kwargs [String] desc
113
+ # The description for the option.
114
+ #
81
115
  # @yield [(value)]
82
116
  # If a block is given, it will be passed the parsed option value.
83
117
  #
@@ -86,6 +120,10 @@ module CommandKit
86
120
  #
87
121
  # @return [Option]
88
122
  #
123
+ # @raise [TypeError]
124
+ # The `value` keyword argument was not a `Hash`, `true`, `false`, or
125
+ # `nil`.
126
+ #
89
127
  # @example Define an option:
90
128
  # option :foo, desc: "Foo option"
91
129
  #
@@ -139,6 +177,8 @@ module CommandKit
139
177
  # # ...
140
178
  # end
141
179
  #
180
+ # @api public
181
+ #
142
182
  def option(name,**kwargs,&block)
143
183
  options[name] = Option.new(name,**kwargs,&block)
144
184
  end
@@ -147,6 +187,9 @@ module CommandKit
147
187
  # Hash of parsed option values.
148
188
  #
149
189
  # @return [Hash{Symbol => Object}]
190
+ #
191
+ # @api semipublic
192
+ #
150
193
  attr_reader :options
151
194
 
152
195
  #
@@ -154,7 +197,13 @@ module CommandKit
154
197
  # {Parser#option_parser option parser}.
155
198
  #
156
199
  # @param [Hash{Symbol => Object}] options
157
- # Optional pre-populated options hash.
200
+ # Optional prepopulated options hash.
201
+ #
202
+ # @note
203
+ # The {#option_parser} will populate {#options} and also call any
204
+ # {ClassMethods#option option} blocks with the parsed option values.
205
+ #
206
+ # @api public
158
207
  #
159
208
  def initialize(options: {}, **kwargs)
160
209
  @options = options
@@ -0,0 +1,157 @@
1
+ require 'command_kit/os'
2
+
3
+ module CommandKit
4
+ module OS
5
+ #
6
+ # Provides methods for determining the specific type of Linux.
7
+ #
8
+ # ## Example
9
+ #
10
+ # require 'command_kit/command'
11
+ # require 'command_kit/os/linux'
12
+ #
13
+ # class Command < CommandKit::Command
14
+ #
15
+ # include CommandKit::OS::Linux
16
+ #
17
+ # def run
18
+ # if debian_linux?
19
+ # # ...
20
+ # elsif redhat_linux?
21
+ # # ...
22
+ # elsif suse_linux?
23
+ # # ...
24
+ # elsif arch_linux?
25
+ # # ...
26
+ # end
27
+ # end
28
+ # end
29
+ #
30
+ # @since 0.2.0
31
+ #
32
+ module Linux
33
+ #
34
+ # @api private
35
+ #
36
+ module ModuleMethods
37
+ #
38
+ # Extends {ClassMethods} or {ModuleMethods}, depending on whether
39
+ # {OS} is being included into a class or a module..
40
+ #
41
+ # @param [Class, Module] context
42
+ # The class or module which is including {OS}.
43
+ #
44
+ def included(context)
45
+ super(context)
46
+
47
+ if context.class == Module
48
+ context.extend ModuleMethods
49
+ else
50
+ context.extend ClassMethods
51
+ end
52
+ end
53
+ end
54
+
55
+ extend ModuleMethods
56
+
57
+ module ClassMethods
58
+ #
59
+ # Determines the specific Linux distro.
60
+ #
61
+ # @return [:fedora, :redhat, :debian, :suse, :arch, nil]
62
+ # Returns the type of Linux distro or `nil` if the Linux distro could
63
+ # not be determined.
64
+ #
65
+ # @api semipublic
66
+ #
67
+ def linux_distro
68
+ if File.file?('/etc/fedora-release') then :fedora
69
+ elsif File.file?('/etc/redhat-release') then :redhat
70
+ elsif File.file?('/etc/debian_version') then :debian
71
+ elsif File.file?('/etc/SuSE-release') then :suse
72
+ elsif File.file?('/etc/arch-release') then :arch
73
+ end
74
+ end
75
+ end
76
+
77
+ # The Linux distro.
78
+ #
79
+ # @return [:fedora, :redhat, :debian, :suse, :arch, nil]
80
+ #
81
+ # @api public
82
+ attr_reader :linux_distro
83
+
84
+ #
85
+ # Initializes the command.
86
+ #
87
+ # @param [:fedora, :redhat, :debian, :suse, :arch, nil] linux_distro
88
+ # Overrides the default detected Linux distro.
89
+ #
90
+ # @param [Hash{Symbol => Object}] kwargs
91
+ # Additional keyword arguments.
92
+ #
93
+ # @api public
94
+ #
95
+ def initialize(linux_distro: self.class.linux_distro, **kwargs)
96
+ super(**kwargs)
97
+
98
+ @linux_distro = linux_distro
99
+ end
100
+
101
+ #
102
+ # Determines if the current OS is RedHat Linux based distro.
103
+ #
104
+ # @return [Boolean]
105
+ #
106
+ # @api public
107
+ #
108
+ def redhat_linux?
109
+ @linux_distro == :redhat
110
+ end
111
+
112
+ #
113
+ # Determines if the current OS is Fedora Linux based distro.
114
+ #
115
+ # @return [Boolean]
116
+ #
117
+ # @api public
118
+ #
119
+ def fedora_linux?
120
+ @linux_distro == :fedora
121
+ end
122
+
123
+ #
124
+ # Determines if the current OS is Debian Linux based distro.
125
+ #
126
+ # @return [Boolean]
127
+ #
128
+ # @api public
129
+ #
130
+ def debian_linux?
131
+ @linux_distro == :debian
132
+ end
133
+
134
+ #
135
+ # Determines if the current OS is SUSE Linux based distro.
136
+ #
137
+ # @return [Boolean]
138
+ #
139
+ # @api public
140
+ #
141
+ def suse_linux?
142
+ @linux_distro == :suse
143
+ end
144
+
145
+ #
146
+ # Determines if the current OS is Arch Linux based distro.
147
+ #
148
+ # @return [Boolean]
149
+ #
150
+ # @api public
151
+ #
152
+ def arch_linux?
153
+ @linux_distro == :arch
154
+ end
155
+ end
156
+ end
157
+ end
@@ -4,26 +4,111 @@ module CommandKit
4
4
  #
5
5
  # ## Examples
6
6
  #
7
- # include CommandKit::OS
7
+ # require 'command_kit/command'
8
+ # require 'command_kit/os'
8
9
  #
9
- # def main(*argv)
10
- # if linux?
11
- # # ...
12
- # elsif macos?
13
- # # ...
14
- # elsif windows?
15
- # # ...
10
+ # class Command < CommandKit::Command
11
+ #
12
+ # include CommandKit::OS
13
+ #
14
+ # def main(*argv)
15
+ # if linux?
16
+ # # ...
17
+ # elsif macos?
18
+ # # ...
19
+ # elsif freebsd?
20
+ # # ...
21
+ # elsif windows?
22
+ # # ...
23
+ # end
16
24
  # end
25
+ #
17
26
  # end
18
27
  #
19
28
  module OS
29
+ #
30
+ # @api private
31
+ #
32
+ module ModuleMethods
33
+ #
34
+ # Extends {ClassMethods} or {ModuleMethods}, depending on whether
35
+ # {OS} is being included into a class or a module..
36
+ #
37
+ # @param [Class, Module] context
38
+ # The class or module which is including {OS}.
39
+ #
40
+ def included(context)
41
+ super(context)
42
+
43
+ if context.class == Module
44
+ context.extend ModuleMethods
45
+ else
46
+ context.extend ClassMethods
47
+ end
48
+ end
49
+ end
50
+
51
+ extend ModuleMethods
52
+
53
+ module ClassMethods
54
+ #
55
+ # Determines the current OS.
56
+ #
57
+ # @return [:linux, :macos, :freebsd, :openbsd, :netbsd, :windows, nil]
58
+ # The OS type or `nil` if the OS could not be determined.
59
+ #
60
+ # @api semipublic
61
+ #
62
+ # @since 0.2.0
63
+ #
64
+ def os
65
+ if RUBY_PLATFORM.include?('linux') then :linux
66
+ elsif RUBY_PLATFORM.include?('darwin') then :macos
67
+ elsif RUBY_PLATFORM.include?('freebsd') then :freebsd
68
+ elsif RUBY_PLATFORM.include?('openbsd') then :openbsd
69
+ elsif RUBY_PLATFORM.include?('netbsd') then :netbsd
70
+ elsif Gem.win_platform? then :windows
71
+ end
72
+ end
73
+ end
74
+
75
+ # The current OS.
76
+ #
77
+ # @return [:linux, :macos, :freebsd, :openbsd, :netbsd, :windows, nil]
78
+ #
79
+ # @api public
80
+ #
81
+ # @since 0.2.0
82
+ attr_reader :os
83
+
84
+ #
85
+ # Initializes the command.
86
+ #
87
+ # @param [:linux, :macos, :freebsd, :openbsd, :netbsd, :windows, nil] os
88
+ # Overrides the default OS.
89
+ #
90
+ # @param [Hash{Symbol => Object}] kwargs
91
+ # Additional keyword arguments.
92
+ #
93
+ # @api public
94
+ #
95
+ # @since 0.2.0
96
+ #
97
+ def initialize(os: self.class.os, **kwargs)
98
+ super(**kwargs)
99
+
100
+ @os = os
101
+ end
102
+
20
103
  #
21
104
  # Determines if the current OS is Linux.
22
105
  #
23
106
  # @return [Boolean]
24
107
  #
108
+ # @api public
109
+ #
25
110
  def linux?
26
- RUBY_PLATFORM.include?('linux')
111
+ @os == :linux
27
112
  end
28
113
 
29
114
  #
@@ -31,8 +116,75 @@ module CommandKit
31
116
  #
32
117
  # @return [Boolean]
33
118
  #
119
+ # @api public
120
+ #
34
121
  def macos?
35
- RUBY_PLATFORM.include?('darwin')
122
+ @os == :macos
123
+ end
124
+
125
+ #
126
+ # Determines if the current OS is FreeBSD.
127
+ #
128
+ # @return [Boolean]
129
+ #
130
+ # @api public
131
+ #
132
+ # @since 0.2.0
133
+ #
134
+ def freebsd?
135
+ @os == :freebsd
136
+ end
137
+
138
+ #
139
+ # Determines if the current OS is OpenBSD.
140
+ #
141
+ # @return [Boolean]
142
+ #
143
+ # @api public
144
+ #
145
+ # @since 0.2.0
146
+ #
147
+ def openbsd?
148
+ @os == :openbsd
149
+ end
150
+
151
+ #
152
+ # Determines if the current OS is NetBSD.
153
+ #
154
+ # @return [Boolean]
155
+ #
156
+ # @api public
157
+ #
158
+ # @since 0.2.0
159
+ #
160
+ def netbsd?
161
+ @os == :netbsd
162
+ end
163
+
164
+ #
165
+ # Determines if the current OS is BSD based.
166
+ #
167
+ # @return [Boolean]
168
+ #
169
+ # @since 0.2.0
170
+ #
171
+ # @api public
172
+ #
173
+ def bsd?
174
+ freebsd? || openbsd? || netbsd?
175
+ end
176
+
177
+ #
178
+ # Determines if the current OS is UNIX based.
179
+ #
180
+ # @return [Boolean]
181
+ #
182
+ # @since 0.2.0
183
+ #
184
+ # @api public
185
+ #
186
+ def unix?
187
+ linux? || macos? || bsd?
36
188
  end
37
189
 
38
190
  #
@@ -40,8 +192,10 @@ module CommandKit
40
192
  #
41
193
  # @return [Boolean]
42
194
  #
195
+ # @api public
196
+ #
43
197
  def windows?
44
- Gem.win_platform?
198
+ @os == :windows
45
199
  end
46
200
  end
47
201
  end