mini-cli 0.3.0 → 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: 6954edd798ee19570124490d3c139443e54cf9db86da1cbf5e1ecf053f5b4de6
4
- data.tar.gz: e9c458ab08eb813875df22053ce3c5fd99c651bbe24f60d787a6d0968936d204
3
+ metadata.gz: 287658b0aa4ac5340cde3aced9e0a411ed6504713c18505706ad741c7c966a8b
4
+ data.tar.gz: 7b6c95ddc87554a011c3f28355f3e181a7be249432d906861a92092978f5b22b
5
5
  SHA512:
6
- metadata.gz: ad9884fa0f18600b69212a8f3b3c36108838d510879cde3d2a4525009439a3574c8eae1d7d7d4b567647fce04aa5cfaeee3fdceec8529381defc2533c1166559
7
- data.tar.gz: 287198992331abcd2fee44165775cad3a6905c15eb1fac71bee380d706ba5f2067b3b2d3498f9a7bc4f07fe92c447e417c854313b247f0b81db304f0810a582b
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
@@ -14,6 +16,14 @@ module MiniCli
14
16
  in_write&.close
15
17
  end
16
18
 
19
+ def run_ruby(*cmd, **run_options)
20
+ run(Shellwords.join(__ruby_cmd + cmd), **run_options)
21
+ end
22
+
23
+ def run_script(script, status: false, chdir: nil)
24
+ run_ruby(stdin_data: script, status: status, chdir: chdir)
25
+ end
26
+
17
27
  private
18
28
 
19
29
  def __run_proc(stdin_data, in_write)
@@ -29,4 +39,13 @@ module MiniCli
29
39
  out.read
30
40
  end
31
41
  end
42
+
43
+ def __ruby_cmd
44
+ [
45
+ RbConfig.ruby,
46
+ '--disable=gems',
47
+ '--disable=did_you_mean',
48
+ '--disable=rubyopt'
49
+ ]
50
+ end
32
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniCli
4
- VERSION = '0.3.0'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/mini-cli.rb CHANGED
@@ -2,8 +2,11 @@
2
2
 
3
3
  module MiniCli
4
4
  def self.included(mod)
5
- source = caller_locations(1, 1).first.absolute_path
6
- mod.const_set(:MiniCli__, Instance.new(source))
5
+ mod.const_set(
6
+ :MiniCli__,
7
+ Instance.new(caller_locations(1, 1).first.absolute_path)
8
+ )
9
+ mod.private_constant(:MiniCli__)
7
10
  end
8
11
 
9
12
  def name(name = nil)
@@ -26,50 +29,68 @@ module MiniCli
26
29
  __minicli__.show_errors = value ? true : false
27
30
  end
28
31
 
32
+ def error_code
33
+ __minicli__.error_code
34
+ end
35
+
29
36
  def error(code, message = nil)
30
37
  $stderr.puts("#{name}: #{message}") if message && show_errors?
31
- exit(code)
38
+ exit(__minicli__.error_code = code)
32
39
  end
33
40
 
34
41
  def parse_argv(argv = nil, &argv_converter)
35
42
  return __minicli__.converter = argv_converter if argv_converter
36
- argv ||= ARGV.dup
43
+ argv = Array.new(argv || ARGV)
37
44
  exit(show_help) if argv.index('--help') || argv.index('-h')
38
- __minicli__.convert(__minicli__.parse(argv, method(:error).to_proc))
45
+ __minicli__.main(argv, method(:error).to_proc)
39
46
  end
40
47
 
41
- def main(args = nil)
42
- at_exit do
43
- yield(args || parse_argv)
48
+ def main
49
+ __minicli__.run do
50
+ yield(parse_argv)
44
51
  rescue Interrupt
45
52
  error(130, 'aborted')
46
53
  end
47
54
  end
48
55
 
56
+ def before(&callback)
57
+ callback and __minicli__.before << callback
58
+ end
59
+
60
+ def after(&callback)
61
+ callback and __minicli__.after << callback
62
+ end
63
+
49
64
  private
50
65
 
51
66
  def __minicli__
52
- self.class::MiniCli__
67
+ self.class.const_get(:MiniCli__)
53
68
  end
54
69
 
55
70
  class Instance
56
71
  attr_reader :source
57
72
  attr_writer :converter
58
- attr_accessor :show_errors
73
+ attr_accessor :show_errors, :before, :after, :error_code
59
74
 
60
75
  def initialize(source)
61
76
  @source = source
62
77
  @name = File.basename(source, '.*')
63
- @parser = @converter = nil
78
+ @converter = @main_proc = nil
79
+ @parser = ArgvParser.new('', [])
80
+ @before = []
81
+ @after = []
64
82
  @show_errors = true
83
+ @before_ok = false
84
+ @error_code = 0
85
+ init_main
65
86
  end
66
87
 
67
- def name(name = nil)
88
+ def name(name)
68
89
  name ? @name = name.to_s : @name
69
90
  end
70
91
 
71
- def help(helptext, args)
72
- @parser = ArgvParser.new(helptext, args)
92
+ def help(*args)
93
+ @parser = ArgvParser.new(*args)
73
94
  end
74
95
 
75
96
  def show_help
@@ -77,18 +98,35 @@ module MiniCli
77
98
  true
78
99
  end
79
100
 
80
- def parse(argv, error)
81
- parser.parse(argv, error)
101
+ def run(&main_proc)
102
+ @main_proc = main_proc
82
103
  end
83
104
 
84
- def convert(args)
105
+ def main(argv, error)
106
+ @before.each(&:call)
107
+ @before_ok = true
108
+ args = parser.parse(argv, error)
85
109
  @converter ? @converter.call(args) || args : args
86
110
  end
87
111
 
88
112
  private
89
113
 
90
- def parser
91
- @parser ||= ArgvParser.new(nil, [])
114
+ attr_reader :parser
115
+
116
+ def init_main
117
+ at_exit do
118
+ next if $! and not ($!.kind_of?(SystemExit) and $!.success?)
119
+ shutdown unless @after.empty?
120
+ @main_proc&.call
121
+ end
122
+ end
123
+
124
+ def shutdown(pid = Process.pid)
125
+ at_exit do
126
+ next if Process.pid != pid
127
+ @after.reverse_each(&:call) if @before_ok
128
+ exit(@error_code)
129
+ end
92
130
  end
93
131
 
94
132
  class ArgvParser
@@ -96,16 +134,17 @@ module MiniCli
96
134
  @helptext = helptext.to_s
97
135
  @args = args.flatten.map!(&:to_s).uniq
98
136
  @options = nil
137
+ @show_options_text = true
99
138
  end
100
139
 
101
140
  def show_help(name)
102
141
  parse_help! unless @options
103
142
  print("Usage: #{name}")
104
- print(' [OPTIONS]') unless @options.empty?
143
+ print(' [<options>]') unless @options.empty?
105
144
  print(' ', @args.join(' ')) unless @args.empty?
106
145
  puts
107
- puts(nil, 'Options:') unless @options.empty?
108
- puts(@helptext) unless @helptext.empty?
146
+ puts(nil, 'Options:') if @show_options_text
147
+ puts(@helptext.gsub('<*name*>', name)) unless @helptext.empty?
109
148
  end
110
149
 
111
150
  def parse(argv, error)
@@ -116,13 +155,16 @@ module MiniCli
116
155
 
117
156
  private
118
157
 
158
+ def error(msg)
159
+ @error[1, msg]
160
+ end
161
+
119
162
  def parse_argv(argv)
120
163
  arguments = []
121
164
  while (arg = argv.shift)
122
165
  case arg
123
166
  when '--'
124
- arguments += argv
125
- break
167
+ break arguments += argv
126
168
  when /\A--([[[:alnum:]]-]+)\z/
127
169
  handle_option(Regexp.last_match[1], argv)
128
170
  when /\A-([[:alnum:]]+)\z/
@@ -134,10 +176,6 @@ module MiniCli
134
176
  arguments
135
177
  end
136
178
 
137
- def error(msg)
138
- @error[1, msg]
139
- end
140
-
141
179
  def process(arguments)
142
180
  @args.each do |arg|
143
181
  process_arg(arg, arguments.shift) unless arg.index('..')
@@ -148,33 +186,38 @@ module MiniCli
148
186
  end
149
187
 
150
188
  def process_arg(arg, value)
151
- if arg.start_with?('[')
152
- @result[arg[1..-2]] = value if value
189
+ if arg[0] == '[' && arg[-1] == ']'
190
+ return unless value
191
+ arg = arg[1..-2]
153
192
  else
154
- @result[arg] = value || error("parameter expected - #{arg}")
193
+ error("parameter expected - #{arg}") unless value
155
194
  end
195
+ @result[(arg[0] == '<' && arg[-1] == '>') ? arg[1..-2] : arg] = value
156
196
  end
157
197
 
158
- def handle_option(option, argv, test = ->(k) { option == k })
159
- key = @options[option] || error("unknown option - #{option}")
160
- @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] == '!'
161
201
  @result[key] = value = argv.shift
162
- return unless value.nil? || value.start_with?('-')
163
- error("parameter #{key} expected - --#{option}")
202
+ return unless value.nil? || value[0] == '-'
203
+ error("parameter <#{key}> expected - #{pref}-#{option}")
164
204
  end
165
205
 
166
206
  def parse_options(options, argv)
167
- test = ->(k) { k == k.downcase }
168
- options.each_char { |opt| handle_option(opt, argv, test) }
207
+ options.each_char { |opt| handle_option(opt, argv, nil) }
169
208
  end
170
209
 
171
210
  def parse_help!
172
211
  @options = {}
173
212
  @helptext.each_line do |line|
174
213
  case line
175
- 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+/
176
218
  option_with_argument(Regexp.last_match)
177
- when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/
219
+ when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/,
220
+ /--([[[:alnum:]]-]+) \<([[:lower:]]+)\>\s+\S+/
178
221
  short_option_with_argument(Regexp.last_match)
179
222
  when /-([[:alnum:]]), --([[[:alnum:]]-]+)\s+\S+/
180
223
  option(Regexp.last_match)
@@ -182,6 +225,7 @@ module MiniCli
182
225
  short_option(Regexp.last_match)
183
226
  end
184
227
  end
228
+ @show_options_text &= !@options.empty?
185
229
  end
186
230
 
187
231
  def option_with_argument(match)
@@ -193,11 +237,11 @@ module MiniCli
193
237
  end
194
238
 
195
239
  def option(match)
196
- @options[match[1]] = @options[match[2]] = match[2]
240
+ @options[match[1]] = @options[match[2]] = "!#{match[2]}"
197
241
  end
198
242
 
199
243
  def short_option(match)
200
- @options[match[1]] = match[1]
244
+ @options[match[1]] = "!#{match[1]}"
201
245
  end
202
246
  end
203
247
  end
data/mini-cli.gemspec CHANGED
@@ -2,30 +2,30 @@
2
2
 
3
3
  require_relative './lib/mini-cli/version'
4
4
 
5
- GemSpec = Gem::Specification.new do |gem|
6
- gem.name = 'mini-cli'
7
- gem.version = MiniCli::VERSION
8
- gem.summary = 'The lean CLI framework for Ruby'
9
- gem.description = <<~DESC
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mini-cli'
7
+ spec.version = MiniCli::VERSION
8
+ spec.required_ruby_version = '>= 2.5.0'
9
+
10
+ spec.summary = 'The lean CLI framework for Ruby'
11
+ spec.description = <<~DESC
10
12
  This gem is a lean, easy to use CLI framework with a very small footprint.
11
13
  It provides an easy to use argument parsing, help displaying and
12
14
  minimalistic error handling.
13
15
  DESC
14
- gem.author = 'Mike Blumtritt'
15
- gem.homepage = 'https://github.com/mblumtritt/mini-cli'
16
- gem.metadata = {
17
- 'source_code_uri' => 'https://github.com/mblumtritt/mini-cli',
18
- 'bug_tracker_uri' => 'https://github.com/mblumtritt/mini-cli/issues'
19
- }
20
16
 
21
- gem.required_ruby_version = '>= 2.5.0'
17
+ spec.author = 'Mike Blumtritt'
18
+ spec.homepage = 'https://github.com/mblumtritt/mini-cli'
19
+ spec.metadata['source_code_uri'] = 'https://github.com/mblumtritt/mini-cli'
20
+ spec.metadata['bug_tracker_uri'] =
21
+ 'https://github.com/mblumtritt/mini-cli/issues'
22
22
 
23
- gem.add_development_dependency 'bundler'
24
- gem.add_development_dependency 'minitest'
25
- gem.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'minitest'
25
+ spec.add_development_dependency 'rake'
26
26
 
27
- all_files = %x(git ls-files -z).split(0.chr)
28
- gem.test_files = all_files.grep(%r{^(spec|test)/})
29
- gem.files = all_files - gem.test_files
30
- gem.extra_rdoc_files = %w[README.md]
27
+ all_files = Dir.chdir(__dir__) { `git ls-files -z`.split(0.chr) }
28
+ spec.test_files = all_files.grep(%r{^(spec|test)/})
29
+ spec.files = all_files - spec.test_files
30
+ spec.extra_rdoc_files = %w[README.md]
31
31
  end
data/rakefile.rb CHANGED
@@ -3,13 +3,11 @@
3
3
  require 'rake/testtask'
4
4
  require 'bundler/gem_tasks'
5
5
 
6
- STDOUT.sync = STDERR.sync = true
6
+ $stdout.sync = $stderr.sync = true
7
7
 
8
- CLOBBER << 'prj'
8
+ task(:default) { exec('rake --tasks') }
9
9
 
10
- task :default do
11
- exec "#{$PROGRAM_NAME} --tasks"
12
- end
10
+ CLOBBER << 'prj'
13
11
 
14
12
  Rake::TestTask.new(:test) do |t|
15
13
  t.ruby_opts = %w[-w]
@@ -4,25 +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|
17
- Struct.new(:target, :sources, :name, :url, :switch, :opt).new.tap do |cfg|
18
- cfg.target = args['TARGET']
19
- cfg.sources = args['FILES'] # args['FILES'] is an array containing all surplus arguments
20
- source = args['SOURCE'] || ENV['SOURCE']
21
- cfg.sources.unshift(source) if source
22
- cfg.sources << 'STDIN' if cfg.sources.empty?
23
- cfg.name = args['NAME'] || 'default_name'
24
- cfg.url = args['URL'] || 'www.url.test'
25
- cfg.switch = args.key?('switch')
26
- cfg.opt = args.key?('opt')
27
- end
21
+ # args['FILES'] is an array containing all surplus arguments
22
+ Struct
23
+ .new(:target, :sources, :name, :url, :switch, :opt)
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
+ )
32
+ .tap do |cfg|
33
+ source = args['source'] || ENV['SOURCE']
34
+ cfg.sources.unshift(source) if source
35
+ cfg.sources << 'STDIN' if cfg.sources.empty?
36
+ end
28
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')
data/test/apps/noop.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # completely empty command
3
+
4
+ require_relative '../../lib/mini-cli'
5
+ include(MiniCli)
6
+ main {}
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # demonstrates the call sequence
3
+
4
+ require_relative '../../lib/mini-cli'
5
+ include(MiniCli)
6
+
7
+ help <<~HELP
8
+ -x, --exit early exit
9
+ -e, --error exit with error
10
+ HELP
11
+
12
+ main do |*args|
13
+ puts('main' + args.inspect)
14
+ exit if args.first['exit']
15
+ error(42, '!error!') if args.first['error']
16
+ end
17
+
18
+ before { |*args| puts('before_1' + args.inspect) }
19
+ after { |*args| puts('after_1' + args.inspect) }
20
+ before { |*args| puts('before_2' + args.inspect) }
21
+ after { |*args| puts('after_2' + args.inspect) }
22
+
23
+ parse_argv do |*args|
24
+ puts('parse_argv' + args.inspect)
25
+ args.first
26
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'shellwords'
5
+ require_relative '../helper'
6
+
7
+ class ExecTest < Minitest::Test
8
+ def test_noop
9
+ assert_empty(assert_no_err('noop.rb'))
10
+ end
11
+
12
+ def test_noop_help
13
+ assert_equal("Usage: noop\n", assert_no_err('noop.rb', '--help'))
14
+ end
15
+
16
+ def test_sequence
17
+ expected = [
18
+ 'before_1[]',
19
+ 'before_2[]',
20
+ "parse_argv[{\"FILES\"=>[]}]",
21
+ "main[{\"FILES\"=>[]}]",
22
+ 'after_2[]',
23
+ 'after_1[]'
24
+ ]
25
+ assert_equal(expected, assert_no_err('sequence.rb').split("\n"))
26
+ end
27
+
28
+ def test_sequence_help
29
+ expected = [
30
+ 'Usage: sequence [<options>]',
31
+ '',
32
+ 'Options:',
33
+ '-x, --exit early exit',
34
+ '-e, --error exit with error'
35
+ ]
36
+ assert_equal(expected, assert_no_err('sequence.rb', '--help').split("\n"))
37
+ end
38
+
39
+ def test_sequence_early_exit
40
+ expected = [
41
+ 'before_1[]',
42
+ 'before_2[]',
43
+ "parse_argv[{\"exit\"=>true, \"FILES\"=>[]}]",
44
+ "main[{\"exit\"=>true, \"FILES\"=>[]}]",
45
+ 'after_2[]',
46
+ 'after_1[]'
47
+ ]
48
+ assert_equal(expected, assert_no_err('sequence.rb', '-x').split("\n"))
49
+ end
50
+
51
+ def test_sequence_error
52
+ expected = [
53
+ 'before_1[]',
54
+ 'before_2[]',
55
+ "parse_argv[{\"error\"=>true, \"FILES\"=>[]}]",
56
+ "main[{\"error\"=>true, \"FILES\"=>[]}]",
57
+ 'after_2[]',
58
+ 'after_1[]'
59
+ ]
60
+ std, err, status = invoke('sequence.rb', '-e')
61
+ assert_same(42, status.exitstatus)
62
+ assert_equal("sequence: !error!\n", err)
63
+ assert_equal(expected, std.split("\n"))
64
+ end
65
+
66
+ def assert_no_err(...)
67
+ std, err = assert_success(...)
68
+ assert_empty(err)
69
+ std
70
+ end
71
+
72
+ def assert_success(...)
73
+ std, err, status = invoke(...)
74
+ assert(status.success?)
75
+ return std, err
76
+ end
77
+
78
+ def invoke(name, *args)
79
+ Open3.capture3(
80
+ Shellwords.join(
81
+ [
82
+ RbConfig.ruby,
83
+ '--disable',
84
+ 'gems',
85
+ '--disable',
86
+ 'did_you_mean',
87
+ '--disable',
88
+ 'rubyopt',
89
+ File.expand_path("../apps/#{name}", __dir__)
90
+ ] + args
91
+ )
92
+ )
93
+ end
94
+ end
@@ -13,12 +13,17 @@ class MainTest < Test
13
13
  subject = Class.new { include MiniCli }.new
14
14
 
15
15
  expected_methods = %i[
16
+ after
17
+ before
16
18
  error
19
+ error_code
17
20
  help
18
21
  main
19
22
  name
20
23
  parse_argv
21
24
  run
25
+ run_ruby
26
+ run_script
22
27
  show_errors=
23
28
  show_errors?
24
29
  show_help
@@ -176,4 +181,13 @@ class MainTest < Test
176
181
  result = subject.parse_argv(as_argv('-nup name port in out opt file'))
177
182
  assert_equal(expected, result)
178
183
  end
184
+
185
+ def test_run
186
+ call_sequence = []
187
+ subject.main { call_sequence << :main }
188
+ subject.before { call_sequence << :start_1 }
189
+ subject.after { call_sequence << :end_1 }
190
+ subject.before { call_sequence << :start_2 }
191
+ subject.after { call_sequence << :end_2 }
192
+ end
179
193
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helper'
4
+
5
+ class RubyRunTest < Test
6
+ def test_simple
7
+ result = subject.run_script('puts("Hello World")')
8
+ assert_equal("Hello World\n", result)
9
+ end
10
+
11
+ def test_error
12
+ result = subject.run_script('UNDEFINED')
13
+ assert_match(/NameError/, result)
14
+ end
15
+
16
+ def test_chdir
17
+ home = Dir.home
18
+ refute(home == Dir.pwd)
19
+ result = subject.run_script('print Dir.pwd', chdir: home)
20
+ assert_equal(home, result)
21
+ end
22
+
23
+ def test_status
24
+ status, result = subject.run_script('print :Ok', status: true)
25
+ assert_instance_of(Process::Status, status)
26
+ assert(status.success?)
27
+ assert_equal('Ok', result)
28
+ end
29
+
30
+ def test_status_error
31
+ status, result = subject.run_script('print :Err;exit 42', status: true)
32
+ assert_instance_of(Process::Status, status)
33
+ refute(status.success?)
34
+ assert_same(42, status.exitstatus)
35
+ assert_equal('Err', result)
36
+ end
37
+
38
+ def test_stream
39
+ stream = StringIO.new('puts "Hello World"')
40
+ result = subject.run_script(stream)
41
+ assert_equal("Hello World\n", result)
42
+ end
43
+ end
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.3.0
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: 2020-11-20 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
@@ -74,8 +74,12 @@ files:
74
74
  - samples/custom_args.rb
75
75
  - samples/demo.rb
76
76
  - samples/simple.rb
77
+ - test/apps/noop.rb
78
+ - test/apps/sequence.rb
77
79
  - test/helper.rb
80
+ - test/mini-cli/exec_test.rb
78
81
  - test/mini-cli/main_test.rb
82
+ - test/mini-cli/ruby_run_test.rb
79
83
  - test/mini-cli/run_test.rb
80
84
  homepage: https://github.com/mblumtritt/mini-cli
81
85
  licenses: []
@@ -97,11 +101,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
101
  - !ruby/object:Gem::Version
98
102
  version: '0'
99
103
  requirements: []
100
- rubygems_version: 3.1.4
104
+ rubygems_version: 3.2.28
101
105
  signing_key:
102
106
  specification_version: 4
103
107
  summary: The lean CLI framework for Ruby
104
108
  test_files:
109
+ - test/apps/noop.rb
110
+ - test/apps/sequence.rb
105
111
  - test/helper.rb
112
+ - test/mini-cli/exec_test.rb
106
113
  - test/mini-cli/main_test.rb
114
+ - test/mini-cli/ruby_run_test.rb
107
115
  - test/mini-cli/run_test.rb