mini-cli 0.5.1 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 299da5a35fccbc561453ee2dc9584f7aec510b1fe9dd34e8c7ae3221b6253dbb
4
- data.tar.gz: 242f37afb8733342cafd7694d73de4247f2887a027cb4f33da210eff1dc81380
3
+ metadata.gz: 287658b0aa4ac5340cde3aced9e0a411ed6504713c18505706ad741c7c966a8b
4
+ data.tar.gz: 7b6c95ddc87554a011c3f28355f3e181a7be249432d906861a92092978f5b22b
5
5
  SHA512:
6
- metadata.gz: da79647fb91708e556151c22296aa0febe509c9502bbbe327e6fb10cfd3cc22b851f402cede01e25d1df6b9e42382200cc7d34c28f8dab7fc1fac9984dda6d47
7
- data.tar.gz: bb7bfb271ea6cbb2e30e4a0833746a30869e484ddc4e7d13c6f1c5f44acdca10d29081f0b52fe9c045685974d6ef6c188ce0e6147cd57f331deb020d74abeacb
6
+ metadata.gz: 2fa1fb33a71928b5fea02349709ba6191992b5375b690a8b39fe8dcb8b932932abe61f02135ca747bf729c0ed758276f7d9b3f41f42a2db1f128ee56eeda1bcb
7
+ data.tar.gz: fb7397ede3cf0f0265dbafd47ef4e070153a37e3afdf5a583b68ea95dd4482e7c54522af941bdba45680ab195e0b305b286bac1c241e27b741162bb28822fcb2
data/lib/mini-cli/run.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require('shellwords')
4
+
3
5
  module MiniCli
4
6
  def run(*cmd, stdin_data: nil, status: false, chdir: nil)
5
7
  in_read, in_write = IO.pipe
@@ -15,8 +17,7 @@ module MiniCli
15
17
  end
16
18
 
17
19
  def run_ruby(*cmd, **run_options)
18
- require 'shellwords'
19
- run(Shellwords.join(RUBY_CMD_ + cmd), **run_options)
20
+ run(Shellwords.join(__ruby_cmd + cmd), **run_options)
20
21
  end
21
22
 
22
23
  def run_script(script, status: false, chdir: nil)
@@ -39,10 +40,12 @@ module MiniCli
39
40
  end
40
41
  end
41
42
 
42
- RUBY_CMD_ =
43
- %w[--disable gems --disable did_you_mean --disable rubyopt].unshift(
44
- RbConfig.ruby
45
- ).freeze
46
-
47
- private_constant(:RUBY_CMD_)
43
+ def __ruby_cmd
44
+ [
45
+ RbConfig.ruby,
46
+ '--disable=gems',
47
+ '--disable=did_you_mean',
48
+ '--disable=rubyopt'
49
+ ]
50
+ end
48
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniCli
4
- VERSION = '0.5.1'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/mini-cli.rb CHANGED
@@ -75,20 +75,22 @@ module MiniCli
75
75
  def initialize(source)
76
76
  @source = source
77
77
  @name = File.basename(source, '.*')
78
- @parser = @converter = @main_proc = nil
79
- @before, @after = [], []
78
+ @converter = @main_proc = nil
79
+ @parser = ArgvParser.new('', [])
80
+ @before = []
81
+ @after = []
80
82
  @show_errors = true
81
83
  @before_ok = false
82
84
  @error_code = 0
83
85
  init_main
84
86
  end
85
87
 
86
- def name(name = nil)
88
+ def name(name)
87
89
  name ? @name = name.to_s : @name
88
90
  end
89
91
 
90
- def help(helptext, args)
91
- @parser = ArgvParser.new(helptext, args)
92
+ def help(*args)
93
+ @parser = ArgvParser.new(*args)
92
94
  end
93
95
 
94
96
  def show_help
@@ -109,6 +111,8 @@ module MiniCli
109
111
 
110
112
  private
111
113
 
114
+ attr_reader :parser
115
+
112
116
  def init_main
113
117
  at_exit do
114
118
  next if $! and not ($!.kind_of?(SystemExit) and $!.success?)
@@ -125,25 +129,22 @@ module MiniCli
125
129
  end
126
130
  end
127
131
 
128
- def parser
129
- @parser ||= ArgvParser.new(nil, [])
130
- end
131
-
132
132
  class ArgvParser
133
133
  def initialize(helptext, args)
134
134
  @helptext = helptext.to_s
135
135
  @args = args.flatten.map!(&:to_s).uniq
136
136
  @options = nil
137
+ @show_options_text = true
137
138
  end
138
139
 
139
140
  def show_help(name)
140
141
  parse_help! unless @options
141
142
  print("Usage: #{name}")
142
- print(' [OPTIONS]') unless @options.empty?
143
+ print(' [<options>]') unless @options.empty?
143
144
  print(' ', @args.join(' ')) unless @args.empty?
144
145
  puts
145
- puts(nil, 'Options:') unless @options.empty?
146
- puts(@helptext) unless @helptext.empty?
146
+ puts(nil, 'Options:') if @show_options_text
147
+ puts(@helptext.gsub('<*name*>', name)) unless @helptext.empty?
147
148
  end
148
149
 
149
150
  def parse(argv, error)
@@ -154,6 +155,10 @@ module MiniCli
154
155
 
155
156
  private
156
157
 
158
+ def error(msg)
159
+ @error[1, msg]
160
+ end
161
+
157
162
  def parse_argv(argv)
158
163
  arguments = []
159
164
  while (arg = argv.shift)
@@ -171,10 +176,6 @@ module MiniCli
171
176
  arguments
172
177
  end
173
178
 
174
- def error(msg)
175
- @error[1, msg]
176
- end
177
-
178
179
  def process(arguments)
179
180
  @args.each do |arg|
180
181
  process_arg(arg, arguments.shift) unless arg.index('..')
@@ -185,33 +186,38 @@ module MiniCli
185
186
  end
186
187
 
187
188
  def process_arg(arg, value)
188
- if arg.start_with?('[')
189
- @result[arg[1..-2]] = value if value
189
+ if arg[0] == '[' && arg[-1] == ']'
190
+ return unless value
191
+ arg = arg[1..-2]
190
192
  else
191
- @result[arg] = value || error("parameter expected - #{arg}")
193
+ error("parameter expected - #{arg}") unless value
192
194
  end
195
+ @result[(arg[0] == '<' && arg[-1] == '>') ? arg[1..-2] : arg] = value
193
196
  end
194
197
 
195
- def handle_option(option, argv, test = ->(k) { option == k })
196
- key = @options[option] || error("unknown option - #{option}")
197
- @result[key] = test[key] and return
198
+ def handle_option(option, argv, pref = '-')
199
+ key = @options[option] || error("unknown option - #{pref}-#{option}")
200
+ return @result[key[1..-1]] = true if key[0] == '!'
198
201
  @result[key] = value = argv.shift
199
- return unless value.nil? || value.start_with?('-')
200
- error("parameter #{key} expected - --#{option}")
202
+ return unless value.nil? || value[0] == '-'
203
+ error("parameter <#{key}> expected - #{pref}-#{option}")
201
204
  end
202
205
 
203
206
  def parse_options(options, argv)
204
- test = ->(k) { k == k.downcase }
205
- options.each_char { |opt| handle_option(opt, argv, test) }
207
+ options.each_char { |opt| handle_option(opt, argv, nil) }
206
208
  end
207
209
 
208
210
  def parse_help!
209
211
  @options = {}
210
212
  @helptext.each_line do |line|
211
213
  case line
212
- when /-([[:alnum:]]), --([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/
214
+ when /Options:$/
215
+ @show_options_text = false
216
+ when /-([[:alnum:]]), --([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/,
217
+ /-([[:alnum:]]), --([[[:alnum:]]-]+) \<([[:lower:]]+)\>\s+\S+/
213
218
  option_with_argument(Regexp.last_match)
214
- when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/
219
+ when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/,
220
+ /--([[[:alnum:]]-]+) \<([[:lower:]]+)\>\s+\S+/
215
221
  short_option_with_argument(Regexp.last_match)
216
222
  when /-([[:alnum:]]), --([[[:alnum:]]-]+)\s+\S+/
217
223
  option(Regexp.last_match)
@@ -219,6 +225,7 @@ module MiniCli
219
225
  short_option(Regexp.last_match)
220
226
  end
221
227
  end
228
+ @show_options_text &= !@options.empty?
222
229
  end
223
230
 
224
231
  def option_with_argument(match)
@@ -230,11 +237,11 @@ module MiniCli
230
237
  end
231
238
 
232
239
  def option(match)
233
- @options[match[1]] = @options[match[2]] = match[2]
240
+ @options[match[1]] = @options[match[2]] = "!#{match[2]}"
234
241
  end
235
242
 
236
243
  def short_option(match)
237
- @options[match[1]] = match[1]
244
+ @options[match[1]] = "!#{match[1]}"
238
245
  end
239
246
  end
240
247
  end
@@ -4,28 +4,34 @@ require_relative '../lib/mini-cli'
4
4
 
5
5
  include MiniCli
6
6
 
7
- help <<~HELP, %w[TARGET [SOURCE]]
8
- -n, --name NAME option requires NAME argument, has shortcut
9
- --url URL option requires URL argument
10
- -s, --switch option without any argument, has shortcut
11
- --opt option without any argument
7
+ help <<~HELP, %w[<target> [<source>]]
8
+
9
+ Demonstration of converting arguments to a custom argument class.
10
+
11
+ Options:
12
+ -n, --name <name> option requires <name> argument, has shortcut
13
+ --url <url> option requires <url> argument
14
+ -s, --switch option without any argument, has shortcut
15
+ --opt option without any argument
12
16
  HELP
13
17
 
14
18
  main { |cfg| cfg.each_pair { |key, value| puts("#{key}: #{value}") } }
15
19
 
16
20
  parse_argv do |args|
21
+ # args['FILES'] is an array containing all surplus arguments
17
22
  Struct
18
23
  .new(:target, :sources, :name, :url, :switch, :opt)
19
- .new
24
+ .new(
25
+ args['target'],
26
+ args['FILES'],
27
+ args['name'] || 'default_name',
28
+ args['url'] || 'www.url.test',
29
+ args.key?('switch'),
30
+ args.key?('opt')
31
+ )
20
32
  .tap do |cfg|
21
- cfg.target = args['TARGET']
22
- cfg.sources = args['FILES'] # args['FILES'] is an array containing all surplus arguments
23
- source = args['SOURCE'] || ENV['SOURCE']
33
+ source = args['source'] || ENV['SOURCE']
24
34
  cfg.sources.unshift(source) if source
25
35
  cfg.sources << 'STDIN' if cfg.sources.empty?
26
- cfg.name = args['NAME'] || 'default_name'
27
- cfg.url = args['URL'] || 'www.url.test'
28
- cfg.switch = args.key?('switch')
29
- cfg.opt = args.key?('opt')
30
36
  end
31
37
  end
data/samples/demo.rb CHANGED
@@ -4,18 +4,24 @@ require_relative '../lib/mini-cli'
4
4
 
5
5
  include MiniCli
6
6
 
7
- help <<~HELP, %w[TARGET [SOURCE]]
8
- -n, --name NAME option requires NAME argument, has shortcut
9
- --url URL option requires URL argument
10
- -s, --switch option without any argument, has shortcut
11
- --opt option without any argument
7
+ help <<~HELP, %w[<target> [<source>]]
8
+
9
+ Demonstration of general Mini-CLI behavior.
10
+
11
+ Options:
12
+ -n, --name <name> option requires <name> argument, has shortcut
13
+ --url <url> option requires <url> argument
14
+ -s, --switch option without any argument, has shortcut
15
+ --opt option without any argument
16
+
17
+ Try to call this <*name*> command with various options and arguments.
12
18
  HELP
13
19
 
14
20
  main do |args|
15
- puts("TARGET: #{args['TARGET']}")
16
- puts("SOURCE: #{args['SOURCE']}") if args.key?('SOURCE')
17
- puts("NAME: #{args['NAME']}") if args.key?('NAME')
18
- puts("URL: #{args['URL']}") if args.key?('URL')
21
+ puts("target: #{args['target']}")
22
+ puts("source: #{args['source']}") if args.key?('source')
23
+ puts("name: #{args['name']}") if args.key?('name')
24
+ puts("url: #{args['url']}") if args.key?('url')
19
25
  puts("FILES: #{args['FILES']}") unless args['FILES'].empty?
20
26
  puts('--switch was given') if args.key?('switch')
21
27
  puts('--opt was given') if args.key?('opt')
@@ -27,7 +27,7 @@ class ExecTest < Minitest::Test
27
27
 
28
28
  def test_sequence_help
29
29
  expected = [
30
- 'Usage: sequence [OPTIONS]',
30
+ 'Usage: sequence [<options>]',
31
31
  '',
32
32
  'Options:',
33
33
  '-x, --exit early exit',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-04 00:00:00.000000000 Z
11
+ date: 2021-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  requirements: []
104
- rubygems_version: 3.2.15
104
+ rubygems_version: 3.2.28
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: The lean CLI framework for Ruby