Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate output step in favour of into: File.stream!(path) #231

Merged
merged 2 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ jobs:
runs-on: ubuntu-20.04
env:
MIX_ENV: test
# TODO: Remove on Req 1.0
REQ_NOWARN_OUTPUT: true
strategy:
fail-fast: false
matrix:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ resp.body #=> %File.Stream{}

* Fix typespecs for some functions

* Deprecate [`output`] step in favour of `into: File.stream!(path)`.

* Rename `follow_redirects` step to [`redirect`]

* [`redirect`]: Rename `:follow_redirects` option to `:redirect`.
Expand Down
14 changes: 5 additions & 9 deletions lib/req.ex
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,6 @@ defmodule Req do

* `:decode_json` - options to pass to `Jason.decode!/2`, defaults to `[]`.

* `:output` - if set, writes the response body to a file (via
[`output`](`Req.Steps.output/1`) step). Can be set to a string path or an atom
`:remote_name` which would use the remote name as the filename in the current working
directory. Once the file is written, the response body is replaced with `""`.

Setting `:output` also sets the `decode_body: false` option to prevent decoding the
response before writing it to the file.

* `:into` - where to send the response body. It can be one of:

* `nil` - (default) read the whole response body and store it in the `response.body`
Expand Down Expand Up @@ -302,7 +294,6 @@ defmodule Req do
:raw,
:decode_body,
:decode_json,
:output,
:redirect,
:redirect_trusted,
:redirect_log_level,
Expand All @@ -323,6 +314,7 @@ defmodule Req do
:unix_socket,

# TODO: Remove on Req 1.0
:output,
:follow_redirects,
:location_trusted
])
Expand Down Expand Up @@ -417,6 +409,10 @@ defmodule Req do

{request_options, options} = Keyword.split(options, request_option_names)

if options[:output] && unquote(!System.get_env("REQ_NOWARN_OUTPUT")) do
IO.warn("setting `output: path` is deprecated in favour of `into: File.stream!(path)`")
end

registered =
MapSet.union(
request.registered_options,
Expand Down
30 changes: 5 additions & 25 deletions lib/req/steps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1151,30 +1151,7 @@ defmodule Req.Steps do
end
end

@doc """
Writes the response body to a file.

After the output file is written, the response body is set to `""`.

## Request Options

* `:output` - if set, writes the response body to a file. Can be one of:

* `path` - writes to the given path

* `:remote_name` - uses the remote name as the filename in the current working directory

## Examples

iex> Req.get!("https://elixir-lang.org/index.html", output: "/tmp/elixir_home.html")
iex> File.exists?("/tmp/elixir_home.html")
true

iex> Req.get!("https://elixir-lang.org/blog/index.html", output: :remote_name)
iex> File.exists?("index.html")
true
"""
@doc step: :response
@doc false
def output(request_response)

def output({request, response}) do
Expand Down Expand Up @@ -1253,9 +1230,12 @@ defmodule Req.Steps do
end

def decode_body({request, response}) do
# TODO: remove on Req 1.0
output? = request.options[:output] not in [nil, false]

if request.options[:raw] == true or
request.options[:decode_body] == false or
request.options[:output] not in [nil, false] or
output? or
Req.Response.get_header(response, "content-encoding") != [] do
{request, response}
else
Expand Down
24 changes: 14 additions & 10 deletions test/req/steps_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,20 @@
end

describe "output" do
unless System.get_env("REQ_NOWARN_OUTPUT") do
@describetag :skip
end

@tag :tmp_dir
test "decode_body with output", c do
Bypass.expect(c.bypass, "GET", "/", fn conn ->
json(conn, 200, %{a: 1})
end)

assert Req.get!(c.url, output: c.tmp_dir <> "/a.json").body == ""
assert File.read!(c.tmp_dir <> "/a.json") == ~s|{"a":1}|
end

@tag :tmp_dir
test "path (compressed)", c do
Bypass.expect_once(c.bypass, "GET", "/foo.txt", fn conn ->
Expand Down Expand Up @@ -477,16 +491,6 @@
assert Req.get!(c.url, decode_json: [keys: :atoms]).body == %{a: 1}
end

@tag :tmp_dir
test "with output", c do
Bypass.expect(c.bypass, "GET", "/", fn conn ->
json(conn, 200, %{a: 1})
end)

assert Req.get!(c.url, output: c.tmp_dir <> "/a.json").body == ""
assert File.read!(c.tmp_dir <> "/a.json") == ~s|{"a":1}|
end

test "gzip", c do
Bypass.expect(c.bypass, "GET", "/", fn conn ->
conn
Expand Down Expand Up @@ -1621,7 +1625,7 @@
refute_receive _
end

test "into: fun with halt", %{bypass: bypass, url: url} do

Check failure on line 1628 in test/req/steps_test.exs

View workflow job for this annotation

GitHub Actions / test (1.15, 26.0, lint)

test run_finch into: fun with halt (Req.StepsTest)
Bypass.expect(bypass, "GET", "/", fn conn ->
conn = Plug.Conn.send_chunked(conn, 200)
{:ok, conn} = Plug.Conn.chunk(conn, "foo")
Expand Down
Loading