command_kit 0.5.6 → 0.6.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
  SHA256:
3
- metadata.gz: 22cdb1135f132682db99b624f27bc5cfbadb51fb988c6c5751210d9e4da994c3
4
- data.tar.gz: c01856011175c54fed46b0ab6663cb63eeb125de18767529ffc05b9ea3045d9b
3
+ metadata.gz: 5bf3011e0c065be0e6c7fd1da97f0c0de87b80674a29e782c339b63b15384992
4
+ data.tar.gz: bcad8e0d7ad0113bee65d2c5eda383f300b9764e3a0b53d90752e551299be0d0
5
5
  SHA512:
6
- metadata.gz: d12c2d1904405af1fff0e36b3d73ab3c897d47057f6f71a6db8e34b6aa4419673c0e2b4a6bec2f9cefd4f90bd72be4c86b4e44d9e82912776f14691ffecbcd82
7
- data.tar.gz: 349d3f009628535477976b63ce42a23ce30765592663b5ec76f0c07e3530edc723c2cad32441ec9c9559241825913e9afaad37822c64918b7985e3b6579703ff
6
+ metadata.gz: 9c13184c83e668c3afd46ad1ad28a7d78655f1e8602831120ead6f39f2f35f4f6ba08151339e16485ef9111690b7975af4cb6a219787ec3530fb0a822cd2c952
7
+ data.tar.gz: ba6caee506bb4085cab8a6fe8a389006e0423643a1ee35e1f0a26a2ec0e6fc1f5f53a982f3a8247fefebdf2e6fbf9a3c05afc5d78a1209f8921e1566643e30b8
data/ChangeLog.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.6.0 / 2024-06-19
2
+
3
+ * Added {CommandKit::Interactive#ask_multiline}.
4
+ * Added {CommandKit::Open}.
5
+ * Added {CommandKit::Options::VerboseLevel}.
6
+
1
7
  ### 0.5.6 / 2024-06-19
2
8
 
3
9
  #### CommandKit::Inflector
data/README.md CHANGED
@@ -229,6 +229,7 @@ end
229
229
  * [CommandKit::Help::Man](https://rubydoc.info/gems/command_kit/CommandKit/Help/Man)
230
230
  * [CommandKit::Interactive](https://rubydoc.info/gems/command_kit/CommandKit/Interactive)
231
231
  * [CommandKit::Main](https://rubydoc.info/gems/command_kit/CommandKit/Main)
232
+ * [CommandKit::Open](https://rubydoc.info/gems/command_kit/CommandKit/Open)
232
233
  * [CommandKit::Options](https://rubydoc.info/gems/command_kit/CommandKit/Options)
233
234
  * [CommandKit::Options::Quiet](https://rubydoc.info/gems/command_kit/CommandKit/Options/Quiet)
234
235
  * [CommandKit::Options::Verbose](https://rubydoc.info/gems/command_kit/CommandKit/Options/Verbose)
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
4
+ require 'command_kit/command'
5
+ require 'command_kit/interactive'
6
+
7
+ class InteractiveCmd < CommandKit::Command
8
+
9
+ include CommandKit::Interactive
10
+
11
+ description 'Demonstrates interactive prompt input'
12
+
13
+ def run
14
+ you_entered = ->(result) {
15
+ puts "You entered: #{result.inspect}"
16
+ puts
17
+ }
18
+
19
+ you_entered[ask("Single-line input")]
20
+ you_entered[ask_secret("Secret input")]
21
+ you_entered[ask_yes_or_no("Yes or no prompt")]
22
+ you_entered[ask_multiple_choice("Multiple choice", %w[Red Green Blue])]
23
+ you_entered[ask_multiline('Multi-line comment 1')]
24
+ end
25
+
26
+ end
27
+
28
+ if __FILE__ == $0
29
+ InteractiveCmd.start
30
+ end
@@ -34,6 +34,15 @@ module CommandKit
34
34
  # #
35
35
  # # => "Lime"
36
36
  #
37
+ # ### Prompt for multi-line input
38
+ #
39
+ # ask_multiline('Comment')
40
+ # # Comment (Press Ctrl^D to exit):
41
+ # # foo bar
42
+ # # baz qux
43
+ # # Ctrl^D
44
+ # # => "foo bar\nbaz qux\n"
45
+ #
37
46
  module Interactive
38
47
  include Stdio
39
48
 
@@ -244,5 +253,83 @@ module CommandKit
244
253
  end
245
254
  end
246
255
 
256
+ #
257
+ # Asks the user for multi-line text input.
258
+ #
259
+ # @param [String] prompt
260
+ # The prompt that will be printed before reading input.
261
+ #
262
+ # @param [String, nil] help
263
+ # Optional help instructions on how to exit from reading.
264
+ #
265
+ # @param [String, nil] default
266
+ # The default value to return if no input is given.
267
+ #
268
+ # @param [Boolean] required
269
+ # Requires non-empty input.
270
+ #
271
+ # @param [:double_newline, :ctrl_d] terminator
272
+ # Indicates how the input should be terminated.
273
+ # Defaults to `:ctrl_d` which indicates `Ctrl^D`.
274
+ #
275
+ # @return [String]
276
+ # The user input.
277
+ #
278
+ # @example
279
+ # ask_multiline('Comment')
280
+ # # Comment (Press Ctrl^D to exit):
281
+ # # foo bar
282
+ # # baz qux
283
+ # # Ctrl^D
284
+ # # => "foo bar\nbaz qux\n"
285
+ #
286
+ # @example Terminate input on a double newline:
287
+ # ask_multiline('Comment', terminator: :double_newline)
288
+ # # Comment (Enter two empty lines to exit):
289
+ # # foo bar
290
+ # # baz qux
291
+ # #
292
+ # # => "foo bar\nbaz qux\n"
293
+ #
294
+ # @api public
295
+ #
296
+ # @since 0.6.0
297
+ #
298
+ def ask_multiline(prompt, help: nil,
299
+ default: nil,
300
+ required: false,
301
+ terminator: :ctrl_d)
302
+ case terminator
303
+ when :ctrl_d
304
+ eos = nil
305
+ help ||= 'Press Ctrl^D to exit'
306
+ when :double_newline
307
+ eos = "#{$/}#{$/}"
308
+ help ||= 'Press Enter twice to exit'
309
+ else
310
+ raise(ArgumentError,"invalid terminator: #{terminator.inspect}")
311
+ end
312
+
313
+ prompt = "#{prompt.chomp} (#{help})"
314
+ prompt << " [#{default}]" if default
315
+ prompt << ": "
316
+
317
+ loop do
318
+ stdout.puts(prompt)
319
+
320
+ value = stdin.gets(eos)
321
+ value ||= '' # convert nil values (ctrl^D) to an empty String
322
+
323
+ if value.empty?
324
+ if required
325
+ next
326
+ else
327
+ return (default || value)
328
+ end
329
+ else
330
+ return value
331
+ end
332
+ end
333
+ end
247
334
  end
248
335
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'stdio'
4
+ require_relative 'printing'
5
+
6
+ module CommandKit
7
+ #
8
+ # Adds helper methods for opening files.
9
+ #
10
+ # ## Features
11
+ #
12
+ # * Prints `No such file or directory` error if the given file does not exist.
13
+ # * Handles `-` file paths which indicate input should be read from STDIN or
14
+ # output written to STDOUT.
15
+ #
16
+ # ## Examples
17
+ #
18
+ # include CommandKit::Open
19
+ #
20
+ # def run(path)
21
+ # open(path) do |file|
22
+ # # ...
23
+ # end
24
+ # end
25
+ #
26
+ # @since 0.6.0
27
+ #
28
+ module Open
29
+ include Stdio
30
+ include Printing
31
+
32
+ #
33
+ # Opens a file for reading or writing.
34
+ #
35
+ # @param [String] path
36
+ # The path of the given file. May be `"-"` to indicate that input should
37
+ # be read from STDINT or output written to STDOUT.
38
+ #
39
+ # @param [String] mode
40
+ # The mode to open the file with.
41
+ #
42
+ # @yield [file]
43
+ # * If the given path is `"-"`.
44
+ # * and the given mode contains `w` or `a`, then {#stdout} will be
45
+ # yielded.
46
+ # * and no mode is given or if the mode contains `r`, then {#stdin} will
47
+ # be yielded.
48
+ # * Otherwise, the newly opened file.
49
+ #
50
+ # @yieldparam [File, IO] file
51
+ # The newly opened file, or {#stdin} / {#stdout} if the given path is
52
+ # `"-"`.
53
+ #
54
+ # @return [File, IO, Object]
55
+ # * If no block is given, the newly opened file, or {#stdin} / {#stdout}
56
+ # if the given path is `"-"`, will be returned.
57
+ # * If a block was given, then the return value of the block will be
58
+ # returned.
59
+ #
60
+ # @example Opening a file for reading:
61
+ # open(path)
62
+ # # => #<File:...>
63
+ #
64
+ # @example Temporarily opening a file for reading:
65
+ # open(path) do |file|
66
+ # # ...
67
+ # end
68
+ #
69
+ # @example Opening a file for writing:
70
+ # open(path,'w')
71
+ # # => #<File:...>
72
+ #
73
+ # @example Temporarily opening a file for writing:
74
+ # open(path,'w') do |output|
75
+ # output
76
+ # end
77
+ #
78
+ # @api public
79
+ #
80
+ # @since 0.6.0
81
+ #
82
+ def open(path,mode='r',&block)
83
+ if path == '-'
84
+ io = case mode
85
+ when /[wa]/ then stdout
86
+ else stdin
87
+ end
88
+
89
+ if block_given?
90
+ return yield(io)
91
+ else
92
+ return io
93
+ end
94
+ end
95
+
96
+ begin
97
+ File.open(path,mode,&block)
98
+ rescue Errno::ENOENT
99
+ print_error "No such file or directory: #{path}"
100
+ exit(1)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../options'
4
+
5
+ module CommandKit
6
+ module Options
7
+ #
8
+ # Defines a `-v`,`--verbose` option that can be specified multiple times to
9
+ # increase the verbosity level.
10
+ #
11
+ # ## Examples
12
+ #
13
+ # include CommandKit::Options::VerboseLevel
14
+ #
15
+ # def run(*argv)
16
+ # # ...
17
+ # case verbose
18
+ # when 1
19
+ # puts "verbose output"
20
+ # when 2
21
+ # puts " extra verbose output"
22
+ # end
23
+ # # ...
24
+ # end
25
+ #
26
+ # @since 0.6.0
27
+ #
28
+ module VerboseLevel
29
+ include Options
30
+
31
+ #
32
+ # @api private
33
+ #
34
+ module ModuleMethods
35
+ #
36
+ # Defines a `-v, --verbose` option or extends {ModuleMethods}, depending
37
+ # on whether {Options::Verbose} is being included into a class or a
38
+ # module.
39
+ #
40
+ # @param [Class, Module] context
41
+ # The class or module including {Verbose}.
42
+ #
43
+ def included(context)
44
+ super(context)
45
+
46
+ if context.class == Module
47
+ context.extend ModuleMethods
48
+ else
49
+ context.option :verbose, short: '-v', desc: 'Increases the verbosity level' do
50
+ @verbose += 1
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ extend ModuleMethods
57
+
58
+ # The verbosity level.
59
+ #
60
+ # @return [Integer]
61
+ attr_reader :verbose
62
+
63
+ #
64
+ # Initializes the command and sets {#verbose} to 0.
65
+ #
66
+ # @param [Hash{Symbol => Object}] kwargs
67
+ # Additional keyword arguments.
68
+ #
69
+ def initialize(**kwargs)
70
+ super(**kwargs)
71
+
72
+ @verbose = 0
73
+ end
74
+
75
+ #
76
+ # Determines if verbose mode is enabled.
77
+ #
78
+ # @return [Boolean]
79
+ #
80
+ # @api public
81
+ #
82
+ def verbose?
83
+ @verbose > 0
84
+ end
85
+ end
86
+ end
87
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module CommandKit
4
4
  # command_kit version
5
- VERSION = "0.5.6"
5
+ VERSION = "0.6.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
@@ -48,6 +48,7 @@ files:
48
48
  - command_kit.gemspec
49
49
  - examples/colors.rb
50
50
  - examples/command.rb
51
+ - examples/interactive.rb
51
52
  - examples/pager.rb
52
53
  - examples/printing/tables.rb
53
54
  - examples/subcommands/cli.rb
@@ -90,6 +91,7 @@ files:
90
91
  - lib/command_kit/interactive.rb
91
92
  - lib/command_kit/main.rb
92
93
  - lib/command_kit/man.rb
94
+ - lib/command_kit/open.rb
93
95
  - lib/command_kit/open_app.rb
94
96
  - lib/command_kit/options.rb
95
97
  - lib/command_kit/options/option.rb
@@ -97,6 +99,7 @@ files:
97
99
  - lib/command_kit/options/parser.rb
98
100
  - lib/command_kit/options/quiet.rb
99
101
  - lib/command_kit/options/verbose.rb
102
+ - lib/command_kit/options/verbose_level.rb
100
103
  - lib/command_kit/options/version.rb
101
104
  - lib/command_kit/os.rb
102
105
  - lib/command_kit/os/linux.rb