Skip to content

Commit

Permalink
replace all redirection operators with x |> redirect(y)
Browse files Browse the repository at this point in the history
closes #5349
  • Loading branch information
JeffBezanson committed Feb 16, 2015
1 parent 9ef1720 commit ed5b7a4
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 53 deletions.
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,7 @@ export
readline,
readlines,
readuntil,
redirect,
redirect_stderr,
redirect_stdin,
redirect_stdout,
Expand Down
6 changes: 3 additions & 3 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ end
global _clipboardcmd
_clipboardcmd !== nothing && return _clipboardcmd
for cmd in (:xclip, :xsel)
success(`which $cmd` |> DevNull) && return _clipboardcmd = cmd
success(`which $cmd` |> redirect(DevNull)) && return _clipboardcmd = cmd
end
error("no clipboard command found, please install xsel or xclip")
end
Expand Down Expand Up @@ -158,7 +158,7 @@ function versioninfo(io::IO=STDOUT, verbose::Bool=false)
println(io, " WORD_SIZE: ", Sys.WORD_SIZE)
if verbose
lsb = ""
@linux_only try lsb = readchomp(`lsb_release -ds` .> DevNull) end
@linux_only try lsb = readchomp(`lsb_release -ds` |> redirect(stderr=DevNull)) end
@windows_only try lsb = strip(readall(`$(ENV["COMSPEC"]) /c ver`)) end
if lsb != ""
println(io, " ", lsb)
Expand Down Expand Up @@ -333,7 +333,7 @@ downloadcmd = nothing
global downloadcmd
if downloadcmd === nothing
for checkcmd in (:curl, :wget, :fetch)
if success(`which $checkcmd` |> DevNull)
if success(`which $checkcmd` |> redirect(DevNull))
downloadcmd = checkcmd
break
end
Expand Down
2 changes: 1 addition & 1 deletion base/pkg/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function add(pkg::AbstractString, vers::VersionSet)
outdated = :yes
else
try
run(Git.cmd(`fetch -q --all`, dir="METADATA") |>DevNull .>DevNull)
run(Git.cmd(`fetch -q --all`, dir="METADATA") |> redirect(DevNull,stderr=DevNull))
outdated = Git.success(`diff --quiet origin/$branch`, dir="METADATA") ?
(:no) : (:yes)
end
Expand Down
2 changes: 1 addition & 1 deletion base/pkg/generate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ github_user() = readchomp(ignorestatus(`git config --global --get github.user`))
function git_contributors(dir::AbstractString, n::Int=typemax(Int))
contrib = Dict()
tty = @windows? "CON:" : "/dev/tty"
for line in eachline(tty |> Git.cmd(`shortlog -nes`, dir=dir))
for line in eachline(tty |> redirect(Git.cmd(`shortlog -nes`, dir=dir)))
m = match(r"\s*(\d+)\s+(.+?)\s+\<(.+?)\>\s*$", line)
m == nothing && continue
commits, name, email = m.captures
Expand Down
2 changes: 1 addition & 1 deletion base/pkg/git.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function git(d)
end

cmd(args::Cmd; dir="") = `$(git(dir)) $args`
run(args::Cmd; dir="", out=STDOUT) = Base.run(cmd(args,dir=dir) |> out)
run(args::Cmd; dir="", out=STDOUT) = Base.run(cmd(args,dir=dir) |> redirect(out))
readall(args::Cmd; dir="") = Base.readall(cmd(args,dir=dir))
readchomp(args::Cmd; dir="") = Base.readchomp(cmd(args,dir=dir))

Expand Down
62 changes: 38 additions & 24 deletions base/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,30 @@ function show(io::IO, cmd::Cmd)
(print_dir || print_env) && print(io, ")")
end

function show(io::IO, cmds::OrCmds)
function show(io::IO, cmds::Union(OrCmds,ErrOrCmds))
if isa(cmds.a, AndCmds) || isa(cmds.a, CmdRedirect)
print(io, "(")
show(io, cmds.a)
print(io, ")")
else
show(io, cmds.a)
end
print(io, " |> ")
if isa(cmds.b, AndCmds) || isa(cmds.b, CmdRedirect)
print(io, "(")
show(io, cmds.b)
print(io, ")")
else
show(io, cmds.b)
end
print(io, " |> redirect(")
isa(cmds, ErrOrCmds) && print(io, "stderr=")
show(io, cmds.b)
print(io, ")")
end

function show(io::IO, cmds::AndCmds)
if isa(cmds.a, OrCmds) || isa(cmds.a, CmdRedirect)
if isa(cmds.a, OrCmds) || isa(cmds.a, ErrOrCmds) || isa(cmds.a, CmdRedirect)
print(io, "(")
show(io, cmds.a)
print(io, ")")
else
show(io, cmds.a)
end
print(io, " & ")
if isa(cmds.b, OrCmds) || isa(cmds.b, CmdRedirect)
if isa(cmds.a, OrCmds) || isa(cmds.a, ErrOrCmds) || isa(cmds.a, CmdRedirect)
print(io, "(")
show(io, cmds.b)
print(io, ")")
Expand Down Expand Up @@ -122,16 +118,19 @@ end
function show(io::IO, cr::CmdRedirect)
if cr.stream_no == STDOUT_NO
show(io, cr.cmd)
print(io, " |> ")
print(io, " |> redirect(")
show(io, cr.handle)
print(io, ")")
elseif cr.stream_no == STDERR_NO
show(io, cr.cmd)
print(io, " .> ")
print(io, " |> redirect(stderr=")
show(io, cr.handle)
print(io, ")")
elseif cr.stream_no == STDIN_NO
show(io, cr.handle)
print(io, " |> ")
print(io, " |> redirect(")
show(io, cr.cmd)
print(io, ")")
end
end

Expand All @@ -145,21 +144,36 @@ setenv(cmd::Cmd, env::Associative; dir="") = (cmd.env = ByteString[string(k)*"="
setenv(cmd::Cmd; dir="") = (cmd.dir = dir; cmd)

(&)(left::AbstractCmd, right::AbstractCmd) = AndCmds(left, right)
(|>)(src::AbstractCmd, dest::AbstractCmd) = OrCmds(src, dest)
(.>)(src::AbstractCmd, dest::AbstractCmd) = ErrOrCmds(src, dest)
redir_out(src::AbstractCmd, dest::AbstractCmd) = OrCmds(src, dest)
redir_err(src::AbstractCmd, dest::AbstractCmd) = ErrOrCmds(src, dest)

# Stream Redirects
(|>)(dest::Redirectable, src::AbstractCmd) = CmdRedirect(src, dest, STDIN_NO)
(|>)(src::AbstractCmd, dest::Redirectable) = CmdRedirect(src, dest, STDOUT_NO)
(.>)(src::AbstractCmd, dest::Redirectable) = CmdRedirect(src, dest, STDERR_NO)
redir_out(dest::Redirectable, src::AbstractCmd) = CmdRedirect(src, dest, STDIN_NO)
redir_out(src::AbstractCmd, dest::Redirectable) = CmdRedirect(src, dest, STDOUT_NO)
redir_err(src::AbstractCmd, dest::Redirectable) = CmdRedirect(src, dest, STDERR_NO)

# File redirects
(|>)(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, false), STDOUT_NO)
(|>)(src::AbstractString, dest::AbstractCmd) = CmdRedirect(dest, FileRedirect(src, false), STDIN_NO)
(.>)(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, false), STDERR_NO)
(>>)(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDOUT_NO)
(.>>)(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDERR_NO)
redir_out(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, false), STDOUT_NO)
redir_out(src::AbstractString, dest::AbstractCmd) = CmdRedirect(dest, FileRedirect(src, false), STDIN_NO)
redir_err(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, false), STDERR_NO)
redir_out_append(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDOUT_NO)
redir_err_append(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDERR_NO)

function redirect(stdout; stderr=nothing, append=false)
if stderr !== nothing
if append
cmd->redir_err_append(redir_out_append(cmd, stdout), stderr)
else
cmd->redir_err(redir_out(cmd, stdout), stderr)
end
else
append ? cmd->redir_out_append(cmd, stdout) : cmd->redir_out(cmd, stdout)
end
end

function redirect(; stderr=error("must specify something to redirect to"), append=false)
append ? cmd->redir_err_append(cmd, stderr) : cmd->redir_err(cmd, stderr)
end

typealias RawOrBoxedHandle Union(UVHandle,UVStream,Redirectable,IOStream)
typealias StdIOSet NTuple{3,RawOrBoxedHandle}
Expand Down
2 changes: 1 addition & 1 deletion base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function make_seed()
seed = reinterpret(UInt64, time())
seed = hash(seed, uint64(getpid()))
try
seed = hash(seed, parseint(UInt64, readall(`ifconfig` |> `sha1sum`)[1:40], 16))
seed = hash(seed, parseint(UInt64, readall(`ifconfig` |> redirect(`sha1sum`))[1:40], 16))
end
return make_seed(seed)
end
Expand Down
42 changes: 21 additions & 21 deletions test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ yes = `perl -le 'while (1) {print STDOUT "y"}'`
#### Examples used in the manual ####

@test readall(`echo hello | sort`) == "hello | sort\n"
@test readall(`echo hello` |> `sort`) == "hello\n"
@test length(spawn(`echo hello` |> `sort`).processes) == 2
@test readall(`echo hello` |> redirect(`sort`)) == "hello\n"
@test length(spawn(`echo hello` |> redirect(`sort`)).processes) == 2

out = readall(`echo hello` & `echo world`)
@test search(out,"world") != (0,0)
@test search(out,"hello") != (0,0)
@test readall((`echo hello` & `echo world`) |> `sort`)=="hello\nworld\n"
@test readall((`echo hello` & `echo world`) |> redirect(`sort`))=="hello\nworld\n"

@test (run(`printf " \033[34m[stdio passthrough ok]\033[0m\n"`); true)

# Test for SIGPIPE being treated as normal termination (throws an error if broken)
@unix_only @test (run(yes|>`head`|>DevNull); true)
@unix_only @test (run(yes|>redirect(`head`)|>redirect(DevNull)); true)

begin
a = Base.Condition()
@schedule begin
p = spawn(yes|>DevNull)
p = spawn(yes|>redirect(DevNull))
Base.notify(a,p)
@test !success(p)
end
Expand All @@ -43,29 +43,29 @@ end
if false
prefixer(prefix, sleep) = `perl -nle '$|=1; print "'$prefix' ", $_; sleep '$sleep';'`
@test success(`perl -le '$|=1; for(0..2){ print; sleep 1 }'` |>
prefixer("A",2) & prefixer("B",2))
redirect(prefixer("A",2) & prefixer("B",2)))
@test success(`perl -le '$|=1; for(0..2){ print; sleep 1 }'` |>
prefixer("X",3) & prefixer("Y",3) & prefixer("Z",3) |>
prefixer("A",2) & prefixer("B",2))
redirect(prefixer("X",3) & prefixer("Y",3) & prefixer("Z",3)) |>
redirect(prefixer("A",2) & prefixer("B",2)))
end

@test success(`true`)
@test !success(`false`)
@test success(`true` |> `true`)
@test success(`true` |> redirect(`true`))
if false
@test success(ignorestatus(`false`))
@test success(ignorestatus(`false`) |> `true`)
@test !success(ignorestatus(`false`) |> `false`)
@test success(ignorestatus(`false`) |> redirect(`true`))
@test !success(ignorestatus(`false`) |> redirect(`false`))
@test !success(ignorestatus(`false`) & `false`)
@test success(ignorestatus(`false` |> `false`))
@test success(ignorestatus(`false` |> redirect(`false`)))
@test success(ignorestatus(`false` & `false`))
end

# STDIN Redirection
file = tempname()
run(`echo hello world` |> file)
@test readall(file |> `cat`) == "hello world\n"
@test open(readall, file |> `cat`, "r") == "hello world\n"
run(`echo hello world` |> redirect(file))
@test readall(file |> redirect(`cat`)) == "hello world\n"
@test open(readall, file |> redirect(`cat`), "r") == "hello world\n"
rm(file)

# Stream Redirection
Expand All @@ -75,12 +75,12 @@ rm(file)
port, server = listenany(2326)
put!(r,port)
client = accept(server)
@test readall(client |> `cat`) == "hello world\n"
@test readall(client |> redirect(`cat`)) == "hello world\n"
close(server)
end
@async begin
sock = connect(fetch(r))
run(`echo hello world` |> sock)
run(`echo hello world` |> redirect(sock))
close(sock)
end
end
Expand All @@ -102,7 +102,7 @@ str2 = readall(stdout)

# This test hangs if the end of run walk across uv streams calls shutdown on a stream that is shutting down.
file = tempname()
open(`cat -` |> file, "w") do io
open(`cat -` |> redirect(file), "w") do io
write(io, str)
end
rm(file)
Expand Down Expand Up @@ -154,13 +154,13 @@ close(sock)

# issue #4535
exename=joinpath(JULIA_HOME,(ccall(:jl_is_debugbuild,Cint,())==0?"julia":"julia-debug"))
@test readall(`$exename -f -e 'println(STDERR,"Hello World")'` .> `cat`) == "Hello World\n"
@test readall(`$exename -f -e 'println(STDERR,"Hello World")'` |> redirect(stderr=`cat`)) == "Hello World\n"

# issue #6310
@test readall(`echo "2+2"` |> `$exename -f`) == "4\n"
@test readall(`echo "2+2"` |> redirect(`$exename -f`)) == "4\n"

# issue #5904
@test run(ignorestatus(`false`) |> `true`) === nothing
@test run(ignorestatus(`false`) |> redirect(`true`)) === nothing


# issue #6010
Expand Down
2 changes: 1 addition & 1 deletion test/unicode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ else
for encoding in ["UTF-32LE", "UTF-16BE", "UTF-16LE", "UTF-8"]
output_path = joinpath(unicodedir, encoding*".unicode")
f = Base.FS.open(output_path,Base.JL_O_WRONLY|Base.JL_O_CREAT,Base.S_IRUSR | Base.S_IWUSR | Base.S_IRGRP | Base.S_IROTH)
run(`iconv -f $primary_encoding -t $encoding $primary_path` |> f)
run(`iconv -f $primary_encoding -t $encoding $primary_path` |> redirect(f))
Base.FS.close(f)
end

Expand Down

2 comments on commit ed5b7a4

@StefanKarpinski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a pretty serious pessimization of brevity. Can't we keep the old behavior and use this for complicated redirects only?

@ViralBShah
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearly he is not into the whole brevity thing. ;-)

http://www.imdb.com/title/tt0118715/quotes?item=qt0464813

Please sign in to comment.