Skip to content

Commit

Permalink
Merge pull request #265 from JEG2/3_0_0_final
Browse files Browse the repository at this point in the history
Release HighLine 3.0.0 (Ruby 3.3.0)
  • Loading branch information
abinoam committed Jan 5, 2024
2 parents 972222b + 560b6c4 commit b0b7200
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 109 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
os: [ubuntu-latest]
ruby-version:
- head
- '3.3'
- '3.2'
- '3.1'
- '3.0'
Expand All @@ -22,7 +23,7 @@ jobs:
- os: windows-latest
ruby-version: head
- os: windows-latest
ruby-version: '3.1'
ruby-version: '3.3'
- os: windows-latest
ruby-version: mingw
- os: windows-latest
Expand All @@ -32,7 +33,7 @@ jobs:
- os: macos-latest
ruby-version: 'head'
- os: macos-latest
ruby-version: '3.1'
ruby-version: '3.3'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 3 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

Below is a complete listing of changes for each revision of HighLine.

### 3.0.0.pre.1 / 2023-04-27
### 3.0.0 / 2024-01-05
* PR #265 - Change Readline for Reline for Ruby 3.3 compat (@abinoam)
* PR #264 - Add abbrev gem as dependency (@mathieujobin)
* PR #263 - Release 3.0.0.pre.1
* Raise minimum Ruby version requirement to 3.0
* PR #262 - Do not call stty on non-tty (@kbrock)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ For more examples see the examples/ directory of this project.
Requirements
------------

HighLine from version >= 1.7.0 requires ruby >= 1.9.3
HighLine from version >= 3.0.0 requires ruby >= 3.0.0

Installing
----------
Expand Down
1 change: 1 addition & 0 deletions highline.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ DESCRIPTION
spec.add_development_dependency "rake"
spec.add_development_dependency "minitest"
spec.add_development_dependency "dry-types"
spec.add_development_dependency "reline"
end
18 changes: 14 additions & 4 deletions lib/highline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,8 @@ def list(items, mode = :rows, option = nil)
#
# @param statement [Statement, String] what to be said
def say(statement)
statement = render_statement(statement)
return if statement.empty?

statement = (indentation + statement)
statement = render_and_ident_statement(statement)
return statement if statement.empty?

# Don't add a newline if statement ends with whitespace, OR
# if statement ends with whitespace before a color escape code.
Expand All @@ -386,6 +384,18 @@ def say(statement)
end
end

# Renders and indents a statement.
#
# Note: extracted here to be used by readline to render its prompt.
#
# @param statement [String] The statement to be rendered and indented.
# @return [String] The rendered and indented statement.
def render_and_ident_statement(statement)
statement = render_statement(statement)
statement = (indentation + statement) unless statement.empty?
statement
end

# Renders a statement using {HighLine::Statement}
# @param statement [String] any string
# @return [Statement] rendered statement
Expand Down
8 changes: 2 additions & 6 deletions lib/highline/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def initialize(template, answer_type)
#
attr_accessor :echo
#
# Use the Readline library to fetch input. This allows input editing as
# Use the Reline library to fetch input. This allows input editing as
# well as keeping a history. In addition, tab will auto-complete
# within an Array of choices or a file listing.
#
Expand All @@ -125,6 +125,7 @@ def initialize(template, answer_type)
# specified _input_ stream.
#
attr_accessor :readline

#
# Used to control whitespace processing for the answer to this question.
# See HighLine::Question.remove_whitespace() for acceptable settings.
Expand Down Expand Up @@ -580,11 +581,6 @@ def ask_on_error_msg
end
end

# readline() needs to handle its own output, but readline only supports
# full line reading. Therefore if question.echo is anything but true,
# the prompt will not be issued. And we have to account for that now.
# Also, JRuby-1.7's ConsoleReader.readLine() needs to be passed the prompt
# to handle line editing properly.
# @param highline [HighLine] context
# @return [void]
def show_question(highline)
Expand Down
3 changes: 2 additions & 1 deletion lib/highline/question_asker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def initialize(question, highline)
#
# @return [String] answer
def ask_once
question.show_question(@highline)
# If in readline mode, let reline take care of the prompt
question.show_question(@highline) unless question.readline

begin
question.get_response_or_default(@highline)
Expand Down
10 changes: 6 additions & 4 deletions lib/highline/terminal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ def get_line(question, highline)
# Get one line using #readline_read
# @param (see #get_line)
def get_line_with_readline(question, highline)
require "readline" # load only if needed
require "reline" # load only if needed

raw_answer = readline_read(question)
raw_answer = readline_read(question, highline)

if !raw_answer && highline.track_eof?
raise EOFError, "The input stream is exhausted."
Expand All @@ -109,20 +109,22 @@ def get_line_with_readline(question, highline)
# Use readline to read one line
# @param question [HighLine::Question] question from where to get
# autocomplete candidate strings
def readline_read(question)
def readline_read(question, highline)
# prep auto-completion
unless question.selection.empty?
Readline.completion_proc = lambda do |str|
question.selection.grep(/\A#{Regexp.escape(str)}/)
end
end

# TODO: Check if this is still needed after Reline
# work-around ugly readline() warnings
old_verbose = $VERBOSE
$VERBOSE = nil

raw_answer = run_preserving_stty do
Readline.readline("", true)
prompt = highline.render_and_ident_statement(question)
Readline.readline(prompt, true)
end

$VERBOSE = old_verbose
Expand Down
2 changes: 1 addition & 1 deletion lib/highline/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

class HighLine
# The version of the installed library.
VERSION = "3.0.0.pre.1".freeze
VERSION = "3.0.0".freeze
end
5 changes: 5 additions & 0 deletions test/acceptance/acceptance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
rescue NameError
'not availabe'
end}
Reline::VERSION: #{begin
Reline::VERSION
rescue NameError
'not available'
end}
ENV['SHELL']: #{ENV['SHELL']}
ENV['TERM']: #{ENV['TERM']}
ENV['TERM_PROGRAM']: #{ENV['TERM_PROGRAM']}
Expand Down
89 changes: 0 additions & 89 deletions test/test_highline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

require "highline"
require "stringio"
require "readline"
require "tempfile"

# if HighLine::CHARACTER_MODE == "Win32API"
Expand Down Expand Up @@ -387,94 +386,6 @@ def test_after_some_chars_erase_line_does_not_enter_prompt_when_utf8
assert_equal(4, @output.string.count("\b"))
end

def test_readline_mode
#
# Rubinius (and JRuby) seems to be ignoring
# Readline input and output assignments. This
# ruins testing.
#
# But it doesn't mean readline is not working
# properly on rubinius or jruby.
#

terminal = @terminal.terminal

if terminal.jruby? || terminal.rubinius? || terminal.windows?
skip "We can't test Readline on JRuby, Rubinius and Windows yet"
end

# Creating Tempfiles here because Readline.input
# and Readline.output only accepts a File object
# as argument (not any duck type as StringIO)

temp_stdin = Tempfile.new "temp_stdin"
temp_stdout = Tempfile.new "temp_stdout"

Readline.input = @input = File.open(temp_stdin.path, "w+")
Readline.output = @output = File.open(temp_stdout.path, "w+")

@terminal = HighLine.new(@input, @output)

@input << "any input\n"
@input.rewind

answer = @terminal.ask("Prompt: ") do |q|
q.readline = true
end

@output.rewind
output = @output.read

assert_equal "any input", answer
assert_match "Prompt: any input\n", output

@input.close
@output.close
Readline.input = STDIN
Readline.output = STDOUT
end

def test_readline_mode_with_limit_set
temp_stdin = Tempfile.new "temp_stdin"
temp_stdout = Tempfile.new "temp_stdout"

Readline.input = @input = File.open(temp_stdin.path, "w+")
Readline.output = @output = File.open(temp_stdout.path, "w+")

@terminal = HighLine.new(@input, @output)

@input << "any input\n"
@input.rewind

answer = @terminal.ask("Prompt: ") do |q|
q.limit = 50
q.readline = true
end

@output.rewind
output = @output.read

assert_equal "any input", answer
assert_equal "Prompt: any input\n", output

@input.close
@output.close
Readline.input = STDIN
Readline.output = STDOUT
end

def test_readline_on_non_echo_question_has_prompt
@input << "you can't see me"
@input.rewind
answer = @terminal.ask("Please enter some hidden text: ") do |q|
q.readline = true
q.echo = "*"
end
assert_equal("you can't see me", answer)
assert_equal("Please enter some hidden text: ****************\n",
@output.string)
end

def test_character_reading
# WARNING: This method does NOT cover Unix and Windows savvy testing!
@input << "12345"
Expand Down
95 changes: 95 additions & 0 deletions test/test_reline.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
require "test_helper"
require "reline"

class TestReline < Minitest::Test
def setup
HighLine.reset
@input = StringIO.new
@output = StringIO.new
@terminal = HighLine.new(@input, @output)
end

def test_readline_mode
# See #267
skip "We need vterm / yamatanooroti based tests for reline"

# Creating Tempfiles here because Readline.input
# and Readline.output only accepts a File object
# as argument (not any duck type as StringIO)

temp_stdin = Tempfile.new "temp_stdin"
temp_stdout = Tempfile.new "temp_stdout"

Reline.input = @input = File.open(temp_stdin.path, "w+")
Reline.output = @output = File.open(temp_stdout.path, "w+")

@terminal = HighLine.new(@input, @output)

@input << "any input\n"
@input.rewind

answer = @terminal.ask("Prompt: ") do |q|
q.readline = true
end

@output.rewind
output = @output.read

assert_equal "any input", answer
assert_match "Prompt: any input\n", output

@input.close
@output.close
Reline.input = STDIN
Reline.output = STDOUT
end

def test_readline_mode_with_limit_set
temp_stdin = Tempfile.new "temp_stdin"
temp_stdout = Tempfile.new "temp_stdout"

Reline.input = @input = File.open(temp_stdin.path, "w+")
Reline.output = @output = File.open(temp_stdout.path, "w+")

@terminal = HighLine.new(@input, @output)

@input << "any input\n"
@input.rewind

answer = @terminal.ask("Prompt: ") do |q|
q.limit = 50
q.readline = true
end

@output.rewind
output = @output.read

assert_equal "any input", answer

# after migrating to Reline, we can't make assertions about the output
# without using vterm / yamatanooroti. See #267
#
# assert_equal "Prompt: any input\n", output

@input.close
@output.close
Reline.input = STDIN
Reline.output = STDOUT
end

def test_readline_on_non_echo_question_has_prompt
@input << "you can't see me"
@input.rewind
answer = @terminal.ask("Please enter some hidden text: ") do |q|
q.readline = true
q.echo = "*"
end
assert_equal("you can't see me", answer)

# after migrating to Reline, we can't make assertions about the output
# without using vterm / yamatanooroti. See #267
#
# assert_equal("Please enter some hidden text: ****************\n",
# @output.string)
end
end

0 comments on commit b0b7200

Please sign in to comment.