cooloptions 0.1.0 → 1.0.0
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.
- 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:
|