highline 1.0.4 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README +33 -1
- data/Rakefile +6 -5
- data/lib/highline.rb +7 -0
- data/lib/highline/import.rb +16 -0
- data/lib/highline/menu.rb +20 -0
- data/lib/highline/question.rb +20 -0
- data/test/tc_highline.rb +7 -0
- data/test/tc_import.rb +26 -0
- data/test/tc_menu.rb +40 -0
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of HighLine.
|
4
4
|
|
5
|
+
== 1.2.0
|
6
|
+
|
7
|
+
* Improved RubyForge and gem spec project descriptions.
|
8
|
+
* Added basic examples to README.
|
9
|
+
* Added a VERSION constant.
|
10
|
+
* Added support for hidden menu commands.
|
11
|
+
* Added Object.or_ask() when using highline/import.
|
12
|
+
|
5
13
|
== 1.0.4
|
6
14
|
|
7
15
|
* Moved the HighLine project to Subversion.
|
data/README
CHANGED
@@ -19,7 +19,39 @@ See HighLine and HighLine::Question for documentation.
|
|
19
19
|
|
20
20
|
== Examples
|
21
21
|
|
22
|
-
|
22
|
+
Basic usage:
|
23
|
+
|
24
|
+
ask("Company? ") { |q| q.default = "none" }
|
25
|
+
|
26
|
+
Validation:
|
27
|
+
|
28
|
+
ask("Age? ", Integer) { |q| q.in = 0..105 }
|
29
|
+
ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
|
30
|
+
|
31
|
+
Type conversion for answers:
|
32
|
+
|
33
|
+
ask("Birthday? ", Date)
|
34
|
+
ask("Interests? (comma sep list) ", lambda { |str| str.split(/,\s*/) })
|
35
|
+
|
36
|
+
Reading passwords:
|
37
|
+
|
38
|
+
ask("Enter your password: ") { |q| q.echo = false }
|
39
|
+
ask("Enter your password: ") { |q| q.echo = "x" }
|
40
|
+
|
41
|
+
ERb based output (with HighLine's ANSI color tools):
|
42
|
+
|
43
|
+
say("This should be <%= color('bold', BOLD) %>!")
|
44
|
+
|
45
|
+
Menus:
|
46
|
+
|
47
|
+
choose do |menu|
|
48
|
+
menu.prompt = "Please choose your favorite programming language? "
|
49
|
+
|
50
|
+
menu.choice(:ruby) { say("Good choice!") }
|
51
|
+
menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
52
|
+
end
|
53
|
+
|
54
|
+
For more examples see the examples/ directory of this project.
|
23
55
|
|
24
56
|
== Installing
|
25
57
|
|
data/Rakefile
CHANGED
@@ -32,9 +32,9 @@ end
|
|
32
32
|
|
33
33
|
spec = Gem::Specification.new do |spec|
|
34
34
|
spec.name = "highline"
|
35
|
-
spec.version = "1.0
|
35
|
+
spec.version = "1.2.0"
|
36
36
|
spec.platform = Gem::Platform::RUBY
|
37
|
-
spec.summary = "HighLine is a high-level line
|
37
|
+
spec.summary = "HighLine is a high-level command-line IO library."
|
38
38
|
spec.files = Dir.glob("{examples,lib,test}/**/*.rb").
|
39
39
|
delete_if { |item| item.include?("CVS") } +
|
40
40
|
["Rakefile", "setup.rb"]
|
@@ -55,9 +55,10 @@ spec = Gem::Specification.new do |spec|
|
|
55
55
|
spec.rubyforge_project = "highline"
|
56
56
|
spec.homepage = "http://highline.rubyforge.org"
|
57
57
|
spec.description = <<END_DESC
|
58
|
-
A
|
59
|
-
|
60
|
-
|
58
|
+
A high-level IO library that provides validation, type conversion, and more for
|
59
|
+
command-line interfaces. HighLine also includes a complete menu system that can
|
60
|
+
crank out anything from simple list selection to complete shells with just
|
61
|
+
minutes of work.
|
61
62
|
END_DESC
|
62
63
|
end
|
63
64
|
|
data/lib/highline.rb
CHANGED
@@ -26,6 +26,9 @@ require "abbrev"
|
|
26
26
|
# checking, convert types, etc.
|
27
27
|
#
|
28
28
|
class HighLine
|
29
|
+
# The version of the installed library.
|
30
|
+
VERSION = "1.2.0".freeze
|
31
|
+
|
29
32
|
# An internal HighLine error. User code does not need to trap this.
|
30
33
|
class QuestionError < StandardError
|
31
34
|
# do nothing, just creating a unique error type
|
@@ -581,9 +584,13 @@ class HighLine
|
|
581
584
|
# Character input will be returned as a single character String,
|
582
585
|
# not an Integer.
|
583
586
|
#
|
587
|
+
# This question's _first_answer_ will be returned instead of input, if set.
|
588
|
+
#
|
584
589
|
# Raises EOFError if input is exhausted.
|
585
590
|
#
|
586
591
|
def get_response( )
|
592
|
+
return @question.first_answer if @question.first_answer?
|
593
|
+
|
587
594
|
if @question.character.nil?
|
588
595
|
if @question.echo == true and @question.limit.nil?
|
589
596
|
get_line
|
data/lib/highline/import.rb
CHANGED
@@ -25,3 +25,19 @@ module Kernel
|
|
25
25
|
extend Forwardable
|
26
26
|
def_delegators :$terminal, :agree, :ask, :choose, :say
|
27
27
|
end
|
28
|
+
|
29
|
+
class Object
|
30
|
+
#
|
31
|
+
# Tries this object as a _first_answer_ for a HighLine::Question. See that
|
32
|
+
# attribute for details.
|
33
|
+
#
|
34
|
+
# *Warning*: This Object will be passed to String() before set.
|
35
|
+
#
|
36
|
+
def or_ask( *args, &details )
|
37
|
+
ask(*args) do |question|
|
38
|
+
question.first_answer = String(self) unless nil?
|
39
|
+
|
40
|
+
details.call(question) unless details.nil?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/highline/menu.rb
CHANGED
@@ -31,6 +31,7 @@ class HighLine
|
|
31
31
|
super("Ignored", [ ], &nil) # avoiding passing the block along
|
32
32
|
|
33
33
|
@items = [ ]
|
34
|
+
@hidden_items = [ ]
|
34
35
|
@help = Hash.new("There's no help for that topic.")
|
35
36
|
|
36
37
|
@index = :number
|
@@ -150,6 +151,13 @@ class HighLine
|
|
150
151
|
def choices( *names, &action )
|
151
152
|
names.each { |n| choice(n, &action) }
|
152
153
|
end
|
154
|
+
|
155
|
+
# Identical to choice(), but the item will not be listed for the user.
|
156
|
+
def hidden( name, help = nil, &action )
|
157
|
+
@hidden_items << [name, action]
|
158
|
+
|
159
|
+
@help[name.to_s.downcase] = help unless help.nil?
|
160
|
+
end
|
153
161
|
|
154
162
|
#
|
155
163
|
# Sets the indexing style for this Menu object. Indexes are appended to
|
@@ -255,6 +263,9 @@ class HighLine
|
|
255
263
|
# on the settings of _index_ and _select_by_.
|
256
264
|
#
|
257
265
|
def options( )
|
266
|
+
# add in any hidden menu commands
|
267
|
+
@items.concat(@hidden_items)
|
268
|
+
|
258
269
|
by_index = if @index == :letter
|
259
270
|
l_index = "`"
|
260
271
|
@items.map { "#{l_index.succ!}" }
|
@@ -271,6 +282,9 @@ class HighLine
|
|
271
282
|
else
|
272
283
|
by_index + by_name
|
273
284
|
end
|
285
|
+
ensure
|
286
|
+
# make sure the hidden items are removed, before we return
|
287
|
+
@items.slice!(@items.size - @hidden_items.size, @hidden_items.size)
|
274
288
|
end
|
275
289
|
|
276
290
|
#
|
@@ -279,6 +293,9 @@ class HighLine
|
|
279
293
|
# selection, it will be executed as described in Menu.choice().
|
280
294
|
#
|
281
295
|
def select( highline_context, selection, details = nil )
|
296
|
+
# add in any hidden menu commands
|
297
|
+
@items.concat(@hidden_items)
|
298
|
+
|
282
299
|
# Find the selected action.
|
283
300
|
name, action = if selection =~ /^\d+$/
|
284
301
|
@items[selection.to_i - 1]
|
@@ -301,6 +318,9 @@ class HighLine
|
|
301
318
|
else
|
302
319
|
nil
|
303
320
|
end
|
321
|
+
ensure
|
322
|
+
# make sure the hidden items are removed, before we return
|
323
|
+
@items.slice!(@items.size - @hidden_items.size, @hidden_items.size)
|
304
324
|
end
|
305
325
|
|
306
326
|
#
|
data/lib/highline/question.rb
CHANGED
@@ -49,6 +49,7 @@ class HighLine
|
|
49
49
|
@in = nil
|
50
50
|
@confirm = nil
|
51
51
|
@gather = false
|
52
|
+
@first_answer = nil
|
52
53
|
@directory = Pathname.new(File.expand_path(File.dirname($0)))
|
53
54
|
@glob = "*"
|
54
55
|
@responses = Hash.new
|
@@ -144,6 +145,13 @@ class HighLine
|
|
144
145
|
# question is evaluated, so you can use it in your question.
|
145
146
|
#
|
146
147
|
attr_accessor :gather
|
148
|
+
#
|
149
|
+
# When set to a non *nil* value, this will be tried as an answer to the
|
150
|
+
# question. If this answer passes validations, it will become the result
|
151
|
+
# without the user ever being prompted. Otherwise this value is discarded,
|
152
|
+
# and this Question is resolved as a normal call to HighLine.ask().
|
153
|
+
#
|
154
|
+
attr_writer :first_answer
|
147
155
|
#
|
148
156
|
# The directory from which a user will be allowed to select files, when
|
149
157
|
# File or Pathname is specified as an _answer_type_. Initially set to
|
@@ -323,6 +331,18 @@ class HighLine
|
|
323
331
|
else expected[0..-2].join(", ") + ", and #{expected.last}"
|
324
332
|
end
|
325
333
|
end
|
334
|
+
|
335
|
+
# Returns _first_answer_, which will be unset following this call.
|
336
|
+
def first_answer( )
|
337
|
+
@first_answer
|
338
|
+
ensure
|
339
|
+
@first_answer = nil
|
340
|
+
end
|
341
|
+
|
342
|
+
# Returns true if _first_answer_ is set.
|
343
|
+
def first_answer?( )
|
344
|
+
not @first_answer.nil?
|
345
|
+
end
|
326
346
|
|
327
347
|
#
|
328
348
|
# Returns +true+ if the _answer_object_ is greater than the _above_
|
data/test/tc_highline.rb
CHANGED
@@ -763,4 +763,11 @@ class TestHighLine < Test::Unit::TestCase
|
|
763
763
|
@terminal.say("-=" * 50)
|
764
764
|
assert_equal(("-=" * 40 + "\n") + ("-=" * 10 + "\n"), @output.string)
|
765
765
|
end
|
766
|
+
|
767
|
+
def test_version
|
768
|
+
assert_not_nil(HighLine::VERSION)
|
769
|
+
assert_instance_of(String, HighLine::VERSION)
|
770
|
+
assert(HighLine::VERSION.frozen?)
|
771
|
+
assert_match(/\A\d\.\d\.\d\Z/, HighLine::VERSION)
|
772
|
+
end
|
766
773
|
end
|
data/test/tc_import.rb
CHANGED
@@ -20,9 +20,35 @@ class TestImport < Test::Unit::TestCase
|
|
20
20
|
assert_respond_to(self, :say)
|
21
21
|
end
|
22
22
|
|
23
|
+
def test_or_ask
|
24
|
+
old_terminal = $terminal
|
25
|
+
|
26
|
+
input = StringIO.new
|
27
|
+
output = StringIO.new
|
28
|
+
$terminal = HighLine.new(input, output)
|
29
|
+
|
30
|
+
input << "10\n"
|
31
|
+
input.rewind
|
32
|
+
|
33
|
+
assert_equal(10, nil.or_ask("How much? ", Integer))
|
34
|
+
|
35
|
+
input.rewind
|
36
|
+
|
37
|
+
assert_equal(20, "20".or_ask("How much? ", Integer))
|
38
|
+
assert_equal(20, 20.or_ask("How much? ", Integer))
|
39
|
+
|
40
|
+
assert_equal(10, 20.or_ask("How much? ", Integer) { |q| q.in = 1..10 })
|
41
|
+
ensure
|
42
|
+
$terminal = old_terminal
|
43
|
+
end
|
44
|
+
|
23
45
|
def test_redirection
|
46
|
+
old_terminal = $terminal
|
47
|
+
|
24
48
|
$terminal = HighLine.new(nil, (output = StringIO.new))
|
25
49
|
say("Testing...")
|
26
50
|
assert_equal("Testing...\n", output.string)
|
51
|
+
ensure
|
52
|
+
$terminal = old_terminal
|
27
53
|
end
|
28
54
|
end
|
data/test/tc_menu.rb
CHANGED
@@ -304,6 +304,46 @@ class TestMenu < Test::Unit::TestCase
|
|
304
304
|
assert_equal("Sample1", selected)
|
305
305
|
end
|
306
306
|
|
307
|
+
def test_hidden
|
308
|
+
@input << "Hidden\n4\n"
|
309
|
+
@input.rewind
|
310
|
+
|
311
|
+
selected = @terminal.choose do |menu|
|
312
|
+
menu.choice "Sample1"
|
313
|
+
menu.choice "Sample2"
|
314
|
+
menu.choice "Sample3"
|
315
|
+
menu.hidden "Hidden!"
|
316
|
+
end
|
317
|
+
assert_equal("Hidden!", selected)
|
318
|
+
assert_equal("1. Sample1\n2. Sample2\n3. Sample3\n? ", @output.string)
|
319
|
+
|
320
|
+
@input.rewind
|
321
|
+
|
322
|
+
selected = @terminal.choose do |menu|
|
323
|
+
menu.select_by = :index
|
324
|
+
|
325
|
+
menu.choice "Sample1"
|
326
|
+
menu.choice "Sample2"
|
327
|
+
menu.choice "Sample3"
|
328
|
+
menu.hidden "Hidden!"
|
329
|
+
end
|
330
|
+
assert_equal("Hidden!", selected)
|
331
|
+
|
332
|
+
@input.rewind
|
333
|
+
|
334
|
+
selected = @terminal.choose do |menu|
|
335
|
+
menu.select_by = :name
|
336
|
+
|
337
|
+
menu.choice "Sample1"
|
338
|
+
menu.choice "Sample2"
|
339
|
+
menu.choice "Sample3"
|
340
|
+
menu.hidden "Hidden!"
|
341
|
+
end
|
342
|
+
assert_equal("Hidden!", selected)
|
343
|
+
|
344
|
+
@input.rewind
|
345
|
+
end
|
346
|
+
|
307
347
|
def test_select_by_letter
|
308
348
|
@input << "b\n"
|
309
349
|
@input.rewind
|
metadata
CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: highline
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0
|
7
|
-
date: 2006-
|
8
|
-
summary: HighLine is a high-level line
|
6
|
+
version: 1.2.0
|
7
|
+
date: 2006-03-22 00:00:00 -06:00
|
8
|
+
summary: HighLine is a high-level command-line IO library.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: james@grayproductions.net
|
12
12
|
homepage: http://highline.rubyforge.org
|
13
13
|
rubyforge_project: highline
|
14
|
-
description:
|
14
|
+
description: A high-level IO library that provides validation, type conversion, and more for command-line interfaces. HighLine also includes a complete menu system that can crank out anything from simple list selection to complete shells with just minutes of work.
|
15
15
|
autorequire: highline
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|