profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/wojtekmach/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Wojtek Mach wojtekmach @dashbitco Kraków, Poland @dashbitco developer, @hexpm & @elixir-ecto team member

surface-ui/surface 1446

A server-side rendering component library for Phoenix

wojtekmach/acme_bank 722

An example ☂ project

ericmj/decimal 367

Arbitrary precision decimal arithmetic

peburrows/goth 214

Elixir package for Oauth authentication via Google Cloud APIs

elixir-ecto/myxql 203

MySQL 5.5+ driver for Elixir

phoenixframework/esbuild 190

An installer for esbuild

erlef/setup-beam 155

Set up your GitHub Actions workflow with OTP and Elixir

aerosol/Tabula 75

:u7533: Pretty printer for maps/structs collections (Elixir)

jsl/shamrock 31

Set up stub services in your application

wojtekmach/attrs 18

Yet another attributes on steroids gem

issue commentwojtekmach/req

New API

I think Req.run! would be renamed to Req.Request.run! and it would no longer honour options like :retry, :cache, etc.

I think this is roughly what I have in mind:

defmodule Req.Request do
  defstruct [
    :method,
    :url,
    headers: [],
    body: "",
    options: [],
    request_steps: [],
    response_steps: [],
    error_steps: []
  ]

  def new(options \\ []) do
    struct!(__MODULE__, options)
  end

  def run!(request) do
    run_request(request)
  end

  defp run_request_steps(request) do
    Enum.reduce_while(request.request_steps, request, ...)
  end

  defp run_response_steps(request, response) do
    Enum.reduce_while(request.request_steps, {request, response}, ...)
  end

  defp run_error_steps(request, exception) do
    Enum.reduce_while(request.error_steps, {request, exception}, ...)
  end
end

defmodule Req do
  def new(options \\ []) do
    Req.Request.new(options: options)
  end

  def get!(request \\ %Req.Request{}, url, options \\ []) do
    request!(request, [method: :get, url: url] ++ options)
  end

  def request!(request \\ %Req.Request{}, options \\ []) do
    {method, options} = Keyword.pop!(options, :method)
    {url, options} = Keyword.pop!(options, :url)
    {body, options} = Keyword.pop!(options, :body, "")
    {headers, options} = Keyword.pop!(options, :headers, [])

    %{request | method: method, url: url, body: body, headers: headers, options: options}
    |> prepend_default_steps()
    |> Req.Request.run!()
  end

  @doc api: :response
  def decompress(request) do
    ...
  end

  defp prepend_default_steps(request) do
    ...
  end
end

wdyt?

wojtekmach

comment created time in an hour

issue commentwojtekmach/req

New API

Hm, another idea is this:

Req.new(retry: true) #=> %Req.Request{options: [retry: true], request_steps: [], error_steps: [], ...}
|> Req.get!(url)     # prepends defaults steps and executes the pipeline

That is, Req.new/1 accepts all the options we currently have, but it doesn't yet add any steps. Only when we execute the pipeline with get!, post!, request!, etc, the default steps (decompress, decode, etc) are prepended. I think this greatly simplifies this:

So basically on Req.new we'd add all the default steps + the opt-in ones based on the options. On Req.get/2 we'd do the same. On Req.get/3 we'd additionally opt-in steps per options.

which I wasn't so sure about.

wojtekmach

comment created time in an hour

issue openedwojtekmach/req

New API

Currently we have two ways of making requests, the high- and low-level API:

Req.get(url)

Req.build(:get, url)
|> Req.prepend_default_steps()
|> Req.run()

We can extend Req by adding steps which is possible with the low-evel API. However, given we build-up the request pipeline starting with the method and the URL, the resulting struct isn't ideal to re-use for different invocations. (It doesn't hurt, but it somewhat feels dirty to then overwrite the method, the URL, etc.)

A simple change is to move things around. Instead of build/2 + run/0 we have build/0 + run/3:

Req.build()
|> Req.prepend_default_steps()
|> Req.run(:get, url)

Then there's also the plugins API proposal, https://github.com/wojtekmach/req/pull/35. The idea was to encapsulate some common logic but more importantly make it super easy to use, without building up the request pipeline. Plugins are modules so we can very easily refer to them but then again from the day one we wanted to avoid modules in favour of anonymous functions or MFArgs, the steps.

Finally we also have https://github.com/wojtekmach/req/issues/34.

Putting this all together, I'm now thinking about this API:

# high-level

Req.get!(url)

Req.new()
|> Req.get!(url)

# low-level

Req.Request.new()
|> Req.Request.prepend_request_steps(...)
|> Req.Request.run()

and regarding plugins we can do either or both:

Req.get!(url, plugins: [ReqS3])

Req.new()
|> ReqS3.call()
|> get!(url)

To sum up, we'd add these functions:

Req.new(options \\ [])
Req.get!(request, url, options)

We'd rename these:

Req.build/1 -> Req.Request.new/1
Req.{append,prepend}_{request, response,error}_steps -> Req.Response.*

and remove Req.prepend_default_steps in favour of Req.new/1.

With this, the get function and friends will become a bit more complicated now:

def get(url) when is_binary(url)

def get(url, options) when is_binary(url) and is_list(options)

def get(%Req.Request{} = request, url, options) when is_binary(url) and is_list(options)

but I think that is ok.

WDYT?

created time in 4 hours

issue commentelixir-lang/ex_doc

Can't generate Erlang library documentation using ExDoc

You need docs.config for configuration that is not available via CLI flags. docs.sh is a totally custom script which is not needed but i imagine almost everyone will have something like that.

kianmeng

comment created time in 13 hours

issue commentelixir-lang/elixir

ExUnit diff for similarly printed strings

This is super naive but perhaps a small step in the right direction:

defmodule Main do
  def main do
    IO.puts(escape("Jos\u00E9 Valim"))
    IO.puts(escape("Jos\u{65}\u{301} Valim"))
  end

  def escape(string) do
    escape(String.graphemes(string), [])
  end

  def escape([<<x>> | rest], acc) do
    escape(rest, [acc, x])
  end

  def escape([x | rest], acc) do
    x =
      for int <- String.to_charlist(x) do
        "\\u{" <> Integer.to_string(int, 16) <> "}"
      end

    escape(rest, [acc, x])
  end

  def escape([], acc) do
    IO.iodata_to_binary(["<<\"", acc, "\">>"])
  end
end

Main.main()
<<"Jos\u{E9} Valim">>
<<"Jos\u{65}\u{301} Valim">>
wojtekmach

comment created time in 2 days

issue commentelixir-lang/elixir

ExUnit diff for similarly printed strings

Hmm, I wonder if there is a function to turn <<74, 111, 115, 195, 169>> back to "Jos\u{E9}”, in other words we print the string with unicode escape codes. If such exists, we could diff that.

wojtekmach

comment created time in 3 days

issue openedelixir-lang/elixir

ExUnit diff for similarly printed strings

Environment

  • Elixir & Erlang/OTP versions (elixir --version): master

Current behavior

For this test:

  test "greets the world" do
    assert "Jos\u{E9} Valim" == "Jos\u{65}\u{301} Valim"
  end

we'd get this failure:

  1) test greets the world (FooTest)
     test/foo_test.exs:5
     Assertion with == failed
     code:  assert "José Valim" == "José Valim"
     left:  "José Valim"
                ^
     right: "José Valim"
                ^
     stacktrace:
       test/foo_test.exs:6: (test)

I'm using ^ to mark the spot. In terminal output we have the red/green colouring of course.

The diff doesn't give us actionable information.

Expected behavior

I thought about a heuristic, if we have two unicode strings that are different byte-for-byte (hence this assertion failure was triggered in the first place), but they are equal when normalised, e.g. using |> String.normalize(:nfd), we mark the differing bytes:

  1) test greets the world (FooTest)
     test/foo_test.exs:5
     Assertion with == failed
     code:  assert "José Valim" == "José Valim"
     left:  <<"Jos", 195, 169, " Valim">>
                     ^^^^^^^^
     right: <<"Jos", 101, 204, 129, " Valim">>
                     ^^^^^^^^^^^^^
     stacktrace:
       test/foo_test.exs:6: (test)

created time in 3 days

issue openedwojtekmach/req

retry: Handle 429 Retry-After header

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429

created time in 3 days

pull request commenthexpm/hex

Validate licenses when building the package

Really nice project @Cantido. I took a glance at the code and a potential improvement is to change this https://github.com/Cantido/hex_licenses/blob/10063bf71fa89b80af96e866bc20d3c4c654b82e/lib/hex_licenses.ex#L64 to instead get the license from already fetched package: `:file.consult('deps/<package>/hex_metadata.config'.

supersimple

comment created time in 5 days

pull request commentwojtekmach/req

Update finch

Thank you!

and thanks for all the other PRs. Im taking time off until end of the month so i likely wont be able to go through all of them but Ill be back early october and definitely will then. Thank you again for the work and your interest in req!

mhanberg

comment created time in 5 days

push eventwojtekmach/req

Mitchell Hanberg

commit sha b964307b4f9fd0c75edd1a9b28384acfbd42a6d0

Update finch (#42) This allows apps to use newer telementry versions

view details

push time in 5 days

PR merged wojtekmach/req

Update finch

This allows apps to use newer telemetry versions.

Finch CHANGELOG

  • Update mix.exs to allow compatibility with Telemetry v1.0
+4 -4

0 comment

2 changed files

mhanberg

pr closed time in 5 days

pull request commentwojtekmach/req

Ensure get_private/put_private have atom keys

Thank you!

mhanberg

comment created time in 7 days

push eventwojtekmach/req

Mitchell Hanberg

commit sha 2e432f0778fbc9d483310929e684f7e5ececc318

Ensure get_private/put_private have atom keys (#39)

view details

push time in 7 days

PR merged wojtekmach/req

Ensure get_private/put_private have atom keys

Closes #28

+3 -3

0 comment

1 changed file

mhanberg

pr closed time in 7 days

issue closedwojtekmach/req

get_private, put_private: Ensure keys are atoms

Let's do this now so that in the future we might support "paths", .eg.: put_private(request, [:foo, :bar], :baz).

closed time in 7 days

wojtekmach

pull request commentwojtekmach/req

Req.put!/3 and Req.delete!/2

Thank you!

mhanberg

comment created time in 8 days

push eventwojtekmach/req

Mitchell Hanberg

commit sha 04f051574b38724b77eccfbb7630732dc58e4bf2

Req.put!/3 and Req.delete!/2 (#38)

view details

push time in 8 days

PR merged wojtekmach/req

Req.put!/3 and Req.delete!/2

Closes #32

+63 -7

0 comment

3 changed files

mhanberg

pr closed time in 8 days

issue commentelixir-lang/ex_doc

Can't generate Erlang library documentation using ExDoc

Please use edoc_opts, not erl_opts for edoc stuff

kianmeng

comment created time in 9 days

issue commentelixir-lang/ex_doc

Can't generate Erlang library documentation using ExDoc

Did you follow all the steps from the readme, in particular changingrebar.config to use edoc chunks and changing certifi.app.src too?

kianmeng

comment created time in 9 days

issue commentwojtekmach/req

Pluggable caching system?

Yup the existing cache solution is just a regular step, there's nothing special about it. You can build your own. If you run any issues, feel free to comment here or elsewhere and I'll be happy to help. Just fyi, I have very limited availability this month but happy to get to it in October :)

thbar

comment created time in 13 days

push eventwojtekmach/dotfiles

Wojtek Mach

commit sha 89f9f2d9d094e7427b746385a9b3b9328682361a

up

view details

push time in 19 days

issue commentwojtekmach/minitest-metadata

metadata override

Hey @jb08, sorry, I don't know the answer to your question off the top of my head. Btw, I don't maintain the project anymore, I'm gonna mark it as such. Sorry about that too!

jb08

comment created time in 19 days

issue closedwojtekmach/minitest-metadata

metadata override

minitest/spec.rb:242:in `let': let 'metadata' cannot override a method in Minitest::Spec. Please use another name. 

Any workarounds to renaming all existing spec usages of let(:metadata)?

closed time in 19 days

jb08

issue openedphoenixframework/phoenix_live_view

Improve error message for ~H with attribute and interpolation

Currently,

~H"""
<div class="<%= @class %>"></div>
"""

will give this compiler error:

** (Phoenix.LiveView.HTMLTokenizer.ParseError) bug.exs:15:17: expected closing `"` for attribute value
    (phoenix_live_view 0.16.1) lib/phoenix_live_view/html_tokenizer.ex:357: Phoenix.LiveView.HTMLTokenizer.handle_attr_value_double_quote/6
    (phoenix_live_view 0.16.1) lib/phoenix_live_view/html_engine.ex:89: Phoenix.LiveView.HTMLEngine.handle_text/3
    (eex 1.13.0-dev) lib/eex/compiler.ex:49: EEx.Compiler.generate_buffer/4
    (phoenix_live_view 0.16.1) expanding macro: Phoenix.LiveView.Helpers.sigil_H/2
    bug.exs:14: Main.main/0

When moving from ~L to ~H such code can be quite common so an error message that tells exactly what's going on will definitely ease the transition.

Here's a full script to reproduce this error:

Application.put_env(:phoenix, :json_library, Jason)

Mix.install([
  {:phoenix_live_view, github: "phoenixframework/phoenix_live_view"},
  {:jason, "~> 1.0"}
])

defmodule Main do
  import Phoenix.LiveView.Helpers

  def main do
    assigns = []

    ~H"""
    <div class="<%= @class %>"></div>
    """
  end
end

Main.main()

created time in 20 days

push eventwojtekmach/livebook

Wojtek Mach

commit sha 6ee6aa8263bc11b65b3cf13347c43720bd01fbc4

Update lib/livebook_cli/server.ex

view details

push time in 20 days

Pull request review commentlivebook-dev/livebook

livebook server: Add `--open-new` flag

 defmodule LivebookCLI.Server do           browser_open(LivebookWeb.Endpoint.access_url())         end +        if opts[:open_new] do+          LivebookWeb.Endpoint.access_url()+          |> URI.parse()+          |> Map.update!(:path, &(&1 <> "explore/notebooks/new"))
          |> Map.update!(:path, &((&1 || "/") <> "explore/notebooks/new"))
wojtekmach

comment created time in 20 days

PullRequestReviewEvent