linen 0.6.4 → 0.7.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/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