rubikon 0.3.0 → 0.4.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/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
|