[ruby/optparse] Invoke pager for `--help`

https://github.com/ruby/optparse/commit/77dccce37c
This commit is contained in:
Nobuyoshi Nakada 2024-03-01 01:24:05 +09:00 коммит произвёл git
Родитель 9b75e5f085
Коммит 5d76fe6b2a
2 изменённых файлов: 61 добавлений и 2 удалений

Просмотреть файл

@ -1050,6 +1050,26 @@ XXX
to << " '*:file:_files' && return 0\n"
end
def help_exit
if STDOUT.tty? && (pager = ENV.values_at(*%w[RUBY_PAGER PAGER]).find {|e| e && !e.empty?})
less = ENV["LESS"]
args = [{"LESS" => "#{!less || less.empty? ? '-' : less}Fe"}, pager, "w"]
print = proc do |f|
f.puts help
rescue Errno::EPIPE
# pager terminated
end
if Process.respond_to?(:fork) and false
IO.popen("-") {|f| f ? Process.exec(*args, in: f) : print.call(STDOUT)}
# unreachable
end
IO.popen(*args, &print)
else
puts help
end
exit
end
#
# Default options for ARGV, which never appear in option summary.
#
@ -1061,8 +1081,7 @@ XXX
#
Officious['help'] = proc do |parser|
Switch::NoArgument.new do |arg|
puts parser.help
exit
parser.help_exit
end
end

Просмотреть файл

@ -164,4 +164,44 @@ class TestOptionParser < Test::Unit::TestCase
e = assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-t))}
assert_equal(["-t"], e.args)
end
def test_help_pager
require 'tmpdir'
Dir.mktmpdir do |dir|
File.open(File.join(dir, "options.rb"), "w") do |f|
f.puts "#{<<~"begin;"}\n#{<<~'end;'}"
begin;
stdout = STDOUT.dup
def stdout.tty?; true; end
Object.__send__(:remove_const, :STDOUT)
STDOUT = stdout
ARGV.options do |opt|
end;
100.times {|i| f.puts " opt.on('--opt-#{i}') {}"}
f.puts "#{<<~"begin;"}\n#{<<~'end;'}"
begin;
opt.parse!
end
end;
end
optparse = $".find {|path| path.end_with?("/optparse.rb")}
args = ["-r#{optparse}", "options.rb", "--help"]
cmd = File.join(dir, "pager.cmd")
if RbConfig::CONFIG["EXECUTABLE_EXTS"]&.include?(".cmd")
command = "@echo off"
else # if File.executable?("/bin/sh")
# TruffleRuby just calls `posix_spawnp` and no fallback to `/bin/sh`.
command = "#!/bin/sh\n"
end
[
[{"RUBY_PAGER"=>cmd, "PAGER"=>"echo ng"}, "Executing RUBY_PAGER"],
[{"RUBY_PAGER"=>nil, "PAGER"=>cmd}, "Executing PAGER"],
].each do |env, expected|
File.write(cmd, "#{command}\n" "echo #{expected}\n", perm: 0o700)
assert_in_out_err([env, *args], "", [expected], chdir: dir)
end
end
end
end