parseopt 0.2.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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/parseopt.rb +65 -0
  3. data/test/test_optparse.rb +124 -0
  4. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 344951947cddbdaf40959c6d42b7319f668d431d34d19f0c9e7c94f253aa957a
4
+ data.tar.gz: 6e3fc5489a126736cb1b03d2a1cee80e3478178e048948200d0132d5afd1a995
5
+ SHA512:
6
+ metadata.gz: e2e4884941cb8c03e132941287ca014b2df78d2eaa47f52819e9966fbbaf2155deef19c16d386d2d6763dbfa5722e11e6234097ff7227fe99ec486605cb7e24f
7
+ data.tar.gz: e841a204bd15ec89c612bd9a99a9bacbc798c859a39919409a5a395b45b5423603247a0744b15b99197360c5734d7cd60536e5c58294f3267acbacfb9e07e83a
data/lib/parseopt.rb ADDED
@@ -0,0 +1,65 @@
1
+ class ParseOpt
2
+ attr_writer :usage
3
+
4
+ class Option
5
+ attr_reader :short, :long, :help
6
+
7
+ def initialize(short, long, help, &block)
8
+ @block = block
9
+ @short = short
10
+ @long = long
11
+ @help = help
12
+ end
13
+
14
+ def call(v)
15
+ @block.call(v) || true
16
+ end
17
+ end
18
+
19
+ def initialize
20
+ @list = {}
21
+ end
22
+
23
+ def on(short, long = nil, help = nil, &block)
24
+ opt = Option.new(short, long, help, &block)
25
+ @list[short] = opt if short
26
+ @list[long] = opt if long
27
+ end
28
+
29
+ def parse(args = ARGV)
30
+ if args.member?('-h') or args.member?('--help')
31
+ usage
32
+ exit 0
33
+ end
34
+ seen_dash = false
35
+ args.delete_if do |cur|
36
+ opt = val = nil
37
+ next false if cur[0] != '-' or seen_dash
38
+ case cur
39
+ when '--'
40
+ seen_dash = true
41
+ next true
42
+ when /^--no-(.+)$/
43
+ opt = @list[$1]
44
+ val = false
45
+ when /^-([^-])(.+)?$/, /^--(.+?)(?:=(.+))?$/
46
+ opt = @list[$1]
47
+ val = $2 || true
48
+ end
49
+ opt&.call(val)
50
+ end
51
+ end
52
+
53
+ def usage
54
+ puts 'usage: %s' % @usage
55
+ @list.values.uniq.each do |opt|
56
+ s = ' '
57
+ s << ''
58
+ s << [opt.short&.prepend('-'), opt.long&.prepend('--')].compact.join(', ')
59
+ s << ''
60
+ s << '%*s%s' % [26 - s.size, '', opt.help] if opt.help
61
+ puts s
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,124 @@
1
+ require 'test/unit'
2
+ require 'parseopt'
3
+ require 'stringio'
4
+
5
+ class ParseOptTest < Test::Unit::TestCase
6
+
7
+ def test_bool
8
+ bool = false
9
+ run_opts('b', %w[-b]) { |v| bool = v }
10
+ assert(bool)
11
+ end
12
+
13
+ def test_empty_bool
14
+ bool = false
15
+ run_opts('b', []) { |v| bool = v }
16
+ assert(!bool)
17
+ end
18
+
19
+ def test_unknown
20
+ run_opts('b', %w[-x], %w[-x])
21
+ end
22
+
23
+ def test_other
24
+ run_opts('b', %w[foo], %w[foo])
25
+ end
26
+
27
+ def test_other_then_bool
28
+ bool = false
29
+ run_opts('b', %w[foo -b], %w[foo]) { |v| bool = v }
30
+ assert(bool)
31
+ end
32
+
33
+ def test_double_dash
34
+ run_opts('b', %w[-- -b], %w[-b])
35
+ end
36
+
37
+ def test_value
38
+ str = 'default'
39
+ run_opts('s', %w[-sfoo]) { |v| str = v }
40
+ assert_equal('foo', str)
41
+ end
42
+
43
+ def test_long
44
+ bool = false
45
+ run_opts(['b', 'bool'], %w[--bool]) { |v| bool = v }
46
+ assert(bool)
47
+ end
48
+
49
+ def test_long_value
50
+ str = 'default'
51
+ run_opts(['s', 'string'], %w[--string=foo]) { |v| str = v }
52
+ assert_equal('foo', str)
53
+ end
54
+
55
+ def test_no_long
56
+ bool = true
57
+ run_opts(['b', 'bool'], %w[--no-bool]) { |v| bool = v }
58
+ assert(!bool)
59
+ end
60
+
61
+ def test_usage
62
+ expected = <<~EOF
63
+ usage:
64
+ -b, --bool
65
+ EOF
66
+ run_usage(['b', 'bool'], expected) { |opts| opts.usage }
67
+ end
68
+
69
+ def test_help
70
+ expected = <<~EOF
71
+ usage:
72
+ -b, --bool
73
+ EOF
74
+ run_usage(['b', 'bool'], expected) do |opts|
75
+ begin
76
+ opts.parse(%w[-h])
77
+ rescue SystemExit
78
+ end
79
+ end
80
+ end
81
+
82
+ def test_custom_usage
83
+ expected = <<~EOF
84
+ usage: test script
85
+ -b, --bool
86
+ EOF
87
+ run_usage(['b', 'bool'], expected) do |opts|
88
+ opts.usage = 'test script'
89
+ opts.usage
90
+ end
91
+ end
92
+
93
+ def test_option_help
94
+ expected = <<~EOF
95
+ usage:
96
+ -b, --bool Boolean
97
+ EOF
98
+ run_usage(['b', 'bool', 'Boolean'], expected) { |opts| opts.usage }
99
+ end
100
+
101
+ private
102
+
103
+ def run_opts(opt, args, result = [])
104
+ opts = ParseOpt.new
105
+ opts.on(*opt) { |v| yield v }
106
+ assert_equal(result, opts.parse(args))
107
+ end
108
+
109
+ def run_usage(opt, expected)
110
+ opts = ParseOpt.new
111
+ opts.on(*opt)
112
+ assert_equal(expected, capture { yield opts })
113
+ end
114
+
115
+ def capture
116
+ stdout_save = $stdout
117
+ $stdout = StringIO.new
118
+ yield
119
+ $stdout.string
120
+ ensure
121
+ $stdout = stdout_save
122
+ end
123
+
124
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parseopt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Felipe Contreras
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A very simple option parser
14
+ email: felipe.contreras@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/parseopt.rb
20
+ - test/test_optparse.rb
21
+ homepage: https://rubygems.org/gems/parseopt
22
+ licenses:
23
+ - GPL-2.0-only
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubygems_version: 3.2.15
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Option parser
44
+ test_files:
45
+ - test/test_optparse.rb