docopt 0.0.1 → 0.0.2

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