Skip to content

Commit

Permalink
Support Ecto 2.x (#23)
Browse files Browse the repository at this point in the history
* Support Ecto 2.x

Update to support Ecto 2.x. We may still move Ecto support into a separate library, however for now this works for both Ecto 1.x and 2.x.

This commit also includes some minor documentation updates. The documentation still needs plenty of help but I did not want to hold up the Ecto 2.x support for this task.

This also includes a CHANGELOG entry in preparation for release of a new version due to an API update and soft deprecation.

* Release v0.4.0
  • Loading branch information
seanabrahams authored Jun 24, 2016
1 parent 44e6912 commit 947bd40
Show file tree
Hide file tree
Showing 19 changed files with 196 additions and 98 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

## 0.4.0 (2016-06-22)

* Update optional dependency for Ecto to support both Ecto v1.x and v2.x.
* Add `GraphQL.Relay.Connection.Ecto.resolve/3` and include deprecation warning for `GraphQL.Relay.Connection.Ecto.resolve/2`. It makes no sense to add your Ecto Repo to `args`. You can now pass it directly as the first argument, which makes much more sense. `GraphQL.Relay.Connection.Ecto.resolve(Repo, query)` not `GraphQL.Relay.Connection.Ecto.resolve(query, %{repo: Repo})`.

## 0.3.0 (2016-06-09)

* Bump version to match GraphQL Elixir
* Update dependencies to v0.3.1 of GraphQL Elixir
* Update dependencies to v0.3 of GraphQL Elixir
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This library relies on the [GraphQL Elixir](https://github.com/graphql-elixir/gr
Add `graphql_relay` to your list of dependencies in `mix.exs`:

def deps do
[{:graphql_relay, "~> 0.3"}]
[{:graphql_relay, "~> 0.4"}]
end

## Configuration
Expand Down
12 changes: 7 additions & 5 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ This document outlines the release process:

4. Run `mix test` to ensure all tests pass

5. Commit changes above with title "Release vVERSION" and push to GitHub
5. Update `examples` to use new version

6. Commit changes above with title "Release vVERSION" and push to GitHub

git add .
git commit -m"Release vX.Y.Z"
git push origin master

6. Check CI is green
7. Check CI is green

7. Create a release on GitHub and add the CHANGELOG from step #2 (https://github.com/graphql-elixir/graphql/releases/new) using VERSION as the tag and title
8. Create a release on GitHub and add the CHANGELOG from step #2 (https://github.com/graphql-elixir/graphql/releases/new) using VERSION as the tag and title

8. Publish new hex release with `mix hex.publish`
9. Publish new hex release with `mix hex.publish`

9. Publish hex docs with `mix hex.docs`
10. Publish hex docs with `mix hex.docs`

## Deprecation policy

Expand Down
19 changes: 10 additions & 9 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use Mix.Config

# config :graphql_relay, GraphQL.Relay.Connection.EctoTest.Repo,
# adapter: Ecto.Adapters.Postgres,
# database: "graphql_relay_test",
# username: "postgres",
# password: "postgres",
# hostname: "localhost"
# Ecto v1.x
# config :graphql_relay, app_repo: EctoTest.Repo

# Ecto v2.x
config :graphql_relay, ecto_repos: [EctoTest.Repo]

config :graphql_relay, app_repo: EctoTest.Repo
config :graphql_relay, EctoTest.Repo,
adapter: Sqlite.Ecto,
database: ":memory:",
adapter: Ecto.Adapters.Postgres,
database: "graphql_relay_test",
username: "postgres",
password: "postgres",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox
14 changes: 7 additions & 7 deletions examples/todo/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Todo.Mixfile do

def project do
[app: :todo,
version: "0.0.1",
version: "0.1.0",
elixir: "~> 1.0",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix] ++ Mix.compilers,
Expand All @@ -30,14 +30,14 @@ defmodule Todo.Mixfile do
#
# Type `mix help deps` for examples and options.
defp deps do
[{:phoenix, "~> 1.1.4"},
{:phoenix_ecto, "~> 2.0"},
{:postgrex, "~> 0.11"},
{:phoenix_html, "~> 2.3"},
[{:phoenix, "~> 1.1.6"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:cowboy, "~> 1.0"},
{:graphql_relay, "~> 0.0.17"},
{:plug_graphql, "~> 0.3.0"}]
{:graphql_relay, "~> 0.4"},
{:plug_graphql, "~> 0.3"}]
end

# Aliases are shortcut or tasks specific to the current project.
Expand Down
22 changes: 11 additions & 11 deletions examples/todo/mix.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
%{"connection": {:hex, :connection, "1.0.2", "f4a06dd3ecae4141aa66f94ce92ea4c4b8753069472814932f1cadbc3078ab80", [:mix], []},
%{"connection": {:hex, :connection, "1.0.3", "3145f7416be3df248a4935f24e3221dc467c1e3a158d62015b35bd54da365786", [:mix], []},
"cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:rebar, :make], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"db_connection": {:hex, :db_connection, "0.2.5", "3e5e28019e0ec744345568d22a2f5206109bff0e2571f4d7819e0d14cf955f3e", [:mix], [{:sbroker, "~> 0.7", [hex: :sbroker, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:connection, "~> 1.0.2", [hex: :connection, optional: false]}]},
"db_connection": {:hex, :db_connection, "1.0.0-rc.2", "c5b2329651ef046d85e47ec2c947cb0e3d10a69eb49fdb71e365e72d6758e4c5", [:mix], [{:sbroker, "~> 1.0.0-beta.2", [hex: :sbroker, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:connection, "~> 1.0.2", [hex: :connection, optional: false]}]},
"decimal": {:hex, :decimal, "1.1.2", "79a769d4657b2d537b51ef3c02d29ab7141d2b486b516c109642d453ee08e00c", [:mix], []},
"ecto": {:hex, :ecto, "1.1.7", "c37127248756e725eb8254b371764b40c05a90c104b2065d1d4f7e32573fdbec", [:mix], [{:sbroker, "~> 0.7", [hex: :sbroker, optional: true]}, {:postgrex, "~> 0.11.0", [hex: :postgrex, optional: true]}, {:poolboy, "~> 1.4", [hex: :poolboy, optional: false]}, {:poison, "~> 1.0 or ~> 2.0", [hex: :poison, optional: true]}, {:mariaex, "~> 0.5.0 or ~> 0.6.0", [hex: :mariaex, optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]},
"ecto": {:hex, :ecto, "2.0.1", "cf97a4d353e14af3d3cc3b4452cfbd18b3aeee1fb4075475efeccec3853444a9", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, optional: true]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, optional: true]}, {:postgrex, "~> 0.11.2", [hex: :postgrex, optional: true]}, {:db_connection, "~> 1.0-rc.2", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}]},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
"graphql": {:hex, :graphql, "0.3.0", "4894f81e0010ff04a0349845f63a19f7f8cce754273bb06ecfe00b30dc685a86", [:mix], []},
"graphql": {:hex, :graphql, "0.3.1", "d3bb5467877456cc2b33debc75407e9216567b10e35e83d5195e2d51e835e8c7", [:mix], []},
"graphql_relay": {:hex, :graphql_relay, "0.0.17", "d5ce633b85c9103ab0507dd3c4e9103d8d14ea9bd316d35fb9cbc9ba31234c5c", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}, {:graphql, "~> 0.3", [hex: :graphql, optional: false]}, {:ecto, "~> 1.1.4", [hex: :ecto, optional: true]}]},
"phoenix": {:hex, :phoenix, "1.1.4", "65809fba92eb94377372a5fb5a561197654bb8406e773cc47ca1a031bbe58019", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}]},
"phoenix_ecto": {:hex, :phoenix_ecto, "2.0.2", "1aff51d1cd21cc39d7891cae2284399cbf4b8e32fb7864e68f5d272d2934e48a", [:mix], [{:poison, "~> 1.3 or ~> 2.0", [hex: :poison, optional: true]}, {:phoenix_html, "~> 2.2", [hex: :phoenix_html, optional: true]}, {:ecto, "~> 1.1.2", [hex: :ecto, optional: false]}]},
"phoenix_html": {:hex, :phoenix_html, "2.5.1", "631053f9e345fecb5c87d9e0ccd807f7266d27e2ee4269817067af425fd81ba8", [:mix], [{:plug, "~> 0.13 or ~> 1.0", [hex: :plug, optional: false]}]},
"phoenix": {:hex, :phoenix, "1.1.6", "7bf19002669c8f692f5a9c8d30dab7b49f3dc56228d5bde92a12fb426b4783c2", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}]},
"phoenix_ecto": {:hex, :phoenix_ecto, "3.0.0", "b947aaf03d076f5b1448f87828f22fb7710478ee38455c67cc3fe8e9a4dfd015", [:mix], [{:ecto, "~> 2.0.0-rc", [hex: :ecto, optional: false]}, {:phoenix_html, "~> 2.6", [hex: :phoenix_html, optional: true]}]},
"phoenix_html": {:hex, :phoenix_html, "2.6.0", "b9f7e091eb3d908586d9634596478fb9e577ee033d76f4ff327a745569bdd2d8", [:mix], [{:plug, "~> 0.13 or ~> 1.0", [hex: :plug, optional: false]}]},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.5", "829218c4152ba1e9848e2bf8e161fcde6b4ec679a516259442561d21fde68d0b", [:mix], [{:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, optional: false]}, {:fs, "~> 0.9.1", [hex: :fs, optional: false]}]},
"plug": {:hex, :plug, "1.1.5", "de5645c18170415a72b18cc3d215c05321ddecac27a15acb923742156e98278b", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}]},
"plug_graphql": {:hex, :plug_graphql, "0.3.0", "17952a585b4eaf1a7941ab4fbfca8f812fdc897905fa616cde72135a479b5dc1", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}, {:plug, "~> 0.14 or ~> 1.0", [hex: :plug, optional: false]}, {:graphql, "~> 0.3", [hex: :graphql, optional: false]}, {:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}]},
"poison": {:hex, :poison, "2.1.0", "f583218ced822675e484648fa26c933d621373f01c6c76bd00005d7bd4b82e27", [:mix], []},
"plug": {:hex, :plug, "1.1.6", "8927e4028433fcb859e000b9389ee9c37c80eb28378eeeea31b0273350bf668b", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}]},
"plug_graphql": {:hex, :plug_graphql, "0.3.1", "8c3c91b889236620cea19606ab5b770c1c533242c92d97c23b9f359be4eb4c03", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}, {:plug, "~> 0.14 or ~> 1.0", [hex: :plug, optional: false]}, {:graphql, "~> 0.3", [hex: :graphql, optional: false]}, {:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}]},
"poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []},
"postgrex": {:hex, :postgrex, "0.11.1", "f48af70c0a58b9bfd1aaa456ec4273624554cfb837726b6a7f0701da4a94b2dd", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, optional: false]}, {:db_connection, "~> 0.2", [hex: :db_connection, optional: false]}, {:connection, "~> 1.0", [hex: :connection, optional: false]}]},
"postgrex": {:hex, :postgrex, "0.11.2", "139755c1359d3c5c6d6e8b1ea72556d39e2746f61c6ddfb442813c91f53487e8", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.0-rc", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []}}
2 changes: 1 addition & 1 deletion examples/todo/web/graphql/todo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ defmodule Todo.GraphQL.Schema.Todo do
end
},
},
mutate_and_get_payload: fn(input, _info) ->
mutate_and_get_payload: fn(_input, _info) ->
# [_, user_id] = Node.from_global_id(input["viewer"]["id"])
todos = Todo.GraphQL.Schema.Todo.delete_completed(1)
%{
Expand Down
3 changes: 1 addition & 2 deletions examples/todo/web/graphql/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ defmodule Todo.GraphQL.Schema.User do
Connection.args
),
resolve: fn(user, args, _ctx) ->
args = Map.put(args, :repo, Repo)
query = Ecto.assoc(user, :todos)
query = case args do
%{status: "active"} -> from things in query, where: things.complete == false
%{status: "completed"} -> from things in query, where: things.complete == true
_ -> query
end
Connection.Ecto.resolve(query, args)
Connection.Ecto.resolve(Repo, query, args)
end
},
totalCount: %{
Expand Down
14 changes: 7 additions & 7 deletions lib/graphql/relay/connection.ex
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
defmodule GraphQL.Relay.Connection do
@doc """
Any type whose name ends in "Connection" is considered by Relay to be a
Connection Type. Connection types must be an "Object" as defined in the
"Type System" section of the GraphQL Specification.
@moduledoc """
You define a Connection for Relay when you want a paginated data source.
Connection types must have fields named edges and pageInfo. They may have
additional fields related to the connection, as the schema designer sees fit.
For example, in a Todo application a User can have many Todos that you want
to list and paginate through. A Connection is the perfect fit for this.
https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types
For an example see https://github.com/graphql-elixir/graphql_relay/blob/44e6912a08468743f7dfa1343723914bbf6809e1/examples/todo/web/graphql/user.ex
For the Connection type specification see: https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types
"""
alias GraphQL.Type.Boolean
alias GraphQL.Type.Int
Expand Down
84 changes: 74 additions & 10 deletions lib/graphql/relay/connection/ecto.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,63 @@
if Code.ensure_loaded?(Ecto) do
defmodule GraphQL.Relay.Connection.Ecto do
@moduledoc """
Interface between Relay Connections and Ecto Queries.
In other words, this module allows you to back a Relay Connection with an
Ecto query.
Interface between Relay Connections and Ecto. This module allows you to
back a Relay Connection with an Ecto query.
## Example
A Relay connection starts with a connection definition. For example, a
`user` can have many `todos` (see code comments):
```elixir
%ObjectType{
name: "User",
description: "The user",
fields: %{
id: Node.global_id_field("user"),
name: %{type: %String{}},
email: %{type: %String{}},
todos: %{
type: Todo.connection[:connection_type],
description: "The todos this user owns",
args: Map.merge(
%{status: %{type: %String{}, defaultValue: "any"}},
Connection.args
),
resolve: fn(user, args, _ctx) ->
# Here we prepare our Ecto query
query = Ecto.assoc(user, :todos)
query = case args do
%{status: "active"} -> from things in query, where: things.complete == false
%{status: "completed"} -> from things in query, where: things.complete == true
_ -> query
end
# Here we resolve the connection using our Ecto Connection module,
# passing it the Ecto Repo we want to query. The `resolve/3` function
# will execute the query and return the results in the form Relay
# requires.
Connection.Ecto.resolve(Repo, query, args)
end
},
},
interfaces: [Root.node_interface]
}
```
For a full example see https://github.com/graphql-elixir/graphql_relay/blob/master/examples/todo/web/graphql/user.ex
"""
import Ecto.Query
@prefix "ectoconnection:"

@doc """
WARNING: this function signature is deprecated. Use `resolve/3`.
"""
def resolve(query, %{repo: repo} = args) do
# Emit deprecation warning once we hit >= v0.6 per RELEASE.md#Deprecations
# :elixir_errors.warn __ENV__.line, __ENV__.file, "Use of `GraphQL.Relay.Connection.Ecto.resolve/2` is deprecated! Use `GraphQL.Relay.Connection.Ecto.resolve/3`."
resolve(repo, query, args)
end

def resolve(repo, query, args \\ %{}) do
before = cursor_to_offset(args[:before])
# `after` is a keyword http://elixir-lang.org/docs/master/elixir/Kernel.SpecialForms.html#try/1
a_after = cursor_to_offset(args[:after])
Expand Down Expand Up @@ -111,20 +159,36 @@ if Code.ensure_loaded?(Ecto) do

defp make_query_countable(query) do
query
|> remove_select
|> remove_order
|> remove_preload
|> remove_select
end

# Remove order by if it exists so that we avoid `field X in "order_by"
# does not exist in the model source in query`
defp remove_order(query) do
Ecto.Query.exclude(query, :order_by)
end

# Remove preload if it exists so that we avoid "the binding used in `from`
# must be selected in `select` when using `preload` in query`"
defp remove_preload(query) do
Ecto.Query.exclude(query, :preload)
end

# Remove select if it exists so that we avoid `only one select
# expression is allowed in query` Ecto exception
defp remove_select(query) do
Ecto.Query.exclude(query, :select)
end

# Remove order by if it exists so that we avoid `field X in "order_by"
# does not exist in the model source in query`
defp remove_order(query) do
Ecto.Query.exclude(query, :order_by)
end
else
defmodule GraphQL.Relay.Connection.Ecto do
def resolve(_, _) do
raise RuntimeError, message: """
Ecto not available. Make sure Ecto is installed as a dependency of your
application.
"""
end
end
end
6 changes: 6 additions & 0 deletions lib/graphql/relay/connection/list.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
defmodule GraphQL.Relay.Connection.List do
@moduledoc """
Interface between Relay Connections and a list. This module allows you to
back a Relay Connection with a common list.
See tests for examples https://github.com/graphql-elixir/graphql_relay/blob/master/test/graphql/relay/connection/list_test.exs
"""
@prefix "arrayconnection:"

def resolve(data), do: resolve(data, %{})
Expand Down
2 changes: 2 additions & 0 deletions lib/graphql/relay/mutation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ defmodule GraphQL.Relay.Mutation do
then returned as part of the object returned by the mutation field.
https://facebook.github.io/relay/graphql/mutations.htm
For an example see https://github.com/graphql-elixir/graphql_relay/blob/44e6912a08468743f7dfa1343723914bbf6809e1/examples/todo/web/graphql/todo.ex#L110
"""
alias GraphQL.Type.NonNull
alias GraphQL.Type.ObjectType
Expand Down
7 changes: 6 additions & 1 deletion lib/graphql/relay/node.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
defmodule GraphQL.Relay.Node do
@doc """
Relay’s support for object identification relies on the GraphQL server exposing object identifiers in a standardized way. In the query, the schema should provide a standard mechanism for asking for an object by ID. In the response, the schema provides a standard way of providing these IDs.
Relay’s support for object identification relies on the GraphQL server
exposing object identifiers in a standardized way. In the query, the schema
should provide a standard mechanism for asking for an object by ID. In the
response, the schema provides a standard way of providing these IDs.
We refer to objects with identifiers as “nodes”.
http://facebook.github.io/relay/graphql/objectidentification.htm
For an example see https://github.com/graphql-elixir/graphql_relay/blob/44e6912a08468743f7dfa1343723914bbf6809e1/examples/todo/web/graphql/root.ex#L6
"""
alias GraphQL.Type.ID
alias GraphQL.Type.Interface
Expand Down
3 changes: 1 addition & 2 deletions lib/graphql_relay.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
defmodule GraphQL.Relay do
require Logger

@moduledoc """
Elixir library containing helpers for making a GraphQL server Relay compliant.
"""
require Logger

@spec resolve_maybe_thunk(fun | map) :: %{}
def resolve_maybe_thunk(t) when is_function(t), do: t.()
Expand Down
6 changes: 3 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule GraphQL.Relay.Mixfile do
use Mix.Project

@version "0.3.0"
@version "0.4.0"
@description "Relay helpers for GraphQL Elixir"
@repo_url "https://github.com/graphql-elixir/graphql_relay"

Expand Down Expand Up @@ -34,8 +34,8 @@ defmodule GraphQL.Relay.Mixfile do
[
{:graphql, "~> 0.3"},
{:poison, "~> 1.5 or ~> 2.0"}, # For .generate_schema_json!
{:ecto, "~> 1.1.4", optional: true},
{:sqlite_ecto, "~> 1.0.0", only: [:dev, :test]},
{:ecto, "~> 1.0 or ~> 2.0", optional: true, only: [:dev, :test]},
{:postgrex, ">= 0.0.0", only: [:dev, :test]},
]
end

Expand Down
Loading

0 comments on commit 947bd40

Please sign in to comment.