Skip to content

Commit 18191c0

Browse files
committed
refactor: run now return stdout or stderr with status
with Exec::IO::MultiWriter we can print and get output both
1 parent 90d4d26 commit 18191c0

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: exec
2-
version: 0.1.1
2+
version: 0.2.0
33

44
authors:
55
- initdc <initd@outlook.com>

spec/exec_spec.cr

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@ describe Exec do
2121
Exec.output("uname").should eq "Linux"
2222
end
2323

24+
it "get Linux\n" do
25+
Exec.run("uname").should eq "Linux\n"
26+
end
27+
28+
it "get Linux\n" do
29+
r = Exec.run("echo good && echo bad >&2 && exit 1")
30+
case r
31+
when String
32+
r.chomp.should eq "good"
33+
else
34+
o, e, s = r
35+
o.chomp.should eq "good"
36+
e.chomp.should eq "bad"
37+
s.exit_code.should eq 1
38+
end
39+
end
40+
2441
it "get Linux\n" do
2542
Exec.output("uname", false).should eq "Linux\n"
2643
end

src/exec.cr

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,47 @@
11
class Exec < Process
2-
VERSION = "0.1.1"
2+
VERSION = "0.2.0"
3+
4+
class IO
5+
class MultiWriter < ::IO::MultiWriter
6+
alias IO = ::IO | ::IO::FileDescriptor | ::String::Builder
7+
8+
def read(slice : Bytes) : NoReturn
9+
raise ::IO::Error.new("Can't read from IO::MultiWriter")
10+
end
11+
end
12+
end
313

414
def self.run(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = true,
5-
input : Stdio = Redirect::Inherit, output : Stdio = Redirect::Inherit, error : Stdio = Redirect::Inherit, chdir : Path | String? = nil) : Process::Status
6-
status = new(command, args, env, clear_env, shell, input, output, error, chdir).wait
15+
input : Stdio = Redirect::Inherit, output : Stdio = Redirect::Inherit, error : Stdio = Redirect::Inherit, chdir : Path | String? = nil) : String | {String, String, Process::Status}
16+
output_strio = String::Builder.new
17+
error_strio = String::Builder.new
18+
19+
output_writer = if output.is_a?(Redirect)
20+
output == Redirect::Close ? output : Exec::IO::MultiWriter.new(STDOUT, output_strio)
21+
else
22+
Exec::IO::MultiWriter.new(STDOUT, output, output_strio)
23+
end
24+
25+
error_writer = if error.is_a?(Redirect)
26+
error == Redirect::Close ? error : Exec::IO::MultiWriter.new(STDERR, error_strio)
27+
else
28+
Exec::IO::MultiWriter.new(STDERR, error, error_strio)
29+
end
30+
31+
status = new(command, args, env, clear_env, shell, input, output_writer, error_writer, chdir).wait
732
$? = status
8-
status
33+
34+
output.close unless output.is_a?(Redirect)
35+
error.close unless error.is_a?(Redirect)
36+
output_strio.close
37+
error_strio.close
38+
39+
case status.success?
40+
when true
41+
output_strio.to_s
42+
else
43+
{output_strio.to_s, error_strio.to_s, status}
44+
end
945
end
1046

1147
def self.code(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = true,

0 commit comments

Comments
 (0)