Skip to content

Commit

Permalink
Fix IO.popen
Browse files Browse the repository at this point in the history
  • Loading branch information
soutaro committed Dec 20, 2023
1 parent ceb28c5 commit 851c63b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
17 changes: 13 additions & 4 deletions core/io.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2533,10 +2533,19 @@ class IO < Object
#
# Raises exceptions that IO.pipe and Kernel.spawn raise.
#
def self.popen: (string cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) -> instance
| (Hash[string, string?] env, string cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) -> instance
| [X] (string cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) { (instance) -> X } -> X
| [X] (Hash[string, string?] env, string cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) { (instance) -> X } -> X
def self.popen: (string | cmd_array cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) -> instance
| (Hash[string, string?] env, string | cmd_array cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) -> instance
| [X] (string | cmd_array cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) { (instance) -> X } -> X
| [X] (Hash[string, string?] env, string | cmd_array cmd, ?string | int mode, ?path: string?, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: String, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: Kernel::redirect_fd, ?out: Kernel::redirect_fd, ?err: Kernel::redirect_fd, ?close_others: boolish, ?chdir: String) { (instance) -> X } -> X

# The command can be given as:
#
# * Array of string `["ruby", "-v"]`, or
# * Array of string with the first element of array `[["ruby", "RUBY"], "-v"]`
#
# But RBS cannot define such a type. So this is simply a union of `string` or `[String, String]`.
#
type cmd_array = array[string | [String, String]]

# <!--
# rdoc-file=io.c
Expand Down
32 changes: 32 additions & 0 deletions test/stdlib/IO_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,38 @@ def test_open
end
end

def ruby
ENV["RUBY"] || RbConfig.ruby
end

def test_popen
with_string("#{ruby} -v") do |command|
assert_send_type(
"(string) { (IO) -> nil } -> nil",
IO, :popen, command, &proc { nil }
)

assert_send_type(
"(Hash[String, String], string) { (IO) -> nil } -> nil",
IO, :popen, { "RUBYOPT" => "-I lib" }, command, &proc { nil }
)
end

with_string("ruby") do |ruby|
with_array(ruby, "-v") do |cmd|
assert_send_type(
"(array[string]) { (IO) -> nil } -> nil",
IO, :popen, cmd, &proc { nil }
)

assert_send_type(
"(Hash[String, String], array[string]) { (IO) -> nil } -> nil",
IO, :popen, { "RUBYOPT" => "-I lib" }, cmd, &proc { nil }
)
end
end
end

def test_copy_stream
Dir.mktmpdir do |dir|
src_name = File.join(dir, "src_file").tap { |f| IO.write(f, "foo") }
Expand Down

0 comments on commit 851c63b

Please sign in to comment.