You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
2.1 KiB

# this file contains some utilities copied from the Documenter.jl package
# (https://github.com/JuliaDocs/Documenter.jl), see LICENSE.md for license
module Documenter
using Compat: stdout, stderr, Cvoid
@static if VERSION < v"0.7.0-DEV.3951"
link_pipe!(pipe; reader_supports_async = true, writer_supports_async = true) =
Base.link_pipe(pipe, julia_only_read = reader_supports_async, julia_only_write = writer_supports_async)
else
import Base: link_pipe!
end
@static if isdefined(Base, :with_logger)
using Logging
else # make things a no-op since warnings/info already print to stdout
struct ConsoleLogger end
ConsoleLogger(io) = ConsoleLogger()
with_logger(f, logger) = f()
end
function withoutput(f)
# Save the default output streams.
default_stdout = stdout
default_stderr = stderr
# Redirect both the `stdout` and `stderr` streams to a single `Pipe` object.
pipe = Pipe()
link_pipe!(pipe; reader_supports_async = true, writer_supports_async = true)
redirect_stdout(pipe.in)
redirect_stderr(pipe.in)
# Also redirect logging stream to the same pipe
logger = ConsoleLogger(pipe.in)
# Bytes written to the `pipe` are captured in `output` and converted to a `String`.
output = UInt8[]
# Run the function `f`, capturing all output that it might have generated.
# Success signals whether the function `f` did or did not throw an exception.
result, success, backtrace = with_logger(logger) do
try
f(), true, Vector{Ptr{Cvoid}}()
catch err
err, false, catch_backtrace()
finally
# Force at least a single write to `pipe`, otherwise `readavailable` blocks.
println()
# Restore the original output streams.
redirect_stdout(default_stdout)
redirect_stderr(default_stderr)
# NOTE: `close` must always be called *after* `readavailable`.
append!(output, readavailable(pipe))
close(pipe)
end
end
return result, success, backtrace, chomp(String(output))
end
end