docopt 0.0.1 → 0.0.2

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 (6) hide show
  1. data/LICENSE-MIT +19 -0
  2. data/README.md +36 -22
  3. data/example.rb +30 -0
  4. data/lib/docopt.rb +101 -0
  5. metadata +15 -9
  6. data/docopt.rb +0 -116
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012 Vladimir Keleshev <vladimir@keleshev.com>, Alex Speller <alex@alexspeller.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md CHANGED
@@ -41,21 +41,21 @@ require 'docopt'
41
41
 
42
42
 
43
43
  if __FILE__ == $0
44
- options = docopt(doc, '1.0.0') # parse options based on doc above
44
+ options = Docopt(doc, '1.0.0') # parse options based on doc above
45
45
  puts options.inspect
46
46
  puts ARGV.inspect
47
47
  end
48
48
  ```
49
49
 
50
50
  Hell yeah! The option parser is generated based on `doc` string above, that you
51
- pass to the `docopt` function.
51
+ pass to the `Docopt` function.
52
52
 
53
53
  API `require 'docopt'`
54
54
  ===============================================================================
55
55
 
56
- ###`options = docopt(doc, version=nil, help=true)`
56
+ ###`options = Docopt(doc, version=nil, help=true)`
57
57
 
58
- `docopt` takes 1 required and 2 optional arguments:
58
+ `Docopt` takes 1 required and 2 optional arguments:
59
59
 
60
60
  - `doc` should be a string that
61
61
  describes **options** in a human-readable format, that will be parsed to create
@@ -86,24 +86,38 @@ Note, when `docopt` is set to automatically handle `-h`, `--help` and
86
86
  `--version` options, you still need to mention them in the options description
87
87
  (`doc`) for your users to know about them.
88
88
 
89
- The **return** value is a hash with option values
90
- (giving long options precedence), e.g:
91
-
92
- {"--benchmark"=>true,
93
- "--count"=>true,
94
- "--doctest"=>false,
95
- "--exclude"=>".svn,CVS,.bzr,.hg,.git",
96
- "--filename"=>"*.rb",
97
- "--help"=>false,
98
- "--ignore"=>false,
99
- "--quiet"=>false,
100
- "--repeat"=>false,
101
- "--select"=>"*.rb",
102
- "--show-source"=>true,
103
- "--statistics"=>true,
104
- "--testsuite"=>false,
105
- "--verbose"=>true,
106
- "--version"=>false}
89
+ The **return** value is an instance of the ```Docopt``` class:
90
+
91
+ ```ruby
92
+ doc = "Options:
93
+ --verbose
94
+ -o FILE Output file [default: out.txt]"
95
+
96
+ options = Docopt(doc)
97
+
98
+ puts options.inspect
99
+ # --verbose=nil
100
+ # -o="out.txt"
101
+ ```
102
+
103
+ You can access the values of options like a hash:
104
+
105
+ ```
106
+ doc = "Options:
107
+ -v, --verbose Verbose output [default: true]
108
+ -o FILE Output file [default: out.txt]"
109
+
110
+ options = Docopt(doc)
111
+
112
+ # The following are equivilant:
113
+
114
+ puts options['-v']
115
+ puts options['--verbose']
116
+ puts options[:v]
117
+ puts options[:verbose]
118
+
119
+
120
+ ```
107
121
 
108
122
  You can access positional arguments in `ARGV`.
109
123
 
@@ -0,0 +1,30 @@
1
+ $DOC = "Usage: example.py [options] <arguments>...
2
+
3
+ Options:
4
+ -h --help show this help message and exit
5
+ --version show version and exit
6
+ -v --verbose print status messages
7
+ -q --quiet report only file names
8
+ -r --repeat show all occurrences of the same error
9
+ --exclude=patterns exclude files or directories which match these comma
10
+ separated patterns [default: .svn,CVS,.bzr,.hg,.git]
11
+ --filename=patterns when parsing directories, only check filenames matching
12
+ these comma separated patterns [default: *.rb]
13
+ --select=errors select errors and warnings (e.g. E,W6)
14
+ --ignore=errors skip errors and warnings (e.g. E4,W)
15
+ --show-source show source code for each error
16
+ --statistics count errors and warnings
17
+ --count print total number of errors and warnings to standard
18
+ error and set exit code to 1 if total is not null
19
+ --benchmark measure processing speed
20
+ --testsuite=dir run regression tests from dir
21
+ --doctest run doctest on myself"
22
+
23
+ require 'docopt'
24
+
25
+
26
+ if __FILE__ == $0
27
+ options = Docopt($DOC, '1.0.0') # parse options based on doc above
28
+ puts options.inspect
29
+ puts ARGV.inspect
30
+ end
@@ -0,0 +1,101 @@
1
+ require 'getoptlong'
2
+
3
+ class Docopt
4
+ attr_reader :docopts
5
+
6
+ class UnknownOptionError < StandardError; end
7
+
8
+ class Option
9
+ attr_reader :short, :long, :argcount, :value
10
+
11
+ def initialize parse
12
+ @argcount = 0
13
+ options, _, description = parse.strip.partition(' ')
14
+ options = options.sub(',', ' ').sub('=', ' ')
15
+
16
+ for s in options.split
17
+ if s.start_with? '--'
18
+ @long = s
19
+ elsif s.start_with? '-'
20
+ @short = s
21
+ else
22
+ @argcount = 1
23
+ end
24
+ end
25
+
26
+ if @argcount == 1
27
+ matched = description.scan(/\[default: (.*)\]/)[0]
28
+ @value = matched ? matched[0] : nil
29
+ end
30
+ end
31
+
32
+ def synonyms
33
+ ([short, long] + symbols).compact
34
+ end
35
+
36
+ def symbols
37
+ [short, long].compact.map do |name|
38
+ name.gsub(/^-+/, '').to_sym
39
+ end
40
+ end
41
+
42
+ def getopt
43
+ [long, short, argcount].compact
44
+ end
45
+
46
+ def inspect
47
+ "#<Docopt::Option short: #{short}, long: #{long}, argcount: #{argcount}, value: #{value}>"
48
+ end
49
+
50
+ def == other
51
+ self.inspect == other.inspect
52
+ end
53
+ end
54
+
55
+
56
+ def initialize(doc, version=nil, help=true)
57
+ @docopts = doc.split(/^ *-|\n *-/)[1..-1].map do |line|
58
+ Option.new('-' + line)
59
+ end
60
+
61
+ GetoptLong.new(*docopts.map(&:getopt)).each do |opt, arg|
62
+ if help and (opt == '--help' or opt == '-h')
63
+ puts doc.strip
64
+ exit
65
+ elsif version and opt == '--version'
66
+ puts version
67
+ exit
68
+ end
69
+ end
70
+ end
71
+
72
+ def option name
73
+ option = @docopts.detect do |docopt|
74
+ docopt.synonyms.include?(name)
75
+ end
76
+ raise UnknownOptionError.new("#{name} option not found") unless option
77
+ option
78
+ end
79
+
80
+
81
+
82
+ def value name
83
+ option(name).value
84
+ end
85
+ alias_method :[], :value
86
+
87
+ def size
88
+ @docopts.size
89
+ end
90
+
91
+ def inspect
92
+ @docopts.map do |option|
93
+ "#{option.short} #{option.long}=#{option.value.inspect}".strip
94
+ end.join("\n")
95
+ end
96
+ end
97
+
98
+ # Convenience method for Docopt.parse
99
+ def Docopt *args
100
+ Docopt.new *args
101
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docopt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,18 +10,24 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-03 00:00:00.000000000 Z
13
+ date: 2012-06-05 00:00:00.000000000 Z
14
14
  dependencies: []
15
- description: A command line option parser, that will make you smile.
16
- email:
15
+ description: A command line option parser, that will make you smile. Isn't it awesome
16
+ how `optparse` and other option parsers generate help and usage-messages based on
17
+ your code?! Hell no! You know what's awesome? It's when the option parser *is*
18
+ generated based on the help and usage-message that you write in a docstring!
19
+ email: alex@alexspeller.com
17
20
  executables: []
18
21
  extensions: []
19
22
  extra_rdoc_files: []
20
23
  files:
21
24
  - README.md
22
- - docopt.rb
23
- homepage: http://github.com/alexspeller/docopt.rb
24
- licenses: []
25
+ - LICENSE-MIT
26
+ - example.rb
27
+ - lib/docopt.rb
28
+ homepage: http://github.com/alexspeller/docopt
29
+ licenses:
30
+ - MIT
25
31
  post_install_message:
26
32
  rdoc_options: []
27
33
  require_paths:
@@ -31,13 +37,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
31
37
  requirements:
32
38
  - - ! '>='
33
39
  - !ruby/object:Gem::Version
34
- version: '0'
40
+ version: 1.9.2
35
41
  required_rubygems_version: !ruby/object:Gem::Requirement
36
42
  none: false
37
43
  requirements:
38
44
  - - ! '>='
39
45
  - !ruby/object:Gem::Version
40
- version: '0'
46
+ version: 1.8.11
41
47
  requirements: []
42
48
  rubyforge_project:
43
49
  rubygems_version: 1.8.23
data/docopt.rb DELETED
@@ -1,116 +0,0 @@
1
- require 'getoptlong'
2
-
3
-
4
- class Option
5
-
6
- attr_reader :short, :long, :argcount, :value
7
-
8
- def initialize(short=nil, long=nil, argcount=0, value=false)
9
- @short, @long, @argcount, @value = short, long, argcount, value
10
- end
11
-
12
- def getopt
13
- [@long, @short, @argcount].compact
14
- end
15
-
16
- def inspect
17
- "Option.new(#{@short}, #{@long}, #{@argcount}, #{@value})"
18
- end
19
-
20
- def == other
21
- self.inspect == other.inspect
22
- end
23
-
24
- end
25
-
26
-
27
- def option parse
28
- options, _, description = parse.strip.partition(' ')
29
- options = options.sub(',', ' ').sub('=', ' ')
30
- short, long, argcount, value = nil, nil, 0, false
31
- for s in options.split
32
- if s.start_with? '--'
33
- long = s
34
- elsif s.start_with? '-'
35
- short = s
36
- else
37
- argcount = 1
38
- end
39
- end
40
- if argcount == 1
41
- matched = description.scan(/\[default: (.*)\]/)[0]
42
- value = matched ? matched[0] : false
43
- end
44
- Option.new(short, long, argcount, value)
45
- end
46
-
47
-
48
- class MyHash < Hash
49
- def inspect
50
- "{#{self.to_a.sort.map {|i| "%p=>%p" % i}.join(",\n ")}}"
51
- end
52
- end
53
-
54
-
55
- def docopt(doc, version=nil, help=true)
56
- ret = MyHash.new
57
- docopts = []
58
- doc.split(/^ *-|\n *-/)[1..-1].each do |s|
59
- docopt = option('-' + s)
60
- docopts += [docopt]
61
- ret[(docopt.long or docopt.short)] = docopt.value
62
- end
63
- begin
64
- GetoptLong.new(*docopts.map {|e| e.getopt}).each do |opt, arg|
65
- if help and (opt == '--help' or opt == '-h')
66
- puts doc.strip
67
- exit
68
- elsif version and opt == '--version'
69
- puts version
70
- exit
71
- elsif (docopts.select {|d|(d.long or d.short)==opt})[0].argcount==0
72
- ret[opt] = true
73
- else
74
- ret[opt] = arg
75
- end
76
- end
77
- rescue
78
- exit 1
79
- end
80
- ret
81
- end
82
-
83
-
84
- if __FILE__ == $0
85
-
86
- def assert cond
87
- print cond ? '.' : 'F'
88
- end
89
-
90
- assert option('-h') == Option.new('-h', nil)
91
- assert option('--help') == Option.new(nil, '--help')
92
- assert option('-h --help') == Option.new('-h', '--help')
93
- assert option('-h, --help') == Option.new('-h', '--help')
94
-
95
- assert option('-h TOPIC') == Option.new('-h', nil, 1)
96
- assert option('--help TOPIC') == Option.new(nil, '--help', 1)
97
- assert option('-h TOPIC --help TOPIC') == Option.new('-h', '--help', 1)
98
- assert option('-h TOPIC, --help TOPIC') == Option.new('-h', '--help', 1)
99
- assert option('-h TOPIC, --help=TOPIC') == Option.new('-h', '--help', 1)
100
-
101
- assert option('-h Description...') == Option.new('-h', nil)
102
- assert option('-h --help Description...') == Option.new('-h', '--help')
103
- assert option('-h TOPIC Description...') == Option.new('-h', nil, 1)
104
-
105
- assert option(' -h') == Option.new('-h', nil)
106
-
107
- assert option('-h TOPIC Descripton... [default: 2]') ==
108
- Option.new('-h', nil, 1, '2')
109
- assert option('-h TOPIC Descripton... [default: topic-1]') ==
110
- Option.new('-h', nil, 1, 'topic-1')
111
- assert option('--help=TOPIC ... [default: 3.14]') ==
112
- Option.new(nil, '--help', 1, '3.14')
113
- assert option('-h, --help=DIR ... [default: ./]') ==
114
- Option.new('-h', '--help', 1, "./")
115
-
116
- end