cooloptions 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.txt +49 -11
- data/Rakefile +1 -1
- data/lib/cooloptions.rb +69 -42
- data/test/test_cooloptions.rb +41 -10
- metadata +3 -3
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -8,26 +8,64 @@ CoolOptions is a simple wrapper around optparse that provides less options and m
|
|
8
8
|
|
9
9
|
== SYNOPSYS:
|
10
10
|
|
11
|
+
=== Declaration:
|
12
|
+
|
11
13
|
options = CoolOptions.parse!("[options] PROJECTNAME") do |o|
|
12
|
-
o.on
|
13
|
-
o.on
|
14
|
-
o.on
|
15
|
-
o.on
|
16
|
-
o.on
|
17
|
-
o.on
|
18
|
-
o.on
|
19
|
-
o.on
|
20
|
-
|
14
|
+
o.on "repository URL", "Remote subversion repository."
|
15
|
+
o.on "svk", "Use svk.", true
|
16
|
+
o.on "project-path PATH", "Root of project workspaces.", File.expand_path("~/svk")
|
17
|
+
o.on "l)repository-path PATH", "Remote repository path.", "/"
|
18
|
+
o.on "mirror-path SVKPATH", "SVK mirror path.", "//"
|
19
|
+
o.on "local-pa(t)h SVKPATH", "SVK local path.", "//local"
|
20
|
+
o.on "create-structure", "Create trunk/tags/branches structure.", true
|
21
|
+
o.on "finish", "Prep and commit the new project.", true
|
22
|
+
|
21
23
|
o.after do |r|
|
22
24
|
r.project_path = File.expand_path(r.project_path)
|
23
|
-
|
25
|
+
o.error("Invalid path.") unless File.exist?(r.project_path)
|
24
26
|
r.project_name = ARGV.shift
|
27
|
+
o.error("Project name is required.") unless r.project_name
|
28
|
+
o.error("Project name is too funky.") unless /^\w+$/ =~ r.project_name
|
25
29
|
end
|
26
30
|
end
|
31
|
+
|
32
|
+
=== Usage:
|
33
|
+
|
34
|
+
$ ./new_rails_project --no-svk -r http://terralien.com/svn/terralien/ --no-finish
|
35
|
+
|
36
|
+
=== Result:
|
37
|
+
|
38
|
+
p options.svk # => false
|
39
|
+
p options.project_path # => '/Users/ntalbott/svk'
|
40
|
+
p options.repository # => 'http://terralien.com/svn/terralien/'
|
41
|
+
p options.finish # => false
|
42
|
+
p options.create_structure # => true
|
43
|
+
p options.project_name # => 'myproject'
|
44
|
+
|
45
|
+
=== Also:
|
46
|
+
|
47
|
+
$ ./new_rails_project --help
|
48
|
+
Usage: t.rb [options] PROJECTNAME
|
49
|
+
-s, --[no-]svk Use svk.
|
50
|
+
Default is: true
|
51
|
+
-p, --project-path PATH Root of project workspaces.
|
52
|
+
Default is: /Users/ntalbott/svk
|
53
|
+
-r, --repository URL Remote subversion repository.
|
54
|
+
-l, --repository-path PATH Remote repository path.
|
55
|
+
Default is: /
|
56
|
+
-m, --mirror-path SVKPATH SVK mirror path.
|
57
|
+
Default is: //
|
58
|
+
-t, --local-path SVKPATH SVK local path.
|
59
|
+
Default is: //local
|
60
|
+
-c, --[no-]create-structure Create trunk/tags/branches structure.
|
61
|
+
Default is: true
|
62
|
+
-f, --[no-]finish Prep and commit the new project.
|
63
|
+
Default is: true
|
64
|
+
-h, --help This help info.
|
27
65
|
|
28
66
|
== REQUIREMENTS:
|
29
67
|
|
30
|
-
optparse (included in Ruby
|
68
|
+
optparse & ostruct (included in Ruby standard library).
|
31
69
|
|
32
70
|
== INSTALL:
|
33
71
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require './lib/cooloptions.rb'
|
|
5
5
|
Hoe.new('cooloptions', CoolOptions::VERSION) do |p|
|
6
6
|
p.rubyforge_name = 'cooloptions'
|
7
7
|
p.summary = p.description = 'CoolOptions is a simple wrapper around optparse that provides less options and more convenience.'
|
8
|
-
p.url = '
|
8
|
+
p.url = 'http://cooloptions.rubyforge.org/'
|
9
9
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
10
10
|
p.author = "Nathaniel Talbott"
|
11
11
|
p.email = "nathaniel@terralien.com"
|
data/lib/cooloptions.rb
CHANGED
@@ -1,19 +1,30 @@
|
|
1
|
-
# Copyright (c) 2006 Nathaniel Talbott and Terralien, Inc. All Rights Reserved.
|
2
|
-
# Licensed under the RUBY license.
|
1
|
+
# Copyright:: Copyright (c) 2006 Nathaniel Talbott and Terralien, Inc. All Rights Reserved.
|
2
|
+
# License:: Licensed under the RUBY license.
|
3
3
|
|
4
4
|
require 'optparse'
|
5
5
|
require 'ostruct'
|
6
6
|
|
7
|
+
# For a high-level overview of using CoolOptions, see README.txt.
|
8
|
+
#
|
9
|
+
# == Usage
|
10
|
+
#
|
11
|
+
# :include:samples/literate.rb
|
12
|
+
|
7
13
|
class CoolOptions
|
8
|
-
VERSION = '
|
14
|
+
VERSION = '1.0.0' #:nodoc:
|
9
15
|
|
10
16
|
class Error < StandardError #:nodoc:
|
11
17
|
end
|
12
18
|
|
13
|
-
|
14
|
-
|
19
|
+
# Takes an optional banner and the arguments you want to parse (defaults to
|
20
|
+
# ARGV) and yields a new CoolOptions to the supplied block. You can then
|
21
|
+
# declare your options in the block using the #on method, and do post-
|
22
|
+
# processing using #after. When processing is done, an OpenStruct
|
23
|
+
# containing the parsed options is returned.
|
24
|
+
def self.parse!(banner="[options]", argv=ARGV) #:yields: cooloptions
|
25
|
+
o = new(banner)
|
15
26
|
yield o
|
16
|
-
o.parse!(
|
27
|
+
o.parse!(argv)
|
17
28
|
rescue Error => e
|
18
29
|
out.puts e.message
|
19
30
|
o.help true
|
@@ -31,59 +42,75 @@ class CoolOptions
|
|
31
42
|
@out = out
|
32
43
|
end
|
33
44
|
|
34
|
-
|
35
|
-
|
45
|
+
attr_reader :parser, :result
|
46
|
+
|
47
|
+
def initialize(banner) #:nodoc:
|
48
|
+
@parser = OptionParser.new
|
49
|
+
@parser.banner = "Usage: #{File.basename($0)} #{banner}"
|
50
|
+
|
51
|
+
@required = []
|
52
|
+
@result = {}
|
36
53
|
@after = nil
|
37
54
|
end
|
38
55
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
56
|
+
NO_DEFAULT = Object.new #:nodoc:
|
57
|
+
|
58
|
+
# Called on cooloptions within the #parse! block to add options to parse on.
|
59
|
+
# Long is the long option itself, description is, well, the description, and
|
60
|
+
# default is the default value for the option, if any.
|
61
|
+
def on(long, description, default=NO_DEFAULT)
|
62
|
+
if /^(.)\)(.+)$/ =~ long
|
63
|
+
short, long = $1, $2
|
64
|
+
elsif /^(.*)\((.)\)(.*)$/ =~ long
|
65
|
+
short = $2
|
66
|
+
long = $1 + $2 + $3
|
46
67
|
end
|
47
|
-
|
68
|
+
short = long[0,1] unless short
|
69
|
+
|
70
|
+
key = long.split(/ /).first.gsub('-', '_').to_sym
|
71
|
+
|
72
|
+
unless long =~ / /
|
73
|
+
long = "[no-]#{long}"
|
74
|
+
end
|
75
|
+
|
76
|
+
args = ["-#{short}", "--#{long}", description]
|
77
|
+
if default == NO_DEFAULT
|
78
|
+
@required << key
|
79
|
+
else
|
80
|
+
@result[key] = default
|
81
|
+
args << "Default is: #{default}"
|
82
|
+
end
|
83
|
+
|
84
|
+
@parser.on(*args){|e| self.result[key] = e}
|
48
85
|
end
|
49
86
|
|
50
|
-
def parse!(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
87
|
+
def parse!(argv) #:nodoc:
|
88
|
+
@parser.on('-h', '--help', "This help info."){help}
|
89
|
+
@parser.parse!(argv)
|
90
|
+
|
91
|
+
@required.reject!{|e| @result.key?(e)}
|
92
|
+
error "Missing required options: #{@required.join(', ')}" unless @required.empty?
|
56
93
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
required << key
|
61
|
-
else
|
62
|
-
result[key] = default
|
63
|
-
args << "Default is: #{default}"
|
64
|
-
end
|
65
|
-
o.on(*args){|e| result[key] = e}
|
66
|
-
end
|
67
|
-
|
68
|
-
o.on('-h', '--help', "This help info."){help}
|
69
|
-
end.parse!(argv)
|
70
|
-
required.reject!{|e| result.key?(e)}
|
71
|
-
error "Missing required options: #{required.join(', ')}" unless required.empty?
|
72
|
-
result = OpenStruct.new(result)
|
73
|
-
@after.call(result) if @after
|
74
|
-
result
|
94
|
+
r = OpenStruct.new(@result)
|
95
|
+
@after.call(r) if @after
|
96
|
+
r
|
75
97
|
end
|
76
98
|
|
99
|
+
# If you want to throw an option parsing error, just call #error with a
|
100
|
+
# message and CoolOptions will bail out and display the help message.
|
77
101
|
def error(message)
|
78
102
|
raise Error, message, caller
|
79
103
|
end
|
80
104
|
|
105
|
+
# CoolOptions only handles options parsing, and it only does rudimentary
|
106
|
+
# option validation. If you want to do more, #after is a convenient place do
|
107
|
+
# it, especially since the right thing will just happen if you call #error.
|
81
108
|
def after(&after)
|
82
109
|
@after = after
|
83
110
|
end
|
84
111
|
|
85
|
-
def help(error=false)
|
86
|
-
out.puts @
|
112
|
+
def help(error=false) #:nodoc:
|
113
|
+
out.puts @parser
|
87
114
|
exit(error ? 1 : 0)
|
88
115
|
end
|
89
116
|
end
|
data/test/test_cooloptions.rb
CHANGED
@@ -20,10 +20,10 @@ class TestCoolOptions < Test::Unit::TestCase
|
|
20
20
|
|
21
21
|
def test_should_handle_booleans
|
22
22
|
r = parse!(%w(-a --no-b --c)) do |o|
|
23
|
-
o.on
|
24
|
-
o.on
|
25
|
-
o.on
|
26
|
-
o.on
|
23
|
+
o.on 'a', 'a', false
|
24
|
+
o.on 'b', 'b', true
|
25
|
+
o.on 'c', 'c', false
|
26
|
+
o.on 'd', 'd', true
|
27
27
|
end
|
28
28
|
|
29
29
|
assert r.a
|
@@ -34,8 +34,8 @@ class TestCoolOptions < Test::Unit::TestCase
|
|
34
34
|
|
35
35
|
def test_should_handle_strings
|
36
36
|
r = parse!(%w(-a b --c=d)) do |o|
|
37
|
-
o.on
|
38
|
-
o.on
|
37
|
+
o.on 'a ARG', 'a'
|
38
|
+
o.on 'c ARG', 'c'
|
39
39
|
end
|
40
40
|
|
41
41
|
assert_equal 'b', r.a
|
@@ -44,7 +44,7 @@ class TestCoolOptions < Test::Unit::TestCase
|
|
44
44
|
|
45
45
|
def test_should_ignore_non_options
|
46
46
|
r = CoolOptions.parse!('', argv=%w(ab -c de)) do |o|
|
47
|
-
o.on
|
47
|
+
o.on 'c', 'c'
|
48
48
|
end
|
49
49
|
|
50
50
|
assert r.c
|
@@ -54,7 +54,7 @@ class TestCoolOptions < Test::Unit::TestCase
|
|
54
54
|
def test_should_call_after
|
55
55
|
called = false
|
56
56
|
r = parse!(%w(-a)) do |o|
|
57
|
-
o.on
|
57
|
+
o.on 'a', 'a'
|
58
58
|
o.after{|r| assert r.a; called=true}
|
59
59
|
end
|
60
60
|
assert called
|
@@ -71,7 +71,7 @@ class TestCoolOptions < Test::Unit::TestCase
|
|
71
71
|
def test_should_output_help
|
72
72
|
begin
|
73
73
|
r = CoolOptions.parse!('details', %w(--help)) do |o|
|
74
|
-
o.on
|
74
|
+
o.on 'a', 'aa'
|
75
75
|
end
|
76
76
|
rescue SystemExit
|
77
77
|
rescued = true
|
@@ -88,8 +88,39 @@ EOH
|
|
88
88
|
def test_should_require_options_with_no_default
|
89
89
|
assert_raise(SystemExit) do
|
90
90
|
CoolOptions.parse!([]) do |o|
|
91
|
-
o.on
|
91
|
+
o.on 'a A', 'a'
|
92
92
|
end
|
93
93
|
end
|
94
|
+
assert_nothing_raised do
|
95
|
+
CoolOptions.parse!([]) do |o|
|
96
|
+
o.on 'a A', 'a', nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_should_allow_specification_of_alternate_short_form
|
102
|
+
r = parse!(%w(-a -b c -c d)) do |o|
|
103
|
+
o.on 'a', 'a', false
|
104
|
+
o.on 'b)aa VALUE', 'aa'
|
105
|
+
o.on 'b(c) VALUE', 'bc'
|
106
|
+
end
|
107
|
+
assert_equal true, r.a
|
108
|
+
assert_equal 'c', r.aa
|
109
|
+
assert_equal 'd', r.bc
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_should_replace_dashes
|
113
|
+
r = parse!(%w(--a-b c)) do |o|
|
114
|
+
o.on 'a-b A', 'a'
|
115
|
+
end
|
116
|
+
assert_equal 'c', r.a_b
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_should_provide_access_to_the_parser
|
120
|
+
called = false
|
121
|
+
r = parse!(%w(-d)) do |o|
|
122
|
+
o.parser.on('-d'){called = true}
|
123
|
+
end
|
124
|
+
assert called
|
94
125
|
end
|
95
126
|
end
|
metadata
CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: cooloptions
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
7
|
-
date: 2006-12-
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2006-12-09 00:00:00 -05:00
|
8
8
|
summary: CoolOptions is a simple wrapper around optparse that provides less options and more convenience.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: nathaniel@terralien.com
|
12
|
-
homepage:
|
12
|
+
homepage: http://cooloptions.rubyforge.org/
|
13
13
|
rubyforge_project: cooloptions
|
14
14
|
description: CoolOptions is a simple wrapper around optparse that provides less options and more convenience.
|
15
15
|
autorequire:
|