Skip to content

Commit

Permalink
Merge pull request derekkraan#17 from derekkraan/chore/updates
Browse files Browse the repository at this point in the history
Updates and cleanup
  • Loading branch information
kevinschweikert authored Dec 4, 2024
2 parents 8a04a80 + 0585253 commit 33b5c67
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 59 deletions.
28 changes: 9 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ And you'll have the full curl command.
```elixir
# Turn a Req request into a `curl` command.

iex> Req.new(url: "/fact", base_url: "https://catfact.ninja/")
iex> Req.new(url: "/fact", base_url: "https://example.com/")
...> |> CurlReq.to_curl()
"curl --compressed -X GET https://catfact.ninja/fact"
"curl --compressed -X GET https://example.com/fact"

# Or use `CurlReq.inspect/2` to inspect inline.

iex> Req.new(url: "/fact", base_url: "https://catfact.nijna/")
...> |> CurlReq.inspect(label: "MY REQ")
...> # |> Req.request!()

Req.new(url: "https://example.com")
|> CurlReq.inspect()
|> Req.request!()
#=> curl --compressed -X GET https://example.com
```

### Curl to Req
Expand All @@ -38,25 +38,24 @@ iex> Req.new(url: "/fact", base_url: "https://catfact.nijna/")

```elixir
iex> import CurlReq
...> ~CURL(curl https://www.google.com)
...> ~CURL(curl https://www.example.com)
...> # |> Req.request!()

```

or use `CurlReq.from_curl/1`:
```elixir
iex> CurlReq.from_curl("curl https://www.google.com")
iex> CurlReq.from_curl("curl https://example.com")
...> # |> Req.request!()

```


### Req Plugin

One final feature to note the Req plugin, `CurlReq.Plugin`. Use `CurlReq.Plugin.attach/2` to set up curl logging (inspired by `TeslaCurl`).

```elixir
iex> Req.new(url: "/fact", base_url: "https://catfact.ninja/")
iex> Req.new(url: "/fact", base_url: "https://example.com/")
...> |> CurlReq.Plugin.attach()
...> # |> Req.request!()

Expand All @@ -83,15 +82,6 @@ The docs can be found at <https://hexdocs.pm/curl_req>.

Contributions are welcome! There are gaps in the library, and this is open source, so let's work together to fill them!

- [x] ~CURL sigil handles newlines
- [x] curl [url]
- [x] curl -H
- [x] curl -X
- [x] curl -d
- [x] curl -b
- [x] curl long form options (--header, --data, etc)
- [x] Req Plugin to log curl command (like `TeslaCurl`)

## How to contribute

- Clone the repository to your computer.
Expand Down
23 changes: 12 additions & 11 deletions lib/curl_req.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ defmodule CurlReq do
Returns the unchanged `req`, just like `IO.inspect/2`.
## Examples
iex> Req.new(url: URI.parse("https://www.google.com"))
...> |> CurlReq.inspect()
...> # |> Req.request!()
Req.new(url: "https://example.com")
|> CurlReq.inspect()
|> Req.request!()
#=> curl --compressed -X GET https://example.com
"""
@spec inspect(Req.Request.t(), [inspect_opt()]) :: Req.Request.t()
Expand Down Expand Up @@ -67,13 +68,13 @@ defmodule CurlReq do
## Examples
iex> Req.new(url: URI.parse("https://www.google.com"))
iex> Req.new(url: URI.parse("https://www.example.com"))
...> |> CurlReq.to_curl()
~S(curl --compressed -X GET https://www.google.com)
~S(curl --compressed -X GET https://www.example.com)
iex> Req.new(url: URI.parse("https://www.google.com"))
iex> Req.new(url: URI.parse("https://www.example.com"))
...> |> CurlReq.to_curl(flags: :long, flavor: :req)
~S(curl --header "accept-encoding: gzip" --header "user-agent: req/#{@req_version}" --request GET https://www.google.com)
~S(curl --header "accept-encoding: gzip" --header "user-agent: req/#{@req_version}" --request GET https://www.example.com)
"""
@type flags :: :short | :long
Expand Down Expand Up @@ -210,8 +211,8 @@ defmodule CurlReq do
## Examples
iex> CurlReq.from_curl("curl https://www.google.com")
%Req.Request{method: :get, url: URI.parse("https://www.google.com")}
iex> CurlReq.from_curl("curl https://www.example.com")
%Req.Request{method: :get, url: URI.parse("https://www.example.com")}
iex> ~S(curl -d "some data" https://example.com) |> CurlReq.from_curl()
%Req.Request{method: :get, body: "some data", url: URI.parse("https://example.com")}
Expand All @@ -233,8 +234,8 @@ defmodule CurlReq do
## Examples
iex> import CurlReq
...> ~CURL(curl "https://www.google.com")
%Req.Request{method: :get, url: URI.parse("https://www.google.com")}
...> ~CURL(curl "https://www.example.com")
%Req.Request{method: :get, url: URI.parse("https://www.example.com")}
iex> import CurlReq
...> ~CURL(curl -d "some data" "https://example.com")
Expand Down
4 changes: 2 additions & 2 deletions lib/curl_req/plugin.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ defmodule CurlReq.Plugin do
## Examples
iex> Req.new(url: "https://catfact.ninja/fact")
iex> Req.new(url: "https://example.com/fact")
...> |>CurlReq.Plugin.attach()
iex> Req.new(url: "https://catfact.ninja/fact")
iex> Req.new(url: "https://example.com/fact")
...> |> CurlReq.Plugin.attach(log_level: :info, log_metadata: [ansi_color: :blue])
# Possible improvements
Expand Down
26 changes: 12 additions & 14 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
%{
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
"ex_doc": {:hex, :ex_doc, "0.34.0", "ab95e0775db3df71d30cf8d78728dd9261c355c81382bcd4cefdc74610bef13e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "60734fb4c1353f270c3286df4a0d51e65a2c1d9fba66af3940847cc65a8066d7"},
"finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"},
"hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"mint": {:hex, :mint, "1.6.1", "065e8a5bc9bbd46a41099dfea3e0656436c5cbcb6e741c80bd2bad5cd872446f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4fc518dcc191d02f433393a72a7ba3f6f94b101d094cb6bf532ea54c89423780"},
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
"ex_doc": {:hex, :ex_doc, "0.35.1", "de804c590d3df2d9d5b8aec77d758b00c814b356119b3d4455e4b8a8687aecaf", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2121c6402c8d44b05622677b761371a759143b958c6c19f6558ff64d0aed40df"},
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.0", "74bb8348c9b3a51d5c589bf5aebb0466a84b33274150e3b6ece1da45584afc82", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49159b7d7d999e836bedaf09dcf35ca18b312230cf901b725a64f3f42e407983"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
"req": {:hex, :req, "0.5.0", "6d8a77c25cfc03e06a439fb12ffb51beade53e3fe0e2c5e362899a18b50298b3", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "dda04878c1396eebbfdec6db6f3d4ca609e5c8846b7ee88cc56eb9891406f7a3"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"req": {:hex, :req, "0.5.8", "50d8d65279d6e343a5e46980ac2a70e97136182950833a1968b371e753f6a662", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d7fc5898a566477e174f26887821a3c5082b243885520ee4b45555f5d53f40ef"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
}
18 changes: 9 additions & 9 deletions test/curl_req/macro_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ defmodule CurlReq.MacroTest do

describe "macro" do
test "single header" do
assert ~CURL(curl -H "user-agent: req/0.4.14" -X GET https://catfact.ninja/fact) ==
assert ~CURL(curl -H "user-agent: req/0.4.14" -X GET https://example.com/fact) ==
%Req.Request{
method: :get,
headers: %{"user-agent" => ["req/0.4.14"]},
url: URI.parse("https://catfact.ninja/fact")
url: URI.parse("https://example.com/fact")
}
end

Expand Down Expand Up @@ -49,10 +49,10 @@ defmodule CurlReq.MacroTest do
end

test "without curl prefix" do
assert ~CURL(http://localhost) ==
assert ~CURL(http://example.com) ==
%Req.Request{
method: :get,
url: URI.parse("http://localhost")
url: URI.parse("http://example.com")
}
end

Expand Down Expand Up @@ -152,12 +152,12 @@ defmodule CurlReq.MacroTest do
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/users
https://example.com/users
"""

assert curl ==
%Req.Request{
url: URI.parse("https://api.github.com/users"),
url: URI.parse("https://example.com/users"),
body: nil,
headers: %{
"accept" => ["application/vnd.github+json"],
Expand Down Expand Up @@ -242,15 +242,15 @@ defmodule CurlReq.MacroTest do
end

test "accepts newlines ending in backslash" do
uri = URI.parse("https://hello.myshopify.com/api/2024-07/graphql.json")
uri = URI.parse("https://example.com/api/2024-07/graphql.json")

assert %Req.Request{
method: :post,
url: ^uri,
headers: %{"content-type" => ["application/json"]}
} = ~CURL"""
curl -X POST \
https://hello.myshopify.com/api/2024-07/graphql.json \
https://example.com/api/2024-07/graphql.json \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Storefront-Access-Token: ABCDEF' \
-d '{
Expand All @@ -273,7 +273,7 @@ defmodule CurlReq.MacroTest do
headers: %{"content-type" => ["application/json"]}
} = ~CURL"""
curl -X POST
https://hello.myshopify.com/api/2024-07/graphql.json
https://example.com/api/2024-07/graphql.json
-H 'Content-Type: application/json'
-H 'X-Shopify-Storefront-Access-Token: ABCDEF'
-d '{
Expand Down
25 changes: 21 additions & 4 deletions test/curl_req_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,28 @@ defmodule CurlReqTest do
use ExUnit.Case, async: true
doctest CurlReq
import CurlReq
import ExUnit.CaptureIO

describe "inspect" do
test "without label" do
assert capture_io(fn ->
Req.new(url: "/without_label", base_url: "https://example.com/")
|> CurlReq.inspect()
end) === "curl --compressed -X GET https://example.com/without_label\n"
end

test "with label" do
assert capture_io(fn ->
Req.new(url: "/with_label", base_url: "https://example.com/")
|> CurlReq.inspect(label: "MY REQ")
end) === "MY REQ: curl --compressed -X GET https://example.com/with_label\n"
end
end

describe "to_curl" do
test "works with base URL" do
assert "curl --compressed -X GET https://catfact.ninja/fact" ==
Req.new(url: "/fact", base_url: "https://catfact.ninja/")
assert "curl --compressed -X GET https://example.com/fact" ==
Req.new(url: "/fact", base_url: "https://example.com/")
|> CurlReq.to_curl()
end

Expand Down Expand Up @@ -46,11 +63,11 @@ defmodule CurlReqTest do
end

test "works when body is iodata" do
assert "curl --compressed -d hello -X POST https://catfact.ninja/fact" ==
assert "curl --compressed -d hello -X POST https://example.com/fact" ==
Req.new(
method: :post,
url: "/fact",
base_url: "https://catfact.ninja",
base_url: "https://example.com",
body: ["h" | ["e" | ["llo"]]]
)
|> CurlReq.to_curl()
Expand Down

0 comments on commit 33b5c67

Please sign in to comment.