rubikon 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +12 -11
- data/Rakefile +4 -2
- data/lib/core_ext/object.rb +43 -0
- data/lib/core_ext/string.rb +8 -0
- data/lib/rubikon/application/base.rb +8 -9
- data/lib/rubikon/application/class_methods.rb +4 -2
- data/lib/rubikon/application/dsl_methods.rb +75 -62
- data/lib/rubikon/application/instance_methods.rb +106 -20
- data/lib/rubikon/application/sandbox.rb +70 -0
- data/lib/rubikon/command.rb +67 -23
- data/lib/rubikon/flag.rb +0 -8
- data/lib/rubikon/has_arguments.rb +182 -0
- data/lib/rubikon/option.rb +2 -9
- data/lib/rubikon/parameter.rb +16 -52
- data/lib/rubikon/progress_bar.rb +1 -1
- data/lib/rubikon.rb +11 -2
- data/samples/helloworld/hello_world.rb +69 -0
- data/test/{application_tests.rb → test_application.rb} +43 -5
- data/test/{command_tests.rb → test_command.rb} +19 -28
- data/test/{flag_tests.rb → test_flag.rb} +7 -5
- data/test/test_has_arguments.rb +99 -0
- data/test/test_helper.rb +1 -0
- data/test/test_option.rb +32 -0
- data/test/test_parameter.rb +21 -0
- data/test/{progress_bar_tests.rb → test_progress_bar.rb} +1 -1
- data/test/{throbber_tests.rb → test_throbber.rb} +3 -9
- data/test/testapps.rb +60 -1
- metadata +39 -17
- data/test/option_tests.rb +0 -75
@@ -0,0 +1,70 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010, Sebastian Staudt
|
5
|
+
|
6
|
+
module Rubikon
|
7
|
+
|
8
|
+
module Application
|
9
|
+
|
10
|
+
# The application sandbox is a wrapper used to secure internal Rubikon
|
11
|
+
# logic from access by user generated application code.
|
12
|
+
#
|
13
|
+
# This is mostly to prevent accidental execution or change of Rubikon's
|
14
|
+
# internal code. But it also helps to prevent possible security problems
|
15
|
+
# depending on the code used inside the application logic.
|
16
|
+
#
|
17
|
+
# @see Application::InstanceMethods
|
18
|
+
# @since 0.4.0
|
19
|
+
class Sandbox
|
20
|
+
|
21
|
+
# Create a new application sandbox
|
22
|
+
#
|
23
|
+
# @param [Application::Base] app The application to be sandboxed
|
24
|
+
def initialize(app)
|
25
|
+
raise ArgumentError unless app.is_a? Application::Base
|
26
|
+
@__app__ = app
|
27
|
+
end
|
28
|
+
|
29
|
+
# Method calls on the sandbox wrapper will be relayed to the singleton
|
30
|
+
# instance. Methods defined in InstanceMethods are protected and will
|
31
|
+
# raise a NoMethodError.
|
32
|
+
#
|
33
|
+
# @param (see ClassMethods#method_missing)
|
34
|
+
# @raise [NoMethodError] if a method is called that is defined inside
|
35
|
+
# InstanceMethods and should therefore be protected
|
36
|
+
# @see InstanceMethods
|
37
|
+
def method_missing(name, *args, &block)
|
38
|
+
if InstanceMethods.method_defined?(name) ||
|
39
|
+
InstanceMethods.private_method_defined?(name)
|
40
|
+
raise NoMethodError.new("Method `#{name}' is protected by the application sandbox", name)
|
41
|
+
end
|
42
|
+
@__app__.send(name, *args, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Relay putc to the instance method
|
46
|
+
#
|
47
|
+
# This is used to hide <tt>Kernel#putc</tt> so that the application's
|
48
|
+
# output IO object is used for printing characters
|
49
|
+
#
|
50
|
+
# @param [String, Numeric] char The character to write into the output
|
51
|
+
# stream
|
52
|
+
def putc(text)
|
53
|
+
@__app__.send(:putc, text)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Relay puts to the instance method
|
57
|
+
#
|
58
|
+
# This is used to hide <tt>Kernel#puts</tt> so that the application's
|
59
|
+
# output IO object is used for printing text
|
60
|
+
#
|
61
|
+
# @param [String] text The text to write into the output stream
|
62
|
+
def puts(text)
|
63
|
+
@__app__.send(:puts, text)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/rubikon/command.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
require 'rubikon/application/base'
|
7
7
|
require 'rubikon/exceptions'
|
8
|
+
require 'rubikon/has_arguments'
|
8
9
|
require 'rubikon/parameter'
|
9
10
|
|
10
11
|
module Rubikon
|
@@ -16,31 +17,33 @@ module Rubikon
|
|
16
17
|
# @since 0.3.0
|
17
18
|
class Command
|
18
19
|
|
19
|
-
include
|
20
|
+
include HasArguments
|
20
21
|
|
22
|
+
# @return [String] The description of this command
|
21
23
|
attr_accessor :description
|
22
|
-
|
23
|
-
|
24
|
+
|
25
|
+
# @return [Array<Parameter>] The parameters of this command
|
26
|
+
attr_reader :params
|
24
27
|
alias_method :parameters, :params
|
25
28
|
|
26
29
|
# Create a new application command with the given name with a reference to
|
27
30
|
# the app it belongs to
|
28
31
|
#
|
29
|
-
# @param [Application::Base] app
|
30
|
-
#
|
31
|
-
# @param [#to_sym] name The name of this command, used in application
|
32
|
+
# @param [Application::Base] app The application this command belongs to
|
33
|
+
# @param [Symbol, #to_sym] name The name of this command, used in application
|
32
34
|
# arguments
|
35
|
+
# @param [Range, Array, Numeric] arg_count The number of arguments this
|
36
|
+
# command takes.
|
33
37
|
# @param [Proc] block The code block which should be executed by this
|
34
38
|
# command
|
35
39
|
# @raise [ArgumentError] if the given application object isn't a Rubikon
|
36
40
|
# application
|
37
41
|
# @raise [BlockMissingError] if no command code block is given and a
|
38
42
|
# command file does not exist
|
39
|
-
|
40
|
-
|
41
|
-
super
|
43
|
+
# @see HasArguments#arg_count=
|
44
|
+
def initialize(app, name, arg_count = nil, &block)
|
45
|
+
super
|
42
46
|
|
43
|
-
@app = app
|
44
47
|
@params = {}
|
45
48
|
|
46
49
|
if block_given?
|
@@ -53,14 +56,14 @@ module Rubikon
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
56
|
-
# Add a new
|
59
|
+
# Add a new parameter for this command
|
57
60
|
#
|
58
|
-
# @param [Parameter, Hash] parameter The parameter to add to this
|
61
|
+
# @param [Parameter, Hash] parameter The parameter to add to this
|
59
62
|
# command. This might also be a Hash where every key will be an
|
60
63
|
# alias to the corresponding value, e.g. <tt>{ :alias => :parameter
|
61
64
|
# }</tt>.
|
62
65
|
# @see Parameter
|
63
|
-
def
|
66
|
+
def add_param(parameter)
|
64
67
|
if parameter.is_a? Hash
|
65
68
|
parameter.each do |alias_name, name|
|
66
69
|
alias_name = alias_name.to_sym
|
@@ -78,12 +81,33 @@ module Rubikon
|
|
78
81
|
@params.each do |name, param|
|
79
82
|
if param == parameter.name
|
80
83
|
parameter.aliases << name
|
84
|
+
@params[name] = parameter
|
81
85
|
end
|
82
86
|
end
|
83
87
|
@params[parameter.name] = parameter
|
84
88
|
end
|
85
89
|
end
|
86
90
|
|
91
|
+
# If a parameter with the specified method name exists, a call to that
|
92
|
+
# method will return the value of the parameter.
|
93
|
+
#
|
94
|
+
# @param (see ClassMethods#method_missing)
|
95
|
+
# @see DSLMethods#params
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
# option :user, [:who]
|
99
|
+
# command :hello, [:mood] do
|
100
|
+
# puts "Hello #{user.who}"
|
101
|
+
# puts "I feel #{mood}"
|
102
|
+
# end
|
103
|
+
def method_missing(name, *args, &block)
|
104
|
+
if args.empty? && !block_given? && @params.key?(name)
|
105
|
+
@params[name]
|
106
|
+
else
|
107
|
+
super
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
87
111
|
# Parses the arguments of this command and sets each Parameter as active
|
88
112
|
# if it has been supplied by the user on the command-line. Additional
|
89
113
|
# arguments are passed to the individual parameters.
|
@@ -96,7 +120,6 @@ module Rubikon
|
|
96
120
|
# @see Option
|
97
121
|
def parse_arguments(args)
|
98
122
|
@args = []
|
99
|
-
parameter = nil
|
100
123
|
args.each do |arg|
|
101
124
|
if arg.start_with?('-')
|
102
125
|
parameter_name = arg.start_with?('--') ? arg[2..-1] : arg[1..-1]
|
@@ -104,21 +127,41 @@ module Rubikon
|
|
104
127
|
raise UnknownParameterError.new(arg) if parameter.nil?
|
105
128
|
end
|
106
129
|
|
107
|
-
unless parameter.nil?
|
108
|
-
|
130
|
+
unless parameter.nil?
|
131
|
+
@app.current_param.active! unless @app.current_param.nil?
|
132
|
+
@app.current_param = parameter
|
109
133
|
next
|
110
134
|
end
|
111
135
|
|
112
|
-
if
|
113
|
-
|
136
|
+
if @app.current_param.nil? || !@app.current_param.more_args?
|
137
|
+
self << arg
|
114
138
|
else
|
115
|
-
|
139
|
+
@app.current_param << arg
|
116
140
|
end
|
117
141
|
end
|
118
142
|
|
119
|
-
@
|
120
|
-
|
121
|
-
|
143
|
+
@app.current_param.active! unless @app.current_param.nil?
|
144
|
+
@app.current_param = nil
|
145
|
+
end
|
146
|
+
|
147
|
+
# Resets this command to its initial state
|
148
|
+
#
|
149
|
+
# @see HasArguments#reset
|
150
|
+
# @since 0.4.0
|
151
|
+
def reset
|
152
|
+
super
|
153
|
+
@params.values.uniq.each { |param| param.reset if param.is_a? Parameter }
|
154
|
+
end
|
155
|
+
|
156
|
+
# Checks whether a parameter with the given name exists for this command
|
157
|
+
#
|
158
|
+
# This is used to determine if a method call would successfully return the
|
159
|
+
# value of a parameter.
|
160
|
+
#
|
161
|
+
# @return +true+ if named parameter with the specified name exists
|
162
|
+
# @see #method_missing
|
163
|
+
def respond_to_missing?(name, include_private = false)
|
164
|
+
@params.key?(name) || super
|
122
165
|
end
|
123
166
|
|
124
167
|
# Run this command's code block
|
@@ -127,7 +170,8 @@ module Rubikon
|
|
127
170
|
# command
|
128
171
|
def run(*args)
|
129
172
|
parse_arguments(args)
|
130
|
-
|
173
|
+
check_args
|
174
|
+
@app.sandbox.instance_eval(&@block)
|
131
175
|
end
|
132
176
|
|
133
177
|
end
|
data/lib/rubikon/flag.rb
CHANGED
@@ -18,14 +18,6 @@ module Rubikon
|
|
18
18
|
|
19
19
|
include Parameter
|
20
20
|
|
21
|
-
# Creates a new flag with the given name and an optional code block
|
22
|
-
#
|
23
|
-
# @param name (see Parameter#initialize)
|
24
|
-
# @param block (see Parameter#initialize)
|
25
|
-
def initialize(name, &block)
|
26
|
-
super(name, 0, &block)
|
27
|
-
end
|
28
|
-
|
29
21
|
# Adds an argument to this flag
|
30
22
|
#
|
31
23
|
# @param arg (see Parameter#<<)
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'rubikon/parameter'
|
7
|
+
|
8
|
+
module Rubikon
|
9
|
+
|
10
|
+
# This module is included in all classes used for parsing command-line
|
11
|
+
# arguments
|
12
|
+
#
|
13
|
+
# @author Sebastian Staudt
|
14
|
+
# @see Application::InstanceMethods
|
15
|
+
# @see Command
|
16
|
+
# @see Option
|
17
|
+
# @since 0.4.0
|
18
|
+
module HasArguments
|
19
|
+
|
20
|
+
include Parameter
|
21
|
+
|
22
|
+
# @return [Array<String>] The arguments given to this parameter
|
23
|
+
attr_reader :args
|
24
|
+
alias_method :arguments, :args
|
25
|
+
|
26
|
+
# Creates a new parameter with arguments with the given name and an
|
27
|
+
# optional code block
|
28
|
+
#
|
29
|
+
# @param [Application::Base] app The application this parameter belongs to
|
30
|
+
# @param [Symbol, #to_sym] name The name of the option
|
31
|
+
# @param [Fixnum, Range, Array] arg_count A range or array allows any
|
32
|
+
# number of arguments inside the limits between the first and the
|
33
|
+
# last element of the range or array (-1 stands for an arbitrary
|
34
|
+
# number of arguments). A positive number indicates the exact amount
|
35
|
+
# of required arguments while a negative argument count indicates
|
36
|
+
# the amount of required arguments, but allows additional, optional
|
37
|
+
# arguments. A argument count of 0 means there are no required
|
38
|
+
# arguments, but it allows optional arguments.
|
39
|
+
# Finally an array of symbols enables named arguments where the
|
40
|
+
# argument count is the size of the array and each argument is named
|
41
|
+
# after the corresponding symbol.
|
42
|
+
# @param [Proc] block An optional code block to be executed if this
|
43
|
+
# option is used
|
44
|
+
def initialize(app, name, arg_count = 0, &block)
|
45
|
+
super(app, name, &block)
|
46
|
+
|
47
|
+
@args = []
|
48
|
+
@arg_names = nil
|
49
|
+
if arg_count.is_a? Fixnum
|
50
|
+
if arg_count > 0
|
51
|
+
@min_arg_count = arg_count
|
52
|
+
@max_arg_count = arg_count
|
53
|
+
elsif arg_count <= 0
|
54
|
+
@min_arg_count = -arg_count
|
55
|
+
@max_arg_count = -1
|
56
|
+
end
|
57
|
+
elsif arg_count.is_a?(Array) && arg_count.all? { |a| a.is_a? Symbol }
|
58
|
+
@max_arg_count = @min_arg_count = arg_count.size
|
59
|
+
@arg_names = arg_count
|
60
|
+
elsif arg_count.is_a?(Range) || arg_count.is_a?(Array)
|
61
|
+
@min_arg_count = arg_count.first
|
62
|
+
@max_arg_count = arg_count.last
|
63
|
+
else
|
64
|
+
@min_arg_count = 0
|
65
|
+
@max_arg_count = 0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Access the arguments of this parameter using a numeric or symbolic index
|
70
|
+
#
|
71
|
+
# @param [Numeric, Symbol] The index of the argument to return. Numeric
|
72
|
+
# indices can be used always while symbolic arguments are only
|
73
|
+
# available for named arguments.
|
74
|
+
# @return The argument with the specified index
|
75
|
+
# @since 0.4.0
|
76
|
+
def [](arg)
|
77
|
+
arg = @arg_names.index(arg) if arg.is_a? Symbol
|
78
|
+
@args[arg]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Adds an argument to this parameter. Arguments can be accessed inside the
|
82
|
+
# application code using the args method.
|
83
|
+
#
|
84
|
+
# @param [String] arg The argument to add to the supplied arguments of this
|
85
|
+
# parameter
|
86
|
+
# @raise [ExtraArgumentError] if the parameter has all required arguments
|
87
|
+
# supplied and does not take optional arguments
|
88
|
+
# @return [Array] The supplied arguments of this parameter
|
89
|
+
# @see #[]
|
90
|
+
# @see #args
|
91
|
+
# @since 0.3.0
|
92
|
+
def <<(arg)
|
93
|
+
if args_full? && @args.size == @max_arg_count
|
94
|
+
raise ExtraArgumentError.new(@name)
|
95
|
+
end
|
96
|
+
@args << arg
|
97
|
+
end
|
98
|
+
|
99
|
+
# Marks this parameter as active when it has been supplied by the user on
|
100
|
+
# the command-line. This also checks the arguments given to this parameter.
|
101
|
+
#
|
102
|
+
# @see #check_args
|
103
|
+
# @see Paramter#active!
|
104
|
+
def active!
|
105
|
+
check_args
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return the allowed range of argument counts this parameter takes
|
110
|
+
#
|
111
|
+
# @return [Range] The allowed range of argument counts this parameter takes
|
112
|
+
def arg_count
|
113
|
+
@min_arg_count..@max_arg_count
|
114
|
+
end
|
115
|
+
|
116
|
+
# Checks whether this parameter has all required arguments supplied
|
117
|
+
#
|
118
|
+
# @return +true+ if all required parameter arguments have been supplied
|
119
|
+
# @since 0.3.0
|
120
|
+
def args_full?
|
121
|
+
@args.size >= @min_arg_count
|
122
|
+
end
|
123
|
+
|
124
|
+
# Checks the arguments for this parameter
|
125
|
+
#
|
126
|
+
# @raise [MissingArgumentError] if there are not enough arguments for
|
127
|
+
# this parameter
|
128
|
+
# @since 0.3.0
|
129
|
+
def check_args
|
130
|
+
raise MissingArgumentError.new(@name) unless args_full?
|
131
|
+
end
|
132
|
+
|
133
|
+
# If a named argument with the specified method name exists, a call to that
|
134
|
+
# method will return the value of the argument.
|
135
|
+
#
|
136
|
+
# @param (see ClassMethods#method_missing)
|
137
|
+
# @see #args
|
138
|
+
# @see #[]
|
139
|
+
#
|
140
|
+
# @example
|
141
|
+
# option :user, [:name] do
|
142
|
+
# @user = name
|
143
|
+
# end
|
144
|
+
def method_missing(name, *args, &block)
|
145
|
+
if args.empty? && !block_given? && !@arg_names.nil? && @arg_names.include?(name)
|
146
|
+
@args[@arg_names.index(name)]
|
147
|
+
else
|
148
|
+
super
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Checks whether this parameter can take more arguments
|
153
|
+
#
|
154
|
+
# @return +true+ if this parameter can take more arguments
|
155
|
+
# @since 0.3.0
|
156
|
+
def more_args?
|
157
|
+
@max_arg_count == -1 || @args.size < @max_arg_count
|
158
|
+
end
|
159
|
+
|
160
|
+
# Resets this parameter to its initial state
|
161
|
+
#
|
162
|
+
# @see Parameter#reset
|
163
|
+
# @since 0.4.0
|
164
|
+
def reset
|
165
|
+
super
|
166
|
+
@args.clear
|
167
|
+
end
|
168
|
+
|
169
|
+
# Checks whether an argument with the given name exists for this parameter
|
170
|
+
#
|
171
|
+
# This is used to determine if a method call would successfully return the
|
172
|
+
# value of an argument.
|
173
|
+
#
|
174
|
+
# @return +true+ if named argument with the specified name exists
|
175
|
+
# @see #method_missing
|
176
|
+
def respond_to_missing?(name, include_private = false)
|
177
|
+
!@arg_names.nil? && @arg_names.include?(name)
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
data/lib/rubikon/option.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# Copyright (c) 2010, Sebastian Staudt
|
5
5
|
|
6
|
-
require 'rubikon/
|
6
|
+
require 'rubikon/has_arguments'
|
7
7
|
|
8
8
|
module Rubikon
|
9
9
|
|
@@ -16,14 +16,7 @@ module Rubikon
|
|
16
16
|
# @since 0.3.0
|
17
17
|
class Option
|
18
18
|
|
19
|
-
|
20
|
-
attr_reader :arg_count
|
21
|
-
|
22
|
-
# @return [Array<String>] The arguments given to this parameter
|
23
|
-
attr_reader :args
|
24
|
-
alias_method :arguments, :args
|
25
|
-
|
26
|
-
include Parameter
|
19
|
+
include HasArguments
|
27
20
|
|
28
21
|
end
|
29
22
|
|
data/lib/rubikon/parameter.rb
CHANGED
@@ -7,9 +7,10 @@ module Rubikon
|
|
7
7
|
|
8
8
|
# A parameter is any command-line argument given to the application that is
|
9
9
|
# not prefixed with one or two dashes. Once a parameter is supplied by the
|
10
|
-
# user, it is relayed to the
|
10
|
+
# user, it is relayed to the command it belongs to.
|
11
11
|
#
|
12
12
|
# @author Sebastian Staudt
|
13
|
+
# @see Command
|
13
14
|
# @since 0.3.0
|
14
15
|
module Parameter
|
15
16
|
|
@@ -21,38 +22,18 @@ module Rubikon
|
|
21
22
|
|
22
23
|
# Creates a new parameter with the given name
|
23
24
|
#
|
25
|
+
# @param [Application::Base] app The application this parameter belongs to
|
24
26
|
# @param [Symbol, #to_sym] name The name of the parameter
|
25
|
-
# @param [Numeric] arg_count The number of arguments this parameter takes
|
26
|
-
# if any
|
27
27
|
# @param [Proc] block An optional code block to be executed if this
|
28
28
|
# parameter is used
|
29
|
-
|
30
|
-
|
31
|
-
# arguments, while a negative argument count indicates the amount of
|
32
|
-
# required arguments, but allows additional, optional arguments. A argument
|
33
|
-
# count of 0 means there are no required arguments, but it allows optional
|
34
|
-
# arguments. If you need a parameter that does not allow arguments at all
|
35
|
-
# you should use a flag instead.
|
36
|
-
def initialize(name, arg_count = 0, &block)
|
37
|
-
@active = false
|
38
|
-
@aliases = []
|
39
|
-
@arg_count = arg_count
|
40
|
-
@args = []
|
41
|
-
@block = block
|
42
|
-
@name = name.to_sym
|
43
|
-
end
|
29
|
+
def initialize(app, name, &block)
|
30
|
+
raise ArgumentError unless app.is_a? Application::Base
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# @raise [ExtraArgumentError] if the parameter has all required arguments
|
51
|
-
# supplied and does not take optional arguments
|
52
|
-
# @return [Array] The supplied arguments of this parameter
|
53
|
-
def <<(arg)
|
54
|
-
raise ExtraArgumentError.new(@name) if args_full? && @arg_count > 0
|
55
|
-
@args << arg
|
32
|
+
@active = false
|
33
|
+
@aliases = []
|
34
|
+
@app = app
|
35
|
+
@block = block
|
36
|
+
@name = name.to_sym
|
56
37
|
end
|
57
38
|
|
58
39
|
# Marks this parameter as active when it has been supplied by the user on
|
@@ -60,7 +41,7 @@ module Rubikon
|
|
60
41
|
# exists
|
61
42
|
def active!
|
62
43
|
@active = true
|
63
|
-
@block
|
44
|
+
@app.sandbox.instance_eval(&@block) unless @block.nil?
|
64
45
|
end
|
65
46
|
|
66
47
|
# Returns whether this parameter has is active, i.e. it has been supplied
|
@@ -70,30 +51,13 @@ module Rubikon
|
|
70
51
|
def active?
|
71
52
|
@active
|
72
53
|
end
|
54
|
+
alias_method :given?, :active?
|
73
55
|
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# @return +true+ if all required parameter arguments have been supplied
|
77
|
-
def args_full?
|
78
|
-
arg_count = @arg_count
|
79
|
-
arg_count = -arg_count if arg_count < 0
|
80
|
-
|
81
|
-
arg_count == 0 || @args.size >= arg_count
|
82
|
-
end
|
83
|
-
|
84
|
-
# Checks the arguments for this parameter
|
85
|
-
#
|
86
|
-
# @raise [MissingArgumentError] if there are not enough arguments for
|
87
|
-
# this parameter
|
88
|
-
def check_args
|
89
|
-
raise MissingArgumentError.new(@name) unless args_full?
|
90
|
-
end
|
91
|
-
|
92
|
-
# Checks whether this parameter can take more arguments
|
56
|
+
# Resets this parameter to its initial state
|
93
57
|
#
|
94
|
-
# @
|
95
|
-
def
|
96
|
-
|
58
|
+
# @since 0.4.0
|
59
|
+
def reset
|
60
|
+
@active = false
|
97
61
|
end
|
98
62
|
|
99
63
|
end
|
data/lib/rubikon/progress_bar.rb
CHANGED
data/lib/rubikon.rb
CHANGED
@@ -6,15 +6,24 @@
|
|
6
6
|
libdir = File.dirname(__FILE__)
|
7
7
|
$:.unshift(libdir) unless $:.include?(libdir)
|
8
8
|
|
9
|
+
require 'core_ext/object'
|
9
10
|
require 'core_ext/string'
|
10
11
|
require 'rubikon/application/base'
|
11
12
|
|
12
|
-
#
|
13
|
+
# Rubikon is a simple to use, yet powerful Ruby framework for building
|
14
|
+
# console-based applications. Rubikon aims to provide an easy to write and easy
|
15
|
+
# to read domain-specific language (DSL) to speed up development of
|
16
|
+
# command-line applications. With Rubikon it's a breeze to implement
|
17
|
+
# applications with only few options as well as more complex programs like
|
18
|
+
# RubyGems, Homebrew or even Git.
|
19
|
+
#
|
20
|
+
# This is the namespace module for all Rubikon related code.
|
13
21
|
#
|
14
22
|
# @author Sebastian Staudt
|
15
23
|
# @since 0.1.0
|
16
24
|
module Rubikon
|
17
25
|
|
18
|
-
|
26
|
+
# This is the current version of the Rubikon gem
|
27
|
+
VERSION = '0.4.0'
|
19
28
|
|
20
29
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This code is free software; you can redistribute it and/or modify it under
|
4
|
+
# the terms of the new BSD License.
|
5
|
+
#
|
6
|
+
# Copyright (c) 2010, Sebastian Staudt
|
7
|
+
|
8
|
+
if ENV['RUBIKON_DEV']
|
9
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'lib', 'rubikon')
|
10
|
+
else
|
11
|
+
require 'rubygems'
|
12
|
+
require 'rubikon'
|
13
|
+
end
|
14
|
+
|
15
|
+
# A relatively simple Hello World application using Rubikon
|
16
|
+
class HelloWorld < Rubikon::Application::Base
|
17
|
+
|
18
|
+
# Greet the whole world per default
|
19
|
+
flag :more
|
20
|
+
option :name, [:who]
|
21
|
+
option :names, -1
|
22
|
+
default 'Simple hello world' do
|
23
|
+
debug 'Starting to greet the world...'
|
24
|
+
if given? :name
|
25
|
+
greet parameters[:name].who
|
26
|
+
elsif given? :names
|
27
|
+
names.args.each do |name|
|
28
|
+
greet name
|
29
|
+
end
|
30
|
+
else
|
31
|
+
greet 'World'
|
32
|
+
end
|
33
|
+
puts 'Nice to see you.' if given? :more
|
34
|
+
end
|
35
|
+
|
36
|
+
# Interactive mode
|
37
|
+
#
|
38
|
+
# Ask the user for his name and greet him
|
39
|
+
command :interactive, 'Greet interactively' do
|
40
|
+
name = input 'Please enter your name'
|
41
|
+
greet name
|
42
|
+
end
|
43
|
+
|
44
|
+
# Show a progress bar while iterating through a loop
|
45
|
+
command :progress, 'Display a progress bar' do
|
46
|
+
put 'Watch my progress while I greet the world: '
|
47
|
+
x = 1000000
|
48
|
+
progress_bar(:char => '+', :maximum => x, :size => 30) do |progress|
|
49
|
+
x.times do
|
50
|
+
progress.+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sleep for 5 seconds while displaying a throbber
|
56
|
+
command :throbber, 'Display a throbber' do
|
57
|
+
put 'Greeting the whole world takes some time... '
|
58
|
+
throbber do
|
59
|
+
sleep 5
|
60
|
+
end
|
61
|
+
puts 'done.'
|
62
|
+
end
|
63
|
+
|
64
|
+
# A standard Ruby class method for greeting
|
65
|
+
def greet(someone)
|
66
|
+
puts "Hello #{someone}!"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|