parseopt 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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