Skip to content

Commit 1045be8

Browse files
committed
refactor: run now return stdout or stderr with status
with Exec::IO::MultiWriter we can print and get output both Update CI, remove spec random option
1 parent 90d4d26 commit 1045be8

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ jobs:
3535
- name: Check formatting
3636
run: crystal tool format --check
3737
- name: Run tests
38-
run: crystal spec --order=random
38+
run: crystal spec

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: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@ 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 "looks like ruby Open3 when bad" 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+
41+
it "looks like ruby IO.popen" do
42+
r = Process.run("bash") do |process|
43+
process.input.puts "uname"
44+
process.input.close
45+
process.output.gets_to_end
46+
end
47+
48+
r.should eq "Linux\n"
49+
end
50+
2451
it "get Linux\n" do
2552
Exec.output("uname", false).should eq "Linux\n"
2653
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)