linen 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/linen.rb +2 -2
- data/lib/linen/argument.rb +2 -2
- data/lib/linen/exceptions.rb +2 -0
- data/lib/linen/handler.rb +11 -4
- data/lib/linen/handlers/cli.rb +26 -5
- data/lib/linen/plugin.rb +9 -0
- data/lib/linen/simple_command.rb +32 -37
- data/lib/linen/two_phase_command.rb +14 -49
- data/lib/linen/workspace.rb +4 -0
- data/lib/string_extensions.rb +1 -1
- metadata +1 -1
data/lib/linen.rb
CHANGED
data/lib/linen/argument.rb
CHANGED
@@ -13,7 +13,7 @@ class Linen::Plugin::Argument
|
|
13
13
|
def initialize( plugin, name, opts )
|
14
14
|
@plugin = plugin
|
15
15
|
@name = name
|
16
|
-
@prompt = opts[ :prompt ] || "Please enter the value for #{@name}"
|
16
|
+
@prompt = opts[ :prompt ] || "Please enter the value for #{@name}: "
|
17
17
|
@regex = opts[ :regex ] || //
|
18
18
|
@process = opts[ :process ] || nil
|
19
19
|
end
|
@@ -32,7 +32,7 @@ class Linen::Plugin::Argument
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
raise Linen::Plugin::ArgumentError, "
|
35
|
+
raise Linen::Plugin::ArgumentError, "The value entered ('#{value}') is not a valid #{@name}." unless value =~ @regex
|
36
36
|
return value unless @process
|
37
37
|
|
38
38
|
begin
|
data/lib/linen/exceptions.rb
CHANGED
data/lib/linen/handler.rb
CHANGED
@@ -8,10 +8,17 @@
|
|
8
8
|
##############################################################
|
9
9
|
|
10
10
|
class Linen::Handler
|
11
|
-
|
12
|
-
# class from which all handlers inherit.
|
13
|
-
|
14
|
-
def self::say( input )
|
11
|
+
def self::say( input = '' )
|
15
12
|
raise NotImplementedError, "You must override say() in the handler"
|
16
13
|
end
|
14
|
+
|
15
|
+
|
16
|
+
def self::die( input = '' )
|
17
|
+
raise NotImplementedError, "You must override die() in the handler"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def self::history
|
22
|
+
raise NotImplementedError, "Handlers must provide a #history method that quacks like an Array"
|
23
|
+
end
|
17
24
|
end
|
data/lib/linen/handlers/cli.rb
CHANGED
@@ -55,6 +55,10 @@ class Linen::CLI < Linen::Handler
|
|
55
55
|
end
|
56
56
|
elsif plugin.nil? or command.nil?
|
57
57
|
puts "You must enter both a plugin name and a command."
|
58
|
+
elsif Linen.plugins[ plugin ].nil?
|
59
|
+
puts "Plugin '#{plugin}' not found."
|
60
|
+
elsif Linen.plugins[ plugin ].commands[ command ].nil?
|
61
|
+
puts "Command '#{command}' not found in '#{plugin}' plugin."
|
58
62
|
else
|
59
63
|
plugin, command, *args = canonicalize( input ).split
|
60
64
|
|
@@ -68,26 +72,43 @@ class Linen::CLI < Linen::Handler
|
|
68
72
|
|
69
73
|
def self::start
|
70
74
|
loop do
|
75
|
+
input = nil
|
76
|
+
|
71
77
|
begin
|
72
78
|
input = Readline.readline( @prompt )
|
73
|
-
rescue Interrupt
|
74
|
-
puts "\nPlease type 'quit' or 'exit' to quit."
|
75
|
-
else
|
76
79
|
parse_command input
|
80
|
+
rescue Interrupt
|
81
|
+
if input
|
82
|
+
puts "\nCommand aborted."
|
83
|
+
else
|
84
|
+
puts "\nPlease type 'quit' or 'exit' to quit."
|
85
|
+
end
|
86
|
+
rescue Linen::Plugin::ArgumentError => e
|
87
|
+
puts e.message
|
77
88
|
end
|
78
89
|
|
79
90
|
puts # blank line to clean things up
|
80
91
|
end
|
81
92
|
end
|
93
|
+
|
94
|
+
|
95
|
+
def self::history
|
96
|
+
return Readline::HISTORY
|
97
|
+
end
|
82
98
|
|
83
99
|
|
84
100
|
#######
|
85
101
|
private
|
86
102
|
#######
|
87
103
|
|
88
|
-
def self::say( input =
|
104
|
+
def self::say( input = '' )
|
89
105
|
puts input.wrap
|
90
106
|
end
|
107
|
+
|
108
|
+
|
109
|
+
def self::die( input = '' )
|
110
|
+
raise Linen::Abort, input
|
111
|
+
end
|
91
112
|
|
92
113
|
|
93
114
|
def self::canonicalize( input )
|
@@ -207,7 +228,7 @@ END
|
|
207
228
|
end
|
208
229
|
|
209
230
|
|
210
|
-
def self::
|
231
|
+
def self::prompt( prompt = "Re-enter: " )
|
211
232
|
old_completion_proc = Readline.completion_proc
|
212
233
|
Readline.completion_proc = proc {}
|
213
234
|
|
data/lib/linen/plugin.rb
CHANGED
@@ -104,4 +104,13 @@ class Linen::Plugin
|
|
104
104
|
|
105
105
|
@description = input
|
106
106
|
end
|
107
|
+
|
108
|
+
|
109
|
+
### give validation a way to fail without explicitly raising
|
110
|
+
### an exception in the lambda
|
111
|
+
def self::fail( input = nil )
|
112
|
+
input ||= "Validation failed."
|
113
|
+
|
114
|
+
raise Linen::Plugin::ArgumentError, input
|
115
|
+
end
|
107
116
|
end
|
data/lib/linen/simple_command.rb
CHANGED
@@ -113,37 +113,35 @@ class Linen::Plugin::SimpleCommand
|
|
113
113
|
@require_confirmation
|
114
114
|
end
|
115
115
|
|
116
|
-
|
117
|
-
private
|
118
|
-
|
116
|
+
#######
|
117
|
+
private
|
118
|
+
#######
|
119
119
|
|
120
120
|
### FIXME:bbleything
|
121
121
|
###
|
122
|
-
###
|
123
|
-
###
|
124
|
-
###
|
122
|
+
### Much of the reprompting stuff is gone, it only exists now to allow us to
|
123
|
+
### prompt when users don't enter anything. We should consider moving the
|
124
|
+
### argument fetching into a separate phase of execution, so as to prevent
|
125
|
+
### the ridiculous duplication of history-manipulation code in the following
|
126
|
+
### two methods (and generally make it clearer how the whole thing works), but
|
127
|
+
### that's probably not going to make it into 0.7.0.
|
125
128
|
|
126
129
|
def validate_one_of_arguments( arg )
|
127
130
|
results = IndifferentHash.new
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
"The value you entered ('#{arg}') is invalid for all arguments." if
|
138
|
-
results.values.compact.empty?
|
139
|
-
rescue Linen::Plugin::ArgumentError => e
|
140
|
-
puts e.message
|
141
|
-
arg = Linen::CLI.reprompt.split.first
|
142
|
-
|
143
|
-
retry
|
131
|
+
|
132
|
+
# put the argument onto the command history if it wasn't already there
|
133
|
+
command_line = Linen::Workspace.handler.history.pop.strip
|
134
|
+
command_line << " #{arg}" unless command_line =~ /#{arg}$/
|
135
|
+
Linen::Workspace.handler.history.push command_line.squeeze( ' ' ).strip
|
136
|
+
|
137
|
+
@arguments.each do |arg_name|
|
138
|
+
argument = @plugin.arguments[ arg_name ]
|
139
|
+
results[ arg_name ] = argument.process( arg ) rescue nil
|
144
140
|
end
|
145
|
-
|
146
|
-
|
141
|
+
|
142
|
+
raise Linen::Plugin::ArgumentError,
|
143
|
+
"The value you entered ('#{arg}') is invalid for all arguments." if
|
144
|
+
results.values.compact.empty?
|
147
145
|
end
|
148
146
|
|
149
147
|
|
@@ -152,20 +150,17 @@ class Linen::Plugin::SimpleCommand
|
|
152
150
|
|
153
151
|
@arguments.each do |arg_name|
|
154
152
|
argument = @plugin.arguments[ arg_name ]
|
153
|
+
|
154
|
+
# prompt if we don't have the arg on the stack already
|
155
155
|
arg_value = args.shift
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
# reset arg_value to nil so we get prompted on retry
|
165
|
-
arg_value = nil
|
166
|
-
|
167
|
-
retry
|
168
|
-
end
|
156
|
+
arg_value ||= Linen::Workspace.handler.prompt( argument.prompt )
|
157
|
+
|
158
|
+
# put the arg value back onto the command line
|
159
|
+
command_line = Linen::Workspace.handler.history.pop
|
160
|
+
command_line << " #{arg_value}" unless command_line =~ /#{arg_value}$/
|
161
|
+
Linen::Workspace.handler.history.push command_line.squeeze( ' ' ).strip
|
162
|
+
|
163
|
+
results[ arg_name ] = argument.process( arg_value )
|
169
164
|
end
|
170
165
|
|
171
166
|
return results
|
@@ -45,37 +45,6 @@ class Linen::Plugin::TwoPhaseCommand
|
|
45
45
|
# PLUGIN DEFINITION METHODS #
|
46
46
|
#############################
|
47
47
|
|
48
|
-
|
49
|
-
# def one_of( *args )
|
50
|
-
# raise Linen::Plugin::ArgumentError,
|
51
|
-
# "You may not specify both required and one_of arguments" if @argument_type == :required
|
52
|
-
#
|
53
|
-
# @argument_type = :one_of
|
54
|
-
#
|
55
|
-
# args.each do |arg|
|
56
|
-
# raise Linen::Plugin::ArgumentError,
|
57
|
-
# "Argument '#{arg}' has not been defined" unless @plugin.arguments.include? arg
|
58
|
-
#
|
59
|
-
# @arguments << arg
|
60
|
-
# end
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
#
|
64
|
-
# def required_arguments( *args )
|
65
|
-
# raise Linen::Plugin::ArgumentError,
|
66
|
-
# "You may not specify both required and one_of arguments" if @argument_type == :one_of
|
67
|
-
#
|
68
|
-
# @argument_type = :required
|
69
|
-
#
|
70
|
-
# args.each do |arg|
|
71
|
-
# raise Linen::Plugin::ArgumentError,
|
72
|
-
# "Argument '#{arg}' has not been defined" unless @plugin.arguments.include? arg
|
73
|
-
#
|
74
|
-
# @arguments << arg
|
75
|
-
# end
|
76
|
-
# end
|
77
|
-
# alias required_argument required_arguments
|
78
|
-
|
79
48
|
def lookup_by( attr_name, &block )
|
80
49
|
@lookup_attr = attr_name
|
81
50
|
@lookup_block = block
|
@@ -121,27 +90,21 @@ class Linen::Plugin::TwoPhaseCommand
|
|
121
90
|
argument = @plugin.arguments[ @lookup_attr ]
|
122
91
|
arg_value = input
|
123
92
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
processed_argument = argument.process( arg_value )
|
93
|
+
# prompt if we didn't get an arg value
|
94
|
+
arg_value ||= Linen::CLI.prompt( argument.prompt )
|
128
95
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
96
|
+
# put the command back onto the history
|
97
|
+
command_line = Linen::Workspace.handler.history.pop
|
98
|
+
command_line << " #{arg_value}" unless command_line =~ /#{arg_value}$/
|
99
|
+
Linen::Workspace.handler.history.push command_line.squeeze( ' ' ).strip
|
100
|
+
|
101
|
+
processed_argument = argument.process( arg_value )
|
102
|
+
results[ @lookup_attr ] = @lookup_block.call( processed_argument )
|
136
103
|
|
137
104
|
return results
|
138
105
|
end
|
139
|
-
|
140
|
-
|
141
|
-
###
|
142
|
-
### The reprompting stuff below is going to come back to bite us when we try to
|
143
|
-
### add batch mode later... that said, in the interest of getting things out the
|
144
|
-
### door, we're going to leave it be for now.
|
106
|
+
|
107
|
+
|
145
108
|
def validate_arguments( args )
|
146
109
|
results = IndifferentHash.new
|
147
110
|
|
@@ -150,7 +113,7 @@ class Linen::Plugin::TwoPhaseCommand
|
|
150
113
|
arg_value = args.shift
|
151
114
|
|
152
115
|
begin
|
153
|
-
arg_value = Linen::CLI.
|
116
|
+
arg_value = Linen::CLI.prompt( argument.prompt ) if arg_value.nil?
|
154
117
|
|
155
118
|
result = argument.process( arg_value, :mode => :edit )
|
156
119
|
|
@@ -162,6 +125,8 @@ class Linen::Plugin::TwoPhaseCommand
|
|
162
125
|
results[ arg_name ] = result
|
163
126
|
end
|
164
127
|
rescue Linen::Plugin::ArgumentError => e
|
128
|
+
puts e.message
|
129
|
+
|
165
130
|
# reset arg_value to nil so we get prompted on retry
|
166
131
|
arg_value = nil ; retry
|
167
132
|
end
|
data/lib/linen/workspace.rb
CHANGED
data/lib/string_extensions.rb
CHANGED