getopt-declare 1.23 → 1.25

Sign up to get free protection for your applications and to get access to all the features.
data/Declare.rdoc CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # = VERSION
7
7
  #
8
- # This document describes version 1.22 of Getopt::Declare,
8
+ # This document describes version 1.25 and later of Getopt::Declare,
9
9
  # Released Jan 21, 2007 for Ruby.
10
10
  #
11
11
  # Original Perl's Getopt-Declare v1.09, Released May 21, 1999.
@@ -17,7 +17,7 @@
17
17
  #
18
18
  # -q, --quiet quiet
19
19
  # -f, --files <files:if>... input files
20
- # -n, --number <num:n> a float number
20
+ # -n, --number <num:n> a float number [required]
21
21
  # -i, --integer <num:i> an integer number
22
22
  #
23
23
  # EOF
data/HISTORY.txt CHANGED
@@ -1,52 +1,69 @@
1
- 1.23 - * Added all samples as Ruby tests, which lead to the discovery
2
- of several bugs.
3
- * Fixed silly bug with foundid that would make some parsing not
4
- work (required parameters).
5
- * Fixed a silly bug when parsing from a string file, which would
6
- modify the string in place
7
- * Fixed a bug in that would make it not parse Rh+ and Rh- in
8
- cmdline_pvttype demo and other potential regexes.
9
- * Removed 3 warnings from parsing multiple times.
10
- * Fixed a bug with cluster: singles not working.
11
- * Fixed a stack trace bug with optional single text arguments.
12
- * Improved handling of optional integer/float arguments, leaving
13
- them as nil instead of 0 as before.
14
- * Added 'used' function to allow returning the flags that are used.
15
- * Made CSV demo work again, albeit I am not too happy with the regex.
16
- * Made Getopt::Declare part of firebrigade.
17
- http://firebrigade.seattlerb.org/
18
-
19
- 1.22 - * Fixed some nasty bugs introduced in 1.21, which would cause stack
20
- traces.
21
- * Fixed the use of /bin/env in some demos instead of /usr/bin/env.
22
-
23
- 1.21 - Incorporated Perl fixes done by Damian in v1.10 and v1.11 of the
24
- corresponding Getopt-Declare into Ruby.
25
-
26
- * If -p[rompt] and -p[rompt]2 are specified, they are now distinguished
27
- as separate flags.
28
- * Documented built-in :id and :qs parameter variable types
29
- * Added \G to -v flag checker to solve nasty problem with embedded
30
- args containing -v
31
-
32
- 1.20 - Added support for using 3 spaces in addition to tabs for
33
- parameter descriptions.
34
- Added support for GNU -p, --param descriptions, for easier
35
- GNU parameter support.
36
- Fixed help description bug with [ditto] of single parameter flags.
37
-
38
- 1.13 - Fixed bug that would always match parameters in a case insensitive
39
- way, as if [nocase] had been used. This should speed the parser a
40
- tiny bit.
41
-
42
- [cluster: ...] was incorrectly being printed in help usage.
43
-
44
- 1.12 - Fixed bug with :+i, :+n, :0+i options not being cast appropiately
45
- when used in pvttypes.
46
- Added [debug] option to argument description to turn on debugging.
47
-
48
- NOTE: there is a known bug when using [] within pvttype regex
49
- definitions. Problem seems to be related to DelimScanner/strscan.
50
-
51
- 1.11 - Fixed a pretty bug that was parsing -flags inappropiately and leading
52
- to slower parsing.
1
+ == 1.25
2
+ * Really just v1.24, but there were problems with hoe releasing.
3
+ * Made -version not fail when doing rake tests and file is not
4
+ located.
5
+ * Upgraded Rakefile to using Hoe (much simpler).
6
+ Sadly, this makes getopt-declare be getoptdeclare.
7
+ * Fixed a bug regarding required parameters not being found in
8
+ the released version of 1.23 (my custom version was okay).
9
+
10
+ == 1.24
11
+ * Made -version not fail when doing rake tests and file is not
12
+ located.
13
+ * Upgraded Rakefile to using Hoe (much simpler).
14
+ * Fixed a bug regarding required parameters not being found in
15
+ the released version of 1.23 (my custom version was okay).
16
+
17
+ == 1.23
18
+ * Added all samples as Ruby tests, which lead to the discovery
19
+ of several bugs.
20
+ * Fixed silly bug with foundid that would make some parsing not
21
+ work (required parameters).
22
+ * Fixed a silly bug when parsing from a string file, which would
23
+ modify the string in place
24
+ * Fixed a bug in that would make it not parse Rh+ and Rh- in
25
+ cmdline_pvttype demo and other potential regexes.
26
+ * Removed 3 warnings from parsing multiple times.
27
+ * Fixed a bug with cluster: singles not working.
28
+ * Fixed a stack trace bug with optional single text arguments.
29
+ * Improved handling of optional integer/float arguments, leaving
30
+ them as nil instead of 0 as before.
31
+ * Added 'used' function to allow returning the flags that are used.
32
+ * Made CSV demo work again, albeit I am not too happy with the regex.
33
+ * Made Getopt::Declare part of firebrigade.
34
+ http://firebrigade.seattlerb.org/
35
+
36
+ 1.22 - * Fixed some nasty bugs introduced in 1.21, which would cause stack
37
+ traces.
38
+ * Fixed the use of /bin/env in some demos instead of /usr/bin/env.
39
+
40
+ 1.21 - Incorporated Perl fixes done by Damian in v1.10 and v1.11 of the
41
+ corresponding Getopt-Declare into Ruby.
42
+
43
+ * If -p[rompt] and -p[rompt]2 are specified, they are now distinguished
44
+ as separate flags.
45
+ * Documented built-in :id and :qs parameter variable types
46
+ * Added \G to -v flag checker to solve nasty problem with embedded
47
+ args containing -v
48
+
49
+ 1.20 - Added support for using 3 spaces in addition to tabs for
50
+ parameter descriptions.
51
+ Added support for GNU -p, --param descriptions, for easier
52
+ GNU parameter support.
53
+ Fixed help description bug with [ditto] of single parameter flags.
54
+
55
+ 1.13 - Fixed bug that would always match parameters in a case insensitive
56
+ way, as if [nocase] had been used. This should speed the parser a
57
+ tiny bit.
58
+
59
+ [cluster: ...] was incorrectly being printed in help usage.
60
+
61
+ 1.12 - Fixed bug with :+i, :+n, :0+i options not being cast appropiately
62
+ when used in pvttypes.
63
+ Added [debug] option to argument description to turn on debugging.
64
+
65
+ NOTE: there is a known bug when using [] within pvttype regex
66
+ definitions. Problem seems to be related to DelimScanner/strscan.
67
+
68
+ 1.11 - Fixed a pretty bug that was parsing -flags inappropiately and leading
69
+ to slower parsing.
data/Manifest.txt ADDED
@@ -0,0 +1,40 @@
1
+ lib
2
+ lib/Getopt
3
+ lib/Getopt/Declare.rb
4
+ lib/Getopt/DelimScanner.rb
5
+ Declare.rdoc
6
+ HISTORY.txt
7
+ README.txt
8
+ Manifest.txt
9
+ samples
10
+ samples/cmdline_basic.rb
11
+ samples/cmdline_mid.rb
12
+ samples/cmdline_parameters.rb
13
+ samples/cmdline_regex.rb
14
+ samples/cmdline_pvtype.rb
15
+ samples/cmdline_code.rb
16
+ samples/cmdline_pvtype2.rb
17
+ samples/cmdline_file.rb
18
+ samples/demo_csv.rb
19
+ samples/demo_shell.rb
20
+ samples/demo_interp.rb
21
+ samples/demo_cmdline.rb
22
+ samples/cmdline_noargv.rb
23
+ samples/cmdline_array.rb
24
+ samples/cmdline_defer.rb
25
+ samples/cmdline_singles.rb
26
+ samples/cmdline_inlines.rb
27
+ samples/cmdline_finish.rb
28
+ Rakefile
29
+ test
30
+ test/test_cmdline_cmdline.rb
31
+ test/test_cmdline_basic.rb
32
+ test/test_cmdline_finish.rb
33
+ test/test_cmdline_mid.rb
34
+ test/test_cmdline_parameters.rb
35
+ test/test_cmdline_pvtype2.rb
36
+ test/test_cmdline_pvtype.rb
37
+ test/test_cmdline_regex.rb
38
+ test/test_demo_csv.rb
39
+ test/test_cluster_singles.rb
40
+ test/test_cmdline_array.rb
data/README.txt ADDED
File without changes
data/Rakefile CHANGED
@@ -1,102 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rake/gempackagetask'
4
- require 'rake/rdoctask'
5
- require 'rake/testtask'
3
+
4
+ require 'rubygems'
5
+ require 'hoe'
6
+ require './lib/Getopt/Declare'
6
7
 
7
8
  rdoc_files = ["Declare.rdoc", 'HISTORY.txt'] + Dir.glob('lib/*/*.rb')
8
9
 
9
- #
10
- # TASK: Gem specification and creation ('gem')
11
- #
12
- spec = Gem::Specification.new do |spec|
13
- spec.name = "getopt-declare"
14
- spec.version = '1.23'
15
- spec.author = "Gonzalo Garramuno"
16
- spec.email = 'ggarra@advancedsl.com.ar, GGarramuno@aol.com'
17
- spec.homepage = 'http://www.rubyforge.org/projects/getoptdeclare/'
18
- spec.summary = 'Getopt-Declare is a command-line argument parser.'
19
- spec.require_path = "lib"
20
- spec.autorequire = "Getopt/Declare"
21
- spec.files = ["lib/Getopt/Declare.rb", "lib/Getopt/DelimScanner.rb",
22
- "Rakefile"]
23
- spec.description = <<-"EOF"
10
+
11
+ Hoe.new('getopt-declare', Getopt::Declare::VERSION) do |p|
12
+ p.rubyforge_name = name = 'getoptdeclare'
13
+ p.author = "Gonzalo Garramuno"
14
+ p.email = 'ggarra@advancedsl.com.ar, GGarramuno@aol.com'
15
+ p.summary = "Getopt-Declare is a command-line argument parser."
16
+ p.description = <<-"EOF"
24
17
  Comprehensive and easy to use command-line parser library using
25
18
  regular expressions. Port of Damian Conway\'s Perl Getopt-Declare.
26
19
  EOF
27
- # to fix emacs coloring bug
28
- spec.extra_rdoc_files = rdoc_files
29
- spec.has_rdoc = true
30
- spec.test_files = Dir.glob('samples/*.rb')
31
- spec.rubyforge_project = 'getoptdeclare'
32
- spec.required_ruby_version = '>= 1.6.8'
33
- end
34
-
35
- Rake::GemPackageTask.new(spec) do |pkg|
36
- pkg.need_tar = true
37
- end
38
-
39
-
40
- #
41
- # TASK: Run rdoc to document code ('rdoc')
42
- #
43
- html_dir = 'doc/html'
44
- library = 'Getopt/Declare'
45
- Rake::RDocTask.new('rdoc') do |t|
46
- t.rdoc_files.include(rdoc_files)
47
- t.main = 'doc/index.html' # Main web page
48
- t.title = "#{library} API documentation"
49
- t.rdoc_dir = html_dir
50
- end
51
-
52
-
53
- #
54
- # TASK: Upload docs to rubyforge ('upload-docs')
55
- #
56
- desc 'Upload documentation to RubyForge.'
57
- task 'upload-docs' => ['rdoc'] do
58
- rubyforge_user = 'gga'
59
- rubyforge_project = spec.rubyforge_project
60
- rubyforge_path = "/var/www/gforge-projects/#{rubyforge_project}/"
61
-
62
- sh "scp -r #{html_dir}/* #{rubyforge_user}@rubyforge.org:#{rubyforge_path}"
63
- end
64
-
65
-
66
- desc 'Zip directory as an archive.'
67
- task 'zip' => ['rdoc'] do
68
- dir = File.basename(Dir.pwd)
69
- zipfile = spec.name + "-" + spec.version.to_s + ".zip"
70
- Dir.chdir('..')
71
- File.unlink(zipfile) if File.exists?(zipfile)
72
- sh "zip -9rv #{zipfile} #{dir} -x '*~' -x '#*#' -x '*docs/*' -x '*pkg/*' -x '.*'"
73
- Dir.chdir(dir)
74
- end
75
-
76
- desc 'Run unit tests'
77
- Rake::TestTask.new do |t|
78
- t.libs << 'test'
79
- t.test_files = FileList['test/*.rb']
80
- t.verbose = true
81
- t.warning = true
82
- # t.loader = :testrb
83
- # p t.methods - Object.methods
84
- end
85
-
86
- desc 'upload gem'
87
- task 'upload-gem' => ['test', 'gem'] do
88
- end
89
-
90
- desc 'upload zip'
91
- task 'upload-zip' => ['zip'] do
20
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
21
+ p.url = "#{name}.rubyforge.org"
22
+ p.changes = p.paragraphs_of('HISTORY.txt', 0).join("\n\n")
23
+ p.need_zip = p.need_tar = true
92
24
  end
93
25
 
94
- desc 'Upload gem, docs and zip file'
95
- task 'upload' => [ 'upload-gem', 'upload-zip', 'upload-docs' ]
96
26
 
27
+ task :default => ['test', 'redocs', 'publish_docs',
28
+ 'package', 'release', 'announce', 'email', 'post_news']
97
29
 
98
30
 
99
- #
100
- # Main task
101
- #
102
- task :default => ['upload']
@@ -4,7 +4,7 @@
4
4
  # Ruby port of Perl's Getopt::Declare, version 1.21,
5
5
  # released May 21, 1999.
6
6
  #
7
- # $Release Version: 1.22 $
7
+ # $Release Version: 1.25 $
8
8
  # $Date: 2007/01/15 10:53:09 $
9
9
  # by Gonzalo Garramu�o
10
10
  #
@@ -70,7 +70,7 @@ module Getopt
70
70
  # Main Class
71
71
  class Declare
72
72
 
73
- VERSION = '1.22'
73
+ VERSION = '1.25'
74
74
 
75
75
  # For debugging, use [debug] and it will output the ruby code as .CODE.rb
76
76
  @@debug = false
@@ -531,7 +531,7 @@ EOS
531
531
  @args = []
532
532
  @actions = []
533
533
  @ditto = dittoflag
534
- @required = 0
534
+ @required = false
535
535
  @requires = nil
536
536
  @id = @@nextid
537
537
  @desc = spec.dup
@@ -753,7 +753,7 @@ EOS
753
753
 
754
754
  # Return foundid of argument, which can be flag's name or variable's name
755
755
  def foundid
756
- return @foundid || "<#{self.name}>"
756
+ return @foundid || self.name
757
757
  end
758
758
 
759
759
  end # Arg
@@ -1285,7 +1285,11 @@ EOS
1285
1285
  # Print out version information and maybe exit
1286
1286
  def version(*t)
1287
1287
  prog = "#{$0}"
1288
- filedate = File.stat( prog ).mtime.localtime()
1288
+ begin
1289
+ filedate = File.stat( prog ).mtime.localtime()
1290
+ rescue
1291
+ filedate = 'Unknown date'
1292
+ end
1289
1293
  prog.sub!(%r#.*/#,'')
1290
1294
  r = ''
1291
1295
  if defined?($VERSION)
@@ -1580,14 +1584,13 @@ end # begin
1580
1584
  for arg in @args
1581
1585
  next unless arg.required
1582
1586
 
1583
- code << %q%
1584
- unless _FOUND_['% + arg.name + %q%'] %
1587
+ code << %q%unless _FOUND_['% + arg.name + %q%'] %
1585
1588
 
1586
- if @mutex[arg.name]
1587
- for m in @mutex[arg.name]
1588
- code << %q# or _FOUND_['# + m + %q#']#
1589
- end
1590
- end
1589
+ if @mutex[arg.name]
1590
+ for m in @mutex[arg.name]
1591
+ code << %q# or _FOUND_['# + m + %q#']#
1592
+ end
1593
+ end
1591
1594
 
1592
1595
  code << %q%
1593
1596
  $stderr.puts "Error#{@source}: required parameter '% + arg.name + %q%' not found."
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_ClusterSingle < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ -a Append mode
16
+ -b Back-up mode
17
+ -bu [ditto]
18
+ -c <file> Copy mode
19
+ -d [<file>] Delete mode
20
+ -e[xec] Execute mode
21
+
22
+ [cluster:singles]
23
+ EOPARAM
24
+ end
25
+
26
+
27
+ def test_normal
28
+ @args.parse('-a -b')
29
+ assert_equal( '-a', @args['-a'] )
30
+ assert_equal( '-b', @args['-b'] )
31
+ end
32
+
33
+ def test_cluster_ab
34
+ @args.parse('-ab')
35
+ assert_equal( '-a', @args['-a'] )
36
+ assert_equal( '-b', @args['-b'] )
37
+ end
38
+
39
+ def test_cluster_ba
40
+ @args.parse('-ba')
41
+ assert_equal( '-a', @args['-a'] )
42
+ assert_equal( '-b', @args['-b'] )
43
+ end
44
+
45
+ def test_bu
46
+ @args.parse('-bu')
47
+ assert_equal( '-bu', @args['-b'] )
48
+ assert_equal( '-bu', @args['-bu'] )
49
+ end
50
+
51
+ def test_cluster_abu
52
+ @args.parse('-abu')
53
+ assert_equal( '-a', @args['-a'] )
54
+ assert_equal( '-b', @args['-b'] )
55
+ assert_equal( ['u'], @args.unused )
56
+ end
57
+
58
+ end
59
+
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+
7
+ class TC_Array < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @file = __FILE__
11
+ @args = Getopt::Declare.new( %q{
12
+ -v <value:i> [etc] One or more values
13
+ <infile:if> Input file [required]
14
+ -o <outfiles:of>... Output files
15
+ }, :build )
16
+ end
17
+
18
+ def test_infile
19
+ @args.parse(@file)
20
+ assert_equal( @file, @args['<infile>'] )
21
+ end
22
+
23
+ def test_v_val
24
+ @args.parse("-v 20 #@file")
25
+ assert_equal( 20, @args['-v']['<value>'] )
26
+ assert_equal( @file, @args['<infile>'] )
27
+ end
28
+
29
+ def test_v_val_etc
30
+ @args.parse("-v 20 etc #@file")
31
+ assert_equal( 20, @args['-v']['<value>'] )
32
+ assert_equal( 'etc', @args['-v']['etc'] )
33
+ assert_equal( @file, @args['<infile>'] )
34
+ end
35
+
36
+ def test_o_single
37
+ @args.parse("-v 20 etc #@file -o goodbye")
38
+ assert_equal( ['goodbye'], @args['-o'] )
39
+ end
40
+
41
+ def test_o_multi
42
+ @args.parse("-v 20 etc #@file -o abc goodbye other")
43
+ assert_equal( ['abc', 'goodbye', 'other'], @args['-o'] )
44
+ end
45
+
46
+ def test_unused
47
+ @args.parse("-v 20 etc #@file crapola -o abc goodbye other")
48
+ assert_equal( ['abc', 'goodbye', 'other'], @args['-o'] )
49
+ assert_equal( ['crapola'], @args.unused )
50
+ end
51
+
52
+ def test_usage
53
+ usage = @args.usage
54
+ # We don't check first lines, as they contain date
55
+ usage.sub!(/.*Options:/m, '')
56
+ puts usage
57
+ assert_equal( <<"EOF", usage )
58
+
59
+ -v <value> [etc] One or more values
60
+ <infile> Input file
61
+ -o <outfiles>... Output files
62
+ EOF
63
+ end
64
+
65
+ end
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+
7
+ class TC_Basic < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @file = __FILE__
11
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
12
+
13
+ ============================================================
14
+ Required parameter:
15
+
16
+ -in <infile> Input file [required]
17
+
18
+ ------------------------------------------------------------
19
+
20
+ Optional parameters:
21
+
22
+ (The first two are mutually exclusive) [mutex: -r -p]
23
+
24
+ -r[and[om]] Output in random order
25
+ -p[erm[ute]] Output all permutations
26
+
27
+ ---------------------------------------------------
28
+
29
+ -out <outfile> Optional output file
30
+
31
+ ------------------------------------------------------------
32
+ Note: this program is known to run very slowly of files with
33
+ long individual lines.
34
+ ============================================================
35
+ EOPARAM
36
+ end
37
+
38
+ def test_infile
39
+ @args.parse("-in #@file")
40
+ assert_equal( @args['-in'], @file )
41
+ end
42
+
43
+ def test_outfile
44
+ @args.parse("-in #@file -out crapola")
45
+ assert_equal( @args['-in'], @file )
46
+ assert_equal( @args['-out'], 'crapola' )
47
+ end
48
+
49
+ def test_random
50
+ @args.parse("-in #@file -random -out crapola")
51
+ assert_equal( @args['-in'], @file )
52
+ assert_equal( @args['-out'], 'crapola' )
53
+ assert_equal( @args['-r']['and'], 'and' )
54
+ assert_equal( @args['-r']['om'], 'om' )
55
+ end
56
+
57
+ def test_r
58
+ @args.parse("-in #@file -r -out crapola")
59
+ assert_equal( @args['-in'], @file )
60
+ assert_equal( @args['-out'], 'crapola' )
61
+ assert_not_equal( @args['-r'], nil )
62
+ end
63
+
64
+ def test_p
65
+ @args.parse("-in #@file -p -out crapola")
66
+ assert_equal( @args['-in'], @file )
67
+ assert_equal( @args['-out'], 'crapola' )
68
+ assert_not_equal( @args['-p'], nil )
69
+ end
70
+
71
+ def test_perm
72
+ @args.parse("-in #@file -perm -out crapola")
73
+ assert_equal( @args['-in'], @file )
74
+ assert_equal( @args['-out'], 'crapola' )
75
+ assert_equal( @args['-p']['erm'], 'erm' )
76
+ assert_not_equal( @args['-p']['ute'], 'ute' )
77
+ end
78
+
79
+ def test_permute
80
+ @args.parse("-in #@file -permute -out crapola")
81
+ assert_equal( @args['-in'], @file )
82
+ assert_equal( @args['-out'], 'crapola' )
83
+ assert_equal( @args['-p']['erm'], 'erm' )
84
+ assert_equal( @args['-p']['ute'], 'ute' )
85
+ end
86
+
87
+ def test_mutex
88
+ # @args.parse("-in #@file -r -permute -out crapola")
89
+ end
90
+
91
+ end
92
+
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_CmdlineDemo < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ General options:
16
+ -e <f:i>..<t:i> Set expansion factor to specified range
17
+ [requires: <file>]
18
+ { puts "k = [#{f}..#{t}]" }
19
+
20
+ -e [<k:n>...] Set expansion factor to <k> (or 2 by default)
21
+ [required]
22
+ { k = [2] unless k
23
+ print "k = [", k.join(','), "]\n"; }
24
+
25
+ -b <blen:i> Use byte length of <blen>
26
+ [excludes: -a +c]
27
+ { print "byte len: #{blen}\n"; }
28
+
29
+ <file>... Process files [required] [implies: -a]
30
+ { print "files: #{file}\n"; }
31
+
32
+ -a [<n:n>] Process all data [except item <n>]
33
+ { print "proc all\n"; print "except #{n}\n" if n }
34
+
35
+ -fab The fabulous option (is always required :-)
36
+ [required]
37
+ { defer { print "fabulous!\n" } }
38
+
39
+ File creation options:
40
+
41
+ +c <file> Create file [mutex: +c -a]
42
+ { print "create: file\n"; }
43
+
44
+ +d <file> Duplicate file [implies: -a and -b 8]
45
+ This is a second line
46
+ { print "dup (+d) #{file}\n"; }
47
+ --dup <file> [ditto] (long form)
48
+
49
+ -how <n:i> Set height to <n> [repeatable]
50
+
51
+ Garbling options:
52
+
53
+ -g [<seed:i>] Garble output with optional seed [requires: +c]
54
+ { print "garbling with #{seed}\n"; }
55
+ -i Case insensitive garbling [required]
56
+ { print "insensitive\n"; }
57
+ -s Case sensitive garbling
58
+ -w WaReZ m0De 6aRBL1N6
59
+
60
+ [mutex: -i -s -w]
61
+ EOPARAM
62
+ end
63
+
64
+
65
+ def test_file
66
+ @args.parse('-e 1.0 -i -fab file.txt')
67
+ assert_equal( ['file.txt'], @args['<file>'] )
68
+ assert_equal( '-fab', @args['-fab'] )
69
+ assert_equal( [1.0], @args['-e'] )
70
+ assert_equal( '-i', @args['-i'] )
71
+ end
72
+
73
+ def test_s
74
+ @args.parse('-e 1.0 -s -fab file.txt')
75
+ assert_equal( ['file.txt'], @args['<file>'] )
76
+ assert_equal( '-fab', @args['-fab'] )
77
+ assert_equal( [1.0], @args['-e'] )
78
+ assert_equal( '-s', @args['-s'] )
79
+ end
80
+
81
+ def test_w
82
+ @args.parse('-e 1.0 -w -fab file.txt')
83
+ assert_equal( ['file.txt'], @args['<file>'] )
84
+ assert_equal( '-fab', @args['-fab'] )
85
+ assert_equal( [1.0], @args['-e'] )
86
+ assert_equal( '-w', @args['-w'] )
87
+ end
88
+
89
+
90
+ def test_d
91
+ @args.parse('+d nothing -e 1.0 -w -fab file.txt')
92
+ assert_equal( ['file.txt'], @args['<file>'] )
93
+ assert_equal( '-fab', @args['-fab'] )
94
+ assert_equal( [1.0], @args['-e'] )
95
+ assert_equal( '-w', @args['-w'] )
96
+ assert_equal( 'nothing', @args['+d'] )
97
+ assert_equal( nil, @args['--dup'] )
98
+ end
99
+
100
+ def test_dup
101
+ @args.parse('--dup nothing -e 1.0 -w -fab file.txt')
102
+ assert_equal( ['file.txt'], @args['<file>'] )
103
+ assert_equal( '-fab', @args['-fab'] )
104
+ assert_equal( [1.0], @args['-e'] )
105
+ assert_equal( '-w', @args['-w'] )
106
+ assert_equal( 'nothing', @args['+d'] )
107
+ assert_equal( 'nothing', @args['--dup'] )
108
+ end
109
+
110
+ def test_how
111
+ @args.parse('-how 2 -how 3 -e 1.0 -w -fab file.txt')
112
+ assert_equal( ['file.txt'], @args['<file>'] )
113
+ assert_equal( '-fab', @args['-fab'] )
114
+ assert_equal( [1.0], @args['-e'] )
115
+ assert_equal( '-w', @args['-w'] )
116
+ assert_equal( 3, @args['-how'] )
117
+ end
118
+
119
+ def test_g
120
+ @args.parse('+c something -g 20 -e 1.0 -w -fab file.txt')
121
+ assert_equal( ['file.txt'], @args['<file>'] )
122
+ assert_equal( '-fab', @args['-fab'] )
123
+ assert_equal( [1.0], @args['-e'] )
124
+ assert_equal( '-w', @args['-w'] )
125
+ assert_equal( 20, @args['-g'] )
126
+ end
127
+
128
+ def test_e
129
+ @args.parse('-e 2..4 -w -fab file.txt')
130
+ assert_equal( ['file.txt'], @args['<file>'] )
131
+ assert_equal( '-fab', @args['-fab'] )
132
+ assert_equal( 2, @args['-e']['<f>'] )
133
+ assert_equal( 4, @args['-e']['<t>'] )
134
+ assert_equal( '-w', @args['-w'] )
135
+ end
136
+
137
+
138
+ end
139
+
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+
7
+ class TC_Finish < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
11
+ --verbose Print verbose info
12
+ -- Traditional argument list terminator
13
+ { finish }
14
+ EOPARAM
15
+ end
16
+
17
+ def test_verbose
18
+ @args.parse("--verbose")
19
+ assert_equal( '--verbose', @args['--verbose'] )
20
+ end
21
+
22
+ def test_terminator
23
+ @args.parse("--verbose -- crapola")
24
+ assert_equal( ['crapola'], @args.unused )
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ def delold
7
+ print "would have deleted\n"
8
+ end
9
+
10
+ class TC_Mid < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @file = __FILE__
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ -a Process all data
16
+ -b <n:n> Set mean byte length threshold to <N>
17
+ { bytelen = n }
18
+ +c <FILE> Create new file <FILE>
19
+ --del Delete old file
20
+ { delold(); }
21
+ delete [ditto]
22
+ e <w:i>x<h:i> Expand image to height <h> and width <w>
23
+ { }
24
+ -F <file>... Process named file(s)
25
+ { defer { file.each {|i|
26
+ process(i) } } }
27
+ =getrand [<n:i>] Get a random number
28
+ (or, optionally, <n> of them)
29
+ { n = 1 unless n }
30
+ -- Traditionally indicates end of arguments
31
+ { finish }
32
+ EOPARAM
33
+ end
34
+
35
+ def test_getrand
36
+ @args.parse('=getrand')
37
+ assert_equal( 1, @args['=getrand'] )
38
+ @args.parse('=getrand 15')
39
+ assert_equal( 15, @args['=getrand'] )
40
+ end
41
+
42
+ def test_e
43
+ @args.parse('e 320x480')
44
+ assert_equal( 320, @args['e']['<w>'] )
45
+ assert_equal( 480, @args['e']['<h>'] )
46
+ end
47
+
48
+ def test_delete
49
+ @args.parse('--del')
50
+ assert_equal( '--del', @args['--del'] )
51
+ @args.parse('delete')
52
+ assert_equal( 'delete', @args['--del'] )
53
+ end
54
+
55
+ def test_end
56
+ @args.parse('--del =getrand -- 15 -a')
57
+ assert_equal( nil, @args['-a'] )
58
+ assert_equal( 1, @args['=getrand'] )
59
+ assert_equal( '--del', @args['--del'] )
60
+ assert_equal( ['15', '-a'], @args.unused )
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_Parameters < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ -list <l>... ttt
16
+ -out <out> ttt
17
+ in=<infile> ttt
18
+ +range <from> [..] <to> ttt
19
+ --lines <start> - <stop> ttt
20
+ ignore bad lines ttt
21
+ <outfile> ttt
22
+ -copy <files>... <dir> copy files to dir
23
+ -range <from:i> [[..] [<to:i>] ] opt. range
24
+ { to = 10 if to == 0 }
25
+ -pattern <regex> match a pattern
26
+ EOPARAM
27
+ end
28
+
29
+ def test_regex
30
+ @args.parse("-pattern abc")
31
+ assert_equal( 'abc', @args['-pattern'] )
32
+
33
+ @args.parse("-pattern .*")
34
+ assert_equal( '.*', @args['-pattern'] )
35
+
36
+ @args.parse("-pattern abc[a-z]")
37
+ assert_equal( 'abc[a-z]', @args['-pattern'] )
38
+
39
+ @args.parse("-pattern abc[a-z]+")
40
+ assert_equal( 'abc[a-z]+', @args['-pattern'] )
41
+
42
+ @args.parse("-pattern abc[a-z]+dsa")
43
+ assert_equal( 'abc[a-z]+dsa', @args['-pattern'] )
44
+
45
+ @args.parse("-pattern abc[a-z]+.*")
46
+ assert_equal( 'abc[a-z]+.*', @args['-pattern'] )
47
+ end
48
+
49
+ def test_list
50
+ @args.parse('-list 1 2 3 4')
51
+ assert_equal( ['1','2','3','4'], @args['-list'] )
52
+ end
53
+
54
+ def test_in
55
+ @args.parse('in=hello')
56
+ assert_equal( 'hello', @args['in='] )
57
+ end
58
+
59
+ def test_plus_range
60
+ @args.parse('+range 1 20')
61
+ assert_equal( '1', @args['+range']['<from>'] )
62
+ assert_equal( '20', @args['+range']['<to>'] )
63
+ @args.parse('+range ABC .. ZZZ')
64
+ assert_equal( 'ABC', @args['+range']['<from>'] )
65
+ assert_equal( 'ZZZ', @args['+range']['<to>'] )
66
+ end
67
+
68
+ def test_lines
69
+ @args.parse('--lines 1 - 20')
70
+ assert_equal( '1', @args['--lines']['<start>'] )
71
+ assert_equal( '20', @args['--lines']['<stop>'] )
72
+ # Hmm... should this work?
73
+ # @args.parse('--lines 1-20')
74
+ # assert_equal( '1', @args['--lines']['<start>'] )
75
+ # assert_equal( '20', @args['--lines']['<stop>'] )
76
+ end
77
+
78
+ def test_range_minus
79
+ @args.parse('-range 1 .. 20')
80
+ assert_equal( 1, @args['-range']['<from>'] )
81
+ assert_equal( 20, @args['-range']['<to>'] )
82
+ @args.parse('-range 1..20')
83
+ assert_equal( 1, @args['-range']['<from>'] )
84
+ assert_equal( 20, @args['-range']['<to>'] )
85
+ @args.parse('-range 1 20')
86
+ assert_equal( 1, @args['-range']['<from>'] )
87
+ assert_equal( 20, @args['-range']['<to>'] )
88
+ @args.parse('-range 1')
89
+ assert_equal( 1, @args['-range']['<from>'] )
90
+ assert_equal( 10, @args['-range']['<to>'] )
91
+ @args.parse('-range 1..')
92
+ assert_equal( 1, @args['-range']['<from>'] )
93
+ assert_equal( 10, @args['-range']['<to>'] )
94
+ end
95
+
96
+ def test_copy
97
+ @args.parse('-copy fileA dest')
98
+ assert_equal( ['fileA'], @args['-copy']['<files>'] )
99
+ assert_equal( 'dest', @args['-copy']['<dir>'] )
100
+ end
101
+
102
+ def test_ignore_bad_lines
103
+ @args.parse('ignore bad lines')
104
+ assert_not_equal( nil, @args['ignore'] )
105
+ end
106
+
107
+ end
108
+
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_PvType < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ [pvtype: type /AB|[OAB]/ ]
16
+ [pvtype: Rh /Rh[+-]/ ]
17
+ [pvtype: days :+i {
18
+ reject( (_VAL_ < 14)," #{_PARAM_} (too soon!)" )
19
+ }
20
+ ]
21
+ -donated <d:days> Days since last donation
22
+ -applied <a:days> Days since applied to donate
23
+
24
+ -blood <type:type> [<rh:Rh>] Specify blood type
25
+ and (optionally) rhesus factor
26
+ EOPARAM
27
+ end
28
+
29
+ def test_type
30
+ ['AB', 'O', 'A', 'B'].each { |type|
31
+ line = "-blood #{type}"
32
+ @args.parse(line)
33
+ assert_equal( type, @args['-blood']['<type>'] )
34
+ }
35
+ end
36
+
37
+ def test_applied
38
+ @args.parse('-applied 15')
39
+ assert_equal( 15, @args['-applied'] )
40
+ end
41
+
42
+ def test_donated
43
+ @args.parse('-donated 15')
44
+ assert_equal( 15, @args['-donated'] )
45
+ end
46
+
47
+ def test_rh
48
+ ['AB', 'O', 'A', 'B'].each { |type|
49
+ ['', 'Rh+','Rh-'].each { |rh|
50
+ line = "-blood #{type} #{rh}"
51
+ @args.parse(line)
52
+ assert_equal( type, @args['-blood']['<type>'] )
53
+ assert_equal( rh, @args['-blood']['<rh>'] )
54
+ }
55
+ }
56
+ end
57
+ end
58
+
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_PvType2 < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ [strict]
16
+ [pvtype: num /\d+/ ]
17
+ [pvtype: 'a num' :n { puts "a num!" } ]
18
+ [pvtype: %q{nbr} :'a num' ]
19
+
20
+ -count1 <n:num> test
21
+ -count2 <n:a num> test2
22
+ -count3 <n:nbr> test3
23
+ EOPARAM
24
+ end
25
+
26
+ def test_count1
27
+ @args.parse('-count1 20')
28
+ assert_equal( '20', @args['-count1'] )
29
+ end
30
+
31
+ def test_count2
32
+ @args.parse('-count2 20')
33
+ assert_equal( 20, @args['-count2'] )
34
+ end
35
+
36
+ # @todo: this should really be 20, not '20'
37
+ def test_count3
38
+ @args.parse('-count3 20')
39
+ assert_equal( '20', @args['-count3'] )
40
+ end
41
+ end
42
+
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+
11
+ class TC_Regex < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @args = Getopt::Declare.new(<<'EOPARAM', :build)
15
+ -ar <r:n> Set aspect ratio (will be clipped to [0..1] )
16
+ {
17
+ r = 0 if r < 0
18
+ r = 1 if r > 1
19
+ }
20
+ -w <pixels:+i> Specify width in pixels
21
+ -h <pixels:+i> Specify height in pixels
22
+ -list <all:i>... list of numbers
23
+ -range <from:i> [- [<to:i>] ] opt. range
24
+ { to = 10 if to == 0 }
25
+ -parity <p:/even|odd|both/> Set parity (<p> must be "even",
26
+ "odd" or "both")
27
+ -file <name:/\w*\.[A-Z]{3}/> File name must have a three-
28
+ capital-letter extension
29
+ -find <what:/(%T.)+/> ; look ahead test
30
+ EOPARAM
31
+ end
32
+
33
+ def test_ar
34
+ @args.parse('-ar 1')
35
+ assert_equal( 1.0, @args['-ar'] )
36
+ @args.parse('-ar 0.4')
37
+ assert_equal( 0.4, @args['-ar'] )
38
+ @args.parse('-ar 15')
39
+ assert_equal( 1.0, @args['-ar'] )
40
+ @args.parse('-ar -15')
41
+ assert_equal( 0.0, @args['-ar'] )
42
+ end
43
+
44
+ def test_w
45
+ @args.parse('-w 512')
46
+ assert_equal( 512, @args['-w'] )
47
+ @args.parse('-w 0')
48
+ assert_equal( nil, @args['-w'] )
49
+ end
50
+
51
+ def test_list
52
+ @args.parse('-list 2 4 8 16 24 64')
53
+ assert_equal( [2,4,8,16,24,64], @args['-list'] )
54
+ end
55
+
56
+ def test_parity_regex
57
+ @args.parse('-parity even')
58
+ assert_equal( 'even', @args['-parity'] )
59
+ @args.parse('-parity odd')
60
+ assert_equal( 'odd', @args['-parity'] )
61
+ @args.parse('-parity both')
62
+ assert_equal( 'both', @args['-parity'] )
63
+ end
64
+
65
+ def test_file_regex
66
+ @args.parse('-file something.EXT')
67
+ assert_equal( 'something.EXT', @args['-file'] )
68
+ @args.parse('-file something.ext')
69
+ assert_equal( nil, @args['-file'] )
70
+ end
71
+
72
+ def test_find_regex
73
+ @args.parse('-find hello')
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require "Getopt/Declare"
5
+
6
+ # to avoid getopt from exiting...
7
+ def exit(args)
8
+ end
9
+
10
+ $students = []
11
+ $absent = []
12
+
13
+ class TC_CSV < Test::Unit::TestCase
14
+
15
+
16
+ def setup
17
+ @args = Getopt::Declare.new(<<'EOCSV', :build)
18
+ <name:qs> , <id:+i> , <score:0+n> STD FORMAT [repeatable]
19
+ { $students.push( {:name=>name, :id=>id, :score=>score} ) }
20
+
21
+ <id:+i> , <name:qs> , <score:0+n> VARIANT FORMAT [repeatable]
22
+ { $students.push( {:name=>name, :id=>id, :score=>score} ) }
23
+
24
+ <name:qs> , <id:+i> , DNS DID NOT SIT [repeatable]
25
+ { $absent.push( {:name=>name, :id=>id, :score=>0} ) }
26
+
27
+ <other:/.+/> SOMETHING ELSE [repeatable]
28
+ { puts "Unknown entry format: #{other}" }
29
+ EOCSV
30
+ end
31
+
32
+ @@data = <<'EODATA'
33
+ absmith,1234567,20
34
+ "aesmith, the other one",7635656,DNS
35
+ cat,dog,22.2
36
+ 7637843,"dejones",66.7
37
+ rmwilliams,288721,88
38
+ help me,I'm trapped,in the marks system
39
+ vtthan,872829,94
40
+ EODATA
41
+
42
+ #'
43
+ def test_csv
44
+ @args.parse(@@data)
45
+
46
+ students = [
47
+ ["absmith",1234567,20],
48
+ ['"dejones"',7637843,66.7],
49
+ ["rmwilliams",288721,88],
50
+ ['vtthan',872829,94],
51
+ ]
52
+
53
+ assert_equal( students.size, $students.size )
54
+
55
+ $students.each_with_index { |i, idx|
56
+ assert_equal( students[idx][0], i[:name] )
57
+ assert_equal( students[idx][1], i[:id] )
58
+ assert_equal( students[idx][2], i[:score] )
59
+ }
60
+
61
+ absent = [
62
+ ['"aesmith, the other one"',7635656],
63
+ ]
64
+
65
+ assert_equal( absent.size, $absent.size )
66
+
67
+ $absent.each_with_index { |i, idx|
68
+ assert_equal( absent[idx][0], i[:name] )
69
+ assert_equal( absent[idx][1], i[:id] )
70
+ }
71
+ end
72
+
73
+
74
+ end
75
+
metadata CHANGED
@@ -3,24 +3,24 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: getopt-declare
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.23"
7
- date: 2007-03-21 00:00:00 -03:00
6
+ version: "1.25"
7
+ date: 2007-06-16 00:00:00 -03:00
8
8
  summary: Getopt-Declare is a command-line argument parser.
9
9
  require_paths:
10
10
  - lib
11
11
  email: ggarra@advancedsl.com.ar, GGarramuno@aol.com
12
- homepage: http://www.rubyforge.org/projects/getoptdeclare/
12
+ homepage: getoptdeclare.rubyforge.org
13
13
  rubyforge_project: getoptdeclare
14
14
  description: Comprehensive and easy to use command-line parser library using regular expressions. Port of Damian Conway's Perl Getopt-Declare.
15
- autorequire: Getopt/Declare
15
+ autorequire:
16
16
  default_executable:
17
17
  bindir: bin
18
18
  has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
- - - ">="
21
+ - - ">"
22
22
  - !ruby/object:Gem::Version
23
- version: 1.6.8
23
+ version: 0.0.0
24
24
  version:
25
25
  platform: ruby
26
26
  signing_key:
@@ -29,12 +29,15 @@ post_install_message:
29
29
  authors:
30
30
  - Gonzalo Garramuno
31
31
  files:
32
+ - lib
33
+ - lib/Getopt
32
34
  - lib/Getopt/Declare.rb
33
35
  - lib/Getopt/DelimScanner.rb
34
- - Rakefile
35
36
  - Declare.rdoc
36
37
  - HISTORY.txt
37
- test_files:
38
+ - README.txt
39
+ - Manifest.txt
40
+ - samples
38
41
  - samples/cmdline_basic.rb
39
42
  - samples/cmdline_mid.rb
40
43
  - samples/cmdline_parameters.rb
@@ -53,18 +56,51 @@ test_files:
53
56
  - samples/cmdline_singles.rb
54
57
  - samples/cmdline_inlines.rb
55
58
  - samples/cmdline_finish.rb
56
- rdoc_options: []
57
-
59
+ - Rakefile
60
+ - test
61
+ - test/test_cmdline_cmdline.rb
62
+ - test/test_cmdline_basic.rb
63
+ - test/test_cmdline_finish.rb
64
+ - test/test_cmdline_mid.rb
65
+ - test/test_cmdline_parameters.rb
66
+ - test/test_cmdline_pvtype2.rb
67
+ - test/test_cmdline_pvtype.rb
68
+ - test/test_cmdline_regex.rb
69
+ - test/test_demo_csv.rb
70
+ - test/test_cluster_singles.rb
71
+ - test/test_cmdline_array.rb
72
+ test_files:
73
+ - test/test_cmdline_cmdline.rb
74
+ - test/test_cmdline_basic.rb
75
+ - test/test_cmdline_finish.rb
76
+ - test/test_cmdline_mid.rb
77
+ - test/test_cmdline_parameters.rb
78
+ - test/test_cmdline_pvtype2.rb
79
+ - test/test_cmdline_pvtype.rb
80
+ - test/test_cmdline_regex.rb
81
+ - test/test_demo_csv.rb
82
+ - test/test_cluster_singles.rb
83
+ - test/test_cmdline_array.rb
84
+ rdoc_options:
85
+ - --main
86
+ - README.txt
58
87
  extra_rdoc_files:
59
- - Declare.rdoc
60
88
  - HISTORY.txt
61
- - lib/Getopt/Declare.rb
62
- - lib/Getopt/DelimScanner.rb
89
+ - README.txt
90
+ - Manifest.txt
63
91
  executables: []
64
92
 
65
93
  extensions: []
66
94
 
67
95
  requirements: []
68
96
 
69
- dependencies: []
70
-
97
+ dependencies:
98
+ - !ruby/object:Gem::Dependency
99
+ name: hoe
100
+ version_requirement:
101
+ version_requirements: !ruby/object:Gem::Version::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: 1.2.1
106
+ version: