acclaim 0.0.3 → 0.0.4
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/Rakefile +2 -43
- data/acclaim.gemspec +1 -0
- data/lib/acclaim/command.rb +37 -26
- data/lib/acclaim/option.rb +15 -6
- data/lib/acclaim/option/parser.rb +47 -29
- data/lib/acclaim/option/type.rb +55 -0
- data/lib/acclaim/option/type/date.rb +21 -0
- data/lib/acclaim/option/type/date_time.rb +21 -0
- data/lib/acclaim/option/type/string.rb +21 -0
- data/lib/acclaim/option/type/time.rb +21 -0
- data/lib/acclaim/option/type/uri.rb +21 -0
- data/lib/acclaim/version.rb +1 -1
- metadata +21 -4
data/Rakefile
CHANGED
@@ -1,44 +1,3 @@
|
|
1
|
-
|
2
|
-
gem_dir = File.join this_dir, 'gem'
|
3
|
-
spec_file = File.join this_dir, 'acclaim.gemspec'
|
1
|
+
require 'rookie'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
task :mkdir do
|
8
|
-
FileUtils.mkdir_p gem_dir
|
9
|
-
end
|
10
|
-
|
11
|
-
task :gem => :mkdir do
|
12
|
-
gem_file = File.join this_dir, Gem::Builder.new(spec).build
|
13
|
-
FileUtils.mv gem_file, gem_dir
|
14
|
-
end
|
15
|
-
|
16
|
-
namespace :gem do
|
17
|
-
|
18
|
-
task :build => :gem
|
19
|
-
|
20
|
-
gem_file = File.join gem_dir, "#{spec.name}-#{spec.version}.gem"
|
21
|
-
|
22
|
-
task :push => :gem do
|
23
|
-
sh "gem push #{gem_file}"
|
24
|
-
end
|
25
|
-
|
26
|
-
task :install => :gem do
|
27
|
-
sh "gem install #{gem_file}"
|
28
|
-
end
|
29
|
-
|
30
|
-
task :uninstall do
|
31
|
-
sh "gem uninstall #{spec.name}"
|
32
|
-
end
|
33
|
-
|
34
|
-
task :clean do
|
35
|
-
FileUtils.rm_rf gem_dir
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
task :clean => 'gem:clean'
|
41
|
-
|
42
|
-
task :setup => [ 'gem:install', :clean ]
|
43
|
-
|
44
|
-
task :default => :setup
|
3
|
+
Rookie::Tasks.new 'acclaim.gemspec'
|
data/acclaim.gemspec
CHANGED
data/lib/acclaim/command.rb
CHANGED
@@ -64,25 +64,27 @@ module Acclaim
|
|
64
64
|
end
|
65
65
|
|
66
66
|
# Adds an option to this command.
|
67
|
-
def option(*args)
|
68
|
-
options << Option.new(*args)
|
67
|
+
def option(*args, &block)
|
68
|
+
options << Option.new(*args, &block)
|
69
69
|
end
|
70
70
|
|
71
71
|
alias :opt :option
|
72
72
|
|
73
73
|
# The block which is executed when this command is called. It is given 2
|
74
|
-
# parameters; the first is an
|
75
|
-
# settings information; the second is the remaining command line.
|
74
|
+
# parameters; the first is an Option::Values instance which can be queried
|
75
|
+
# for settings information; the second is the remaining command line.
|
76
76
|
def action(&block)
|
77
77
|
@action = block
|
78
78
|
end
|
79
79
|
|
80
80
|
alias :when_called :action
|
81
81
|
|
82
|
+
# Adds help subcommand and options to this command.
|
82
83
|
def help(opts = {})
|
83
84
|
subcommands << Help.create(self, opts)
|
84
85
|
end
|
85
86
|
|
87
|
+
# Adds help subcommand and options to this command.
|
86
88
|
def version(version_string, opts = {})
|
87
89
|
subcommands << Version.create(self, version_string, opts)
|
88
90
|
end
|
@@ -92,50 +94,43 @@ module Acclaim
|
|
92
94
|
Option::Parser.new(args, options).parse!
|
93
95
|
end
|
94
96
|
|
95
|
-
# Invokes this command with a fresh set of
|
97
|
+
# Invokes this command with a fresh set of option values.
|
96
98
|
def run(*args)
|
97
99
|
invoke Option::Values.new, args
|
98
100
|
rescue Option::Parser::Error => e
|
99
101
|
puts e.message
|
100
102
|
end
|
101
103
|
|
102
|
-
# Parses the argument array.
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
104
|
+
# Parses the argument array. The argument array will be searched for
|
105
|
+
# subcommands; if one is found, it will be invoked, if not, this command
|
106
|
+
# will be executed. A subcommand may be anywhere in the array as long as
|
107
|
+
# it is before an argument separator, which is tipically a double dash
|
108
|
+
# (<tt>--<\tt>) and may be omitted.
|
106
109
|
def invoke(opts, args = [])
|
107
110
|
opts.merge! parse_options!(args)
|
108
111
|
handle_special_options! opts, args
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
index = args.index subcommand.line
|
115
|
-
# If we have the subcommand AND the separator, then we have it if the
|
116
|
-
# subcommand is before the separator.
|
117
|
-
index and (not separator_index or index < separator_index)
|
118
|
-
end.tap do |subcommand|
|
119
|
-
if subcommand
|
120
|
-
args.delete subcommand.line
|
121
|
-
subcommand.invoke(opts, args)
|
122
|
-
else
|
123
|
-
execute(opts, args)
|
124
|
-
end
|
112
|
+
if subcommand = find_subcommand_in(separated args)
|
113
|
+
args.delete subcommand.line
|
114
|
+
subcommand.invoke(opts, args)
|
115
|
+
else
|
116
|
+
execute(opts, args)
|
125
117
|
end
|
126
118
|
end
|
127
119
|
|
128
|
-
# Calls this command's action block with the given
|
120
|
+
# Calls this command's action block with the given option values and
|
121
|
+
# arguments.
|
129
122
|
def execute(opts, args)
|
130
123
|
@action.call opts, args
|
131
124
|
end
|
132
125
|
|
133
126
|
alias :call :execute
|
134
127
|
|
128
|
+
# True if this is a top-level command.
|
135
129
|
def root?
|
136
130
|
superclass == Acclaim::Command
|
137
131
|
end
|
138
132
|
|
133
|
+
# Finds the root of the command hierarchy.
|
139
134
|
def root
|
140
135
|
command = self
|
141
136
|
command = command.superclass until command.root?
|
@@ -150,6 +145,22 @@ module Acclaim
|
|
150
145
|
const_get(:Version).execute opts, args if opts.acclaim_version?
|
151
146
|
end
|
152
147
|
|
148
|
+
# Attempts to find a subcommand of this command in the given argument
|
149
|
+
# array. If a subcommand is found, it is returned, if not, nil is
|
150
|
+
# returned.
|
151
|
+
def find_subcommand_in(args)
|
152
|
+
subcommands.find do |subcommand|
|
153
|
+
args.include? subcommand.line
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Finds the argument separator and returns an array containing all the
|
158
|
+
# elements before it. If a separator is not present, the original array
|
159
|
+
# is returned.
|
160
|
+
def separated(args)
|
161
|
+
args.take_while { |arg| arg !~ Option::Parser::Regexp::ARGUMENT_SEPARATOR }
|
162
|
+
end
|
163
|
+
|
153
164
|
end
|
154
165
|
|
155
166
|
# Add the class methods to the subclass and add it to this command's list of
|
data/lib/acclaim/option.rb
CHANGED
@@ -1,23 +1,32 @@
|
|
1
1
|
require 'acclaim/option/arity'
|
2
2
|
require 'acclaim/option/parser/regexp'
|
3
|
+
require 'acclaim/option/type'
|
3
4
|
|
4
5
|
module Acclaim
|
5
6
|
|
6
7
|
# Represents a command-line option.
|
7
8
|
class Option
|
8
9
|
|
9
|
-
attr_accessor :key, :names, :description, :type, :default
|
10
|
+
attr_accessor :key, :names, :description, :type, :default, :handler
|
10
11
|
|
11
|
-
def initialize(key, *args)
|
12
|
+
def initialize(key, *args, &block)
|
12
13
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
14
|
+
matches = args.select { |arg| arg.is_a? String }.group_by do |arg|
|
15
|
+
arg =~ Parser::Regexp::SWITCH ? true : false
|
16
|
+
end
|
17
|
+
klass = args.find { |arg| arg.is_a? Class }
|
13
18
|
self.key = key
|
14
|
-
self.names =
|
15
|
-
self.description =
|
16
|
-
self.type = args.find { |arg| arg.is_a? Class }
|
19
|
+
self.names = matches.fetch true, []
|
20
|
+
self.description = matches.fetch(false, []).first
|
17
21
|
self.arity = options[:arity]
|
18
22
|
self.default = options[:default]
|
19
23
|
self.required = options[:required]
|
20
|
-
|
24
|
+
self.type = klass || String
|
25
|
+
self.handler = block
|
26
|
+
end
|
27
|
+
|
28
|
+
def convert_parameters(*args)
|
29
|
+
args.map { |arg| Type[type].call arg }
|
21
30
|
end
|
22
31
|
|
23
32
|
def =~(str)
|
@@ -73,39 +73,19 @@ module Acclaim
|
|
73
73
|
def parse_values!
|
74
74
|
Values.new.tap do |options_instance|
|
75
75
|
options.each do |option|
|
76
|
-
key = option.key
|
77
|
-
options_instance[key] = option.default
|
78
|
-
|
79
|
-
if
|
76
|
+
key = option.key
|
77
|
+
options_instance[key] = option.default unless options_instance[key]
|
78
|
+
switches = argv.find_all { |switch| option =~ switch }
|
79
|
+
if switches.any?
|
80
80
|
if option.flag?
|
81
|
-
|
81
|
+
set_option_value option, options_instance
|
82
82
|
else
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
arg_index + arity.total
|
88
|
-
else
|
89
|
-
argv.length - 1
|
90
|
-
end
|
91
|
-
params = argv[arg_index + 1, len]
|
92
|
-
values = []
|
93
|
-
params.each do |param|
|
94
|
-
case param
|
95
|
-
when nil, SWITCH, ARGUMENT_SEPARATOR then break
|
96
|
-
else
|
97
|
-
break if arity.bound? and values.count >= arity.total
|
98
|
-
values << param
|
99
|
-
end
|
100
|
-
end
|
101
|
-
count = values.count
|
102
|
-
Error.raise_wrong_arg_number count, *option.arity if count < arity.required
|
103
|
-
value = if arity.total == 1 then values.first else values end
|
104
|
-
options_instance[key] = value unless values.empty?
|
105
|
-
values.each { |value| argv.delete value }
|
83
|
+
switches.each do |switch|
|
84
|
+
params = extract_parameters_of! option, switch
|
85
|
+
argv.delete switch
|
86
|
+
set_option_value option, options_instance, params
|
106
87
|
end
|
107
88
|
end
|
108
|
-
args.each { |arg| argv.delete arg }
|
109
89
|
else
|
110
90
|
Error.raise_missing_arg(option.names.join ' | ') if option.required?
|
111
91
|
end
|
@@ -113,6 +93,44 @@ module Acclaim
|
|
113
93
|
end
|
114
94
|
end
|
115
95
|
|
96
|
+
def extract_parameters_of!(option, switch)
|
97
|
+
arity = option.arity
|
98
|
+
switch_index = argv.index switch
|
99
|
+
len = if arity.bound?
|
100
|
+
switch_index + arity.total
|
101
|
+
else
|
102
|
+
argv.length - 1
|
103
|
+
end
|
104
|
+
params = argv[switch_index + 1, len]
|
105
|
+
values = []
|
106
|
+
params.each do |param|
|
107
|
+
case param
|
108
|
+
when nil, SWITCH, ARGUMENT_SEPARATOR then break
|
109
|
+
else
|
110
|
+
break if arity.bound? and values.count >= arity.total
|
111
|
+
values << param
|
112
|
+
end
|
113
|
+
end
|
114
|
+
count = values.count
|
115
|
+
Error.raise_wrong_arg_number count, *arity if count < arity.required
|
116
|
+
values.each { |value| argv.delete value }
|
117
|
+
end
|
118
|
+
|
119
|
+
def set_option_value(option, values, params = [])
|
120
|
+
params = option.convert_parameters *params
|
121
|
+
if handler = option.handler
|
122
|
+
if option.flag? then handler.call values
|
123
|
+
else handler.call values, params end
|
124
|
+
else
|
125
|
+
key = option.key.to_sym
|
126
|
+
if option.flag? then values[key] = true
|
127
|
+
else
|
128
|
+
value = option.arity.total == 1 ? params.first : params
|
129
|
+
values[key] = value unless params.empty?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
116
134
|
end
|
117
135
|
end
|
118
136
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Acclaim
|
2
|
+
class Option
|
3
|
+
|
4
|
+
# Associates a class with a handler block.
|
5
|
+
module Type
|
6
|
+
|
7
|
+
instance_eval do
|
8
|
+
|
9
|
+
# Yields class, proc pairs if a block was given. Returns an enumerator
|
10
|
+
# otherwise.
|
11
|
+
def each(&block)
|
12
|
+
table.each &block
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns all registered classes.
|
16
|
+
def all
|
17
|
+
table.keys
|
18
|
+
end
|
19
|
+
|
20
|
+
alias registered all
|
21
|
+
|
22
|
+
# Registers a handler for a class.
|
23
|
+
def register(klass, &block)
|
24
|
+
table[klass] = block
|
25
|
+
end
|
26
|
+
|
27
|
+
alias add_handler_for register
|
28
|
+
alias accept register
|
29
|
+
|
30
|
+
# Returns the handler for the given class.
|
31
|
+
def handler_for(klass)
|
32
|
+
table[klass]
|
33
|
+
end
|
34
|
+
|
35
|
+
alias [] handler_for
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# The hash used to associate classes with their handlers.
|
40
|
+
def table
|
41
|
+
@table ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
require 'acclaim/option/type/date'
|
52
|
+
require 'acclaim/option/type/date_time'
|
53
|
+
require 'acclaim/option/type/string'
|
54
|
+
require 'acclaim/option/type/time'
|
55
|
+
require 'acclaim/option/type/uri'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'acclaim/option/type'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Acclaim
|
5
|
+
class Option
|
6
|
+
module Type
|
7
|
+
|
8
|
+
# Handles dates given as arguments in the command line.
|
9
|
+
module Date
|
10
|
+
|
11
|
+
def self.handle(str)
|
12
|
+
::Date.parse str
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
self.accept ::Date, &Date.method(:handle)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'acclaim/option/type'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Acclaim
|
5
|
+
class Option
|
6
|
+
module Type
|
7
|
+
|
8
|
+
# Handles dates and times given as arguments in the command line.
|
9
|
+
module DateTime
|
10
|
+
|
11
|
+
def self.handle(str)
|
12
|
+
::DateTime.parse str
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
self.accept ::DateTime, &DateTime.method(:handle)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'acclaim/option/type'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Acclaim
|
5
|
+
class Option
|
6
|
+
module Type
|
7
|
+
|
8
|
+
# Handles strings given as arguments in the command line.
|
9
|
+
module String
|
10
|
+
|
11
|
+
def self.handle(str)
|
12
|
+
str.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
self.accept ::String, &String.method(:handle)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'acclaim/option/type'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Acclaim
|
5
|
+
class Option
|
6
|
+
module Type
|
7
|
+
|
8
|
+
# Handles times given as arguments in the command line.
|
9
|
+
module Time
|
10
|
+
|
11
|
+
def self.handle(str)
|
12
|
+
::Time.parse str
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
self.accept ::Time, &Time.method(:handle)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'acclaim/option/type'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Acclaim
|
5
|
+
class Option
|
6
|
+
module Type
|
7
|
+
|
8
|
+
# Handles URIs given as arguments in the command line.
|
9
|
+
module URI
|
10
|
+
|
11
|
+
def self.handle(str)
|
12
|
+
::URI.parse str
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
self.accept ::URI, &URI.method(:handle)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/acclaim/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acclaim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &13170100 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,18 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *13170100
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rookie
|
27
|
+
requirement: &13169620 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *13169620
|
25
36
|
description: Command-line option parser and command interface.
|
26
37
|
email: matheus.a.m.moreira@gmail.com
|
27
38
|
executables: []
|
@@ -43,6 +54,12 @@ files:
|
|
43
54
|
- lib/acclaim/option/arity.rb
|
44
55
|
- lib/acclaim/option/parser.rb
|
45
56
|
- lib/acclaim/option/parser/regexp.rb
|
57
|
+
- lib/acclaim/option/type.rb
|
58
|
+
- lib/acclaim/option/type/date.rb
|
59
|
+
- lib/acclaim/option/type/date_time.rb
|
60
|
+
- lib/acclaim/option/type/string.rb
|
61
|
+
- lib/acclaim/option/type/time.rb
|
62
|
+
- lib/acclaim/option/type/uri.rb
|
46
63
|
- lib/acclaim/option/values.rb
|
47
64
|
- lib/acclaim/version.rb
|
48
65
|
- spec/acclaim/option/arity_spec.rb
|