Skip to content

Commit 1a38ce6

Browse files
committed
feat: add credo
1 parent 3ec4635 commit 1a38ce6

12 files changed

+138
-47
lines changed

.credo.exs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
%{
2+
configs: [
3+
%{
4+
name: "default",
5+
files: %{
6+
included: ["lib/"],
7+
excluded: ["lib/test.ex"]
8+
},
9+
requires: [],
10+
checks: [
11+
# Consistency
12+
{Credo.Check.Consistency.ExceptionNames},
13+
{Credo.Check.Consistency.LineEndings},
14+
{Credo.Check.Consistency.MultiAliasImportRequireUse},
15+
{Credo.Check.Consistency.ParameterPatternMatching},
16+
{Credo.Check.Consistency.SpaceAroundOperators},
17+
{Credo.Check.Consistency.SpaceInParentheses},
18+
{Credo.Check.Consistency.TabsOrSpaces},
19+
# Design
20+
{Credo.Check.Design.AliasUsage},
21+
{Credo.Check.Design.DuplicatedCode},
22+
{Credo.Check.Design.TagFIXME},
23+
{Credo.Check.Design.TagTODO, exit_status: 0},
24+
# Readability
25+
{Credo.Check.Readability.AliasOrder},
26+
{Credo.Check.Readability.FunctionNames},
27+
{Credo.Check.Readability.LargeNumbers},
28+
{Credo.Check.Readability.MaxLineLength},
29+
{Credo.Check.Readability.ModuleAttributeNames},
30+
{Credo.Check.Readability.ModuleDoc},
31+
{Credo.Check.Readability.ModuleNames},
32+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, false},
33+
{Credo.Check.Readability.PredicateFunctionNames},
34+
{Credo.Check.Readability.PreferImplicitTry, false},
35+
{Credo.Check.Readability.PreferUnquotedAtoms},
36+
{Credo.Check.Readability.RedundantBlankLines},
37+
{Credo.Check.Readability.Semicolons},
38+
{Credo.Check.Readability.SinglePipe},
39+
{Credo.Check.Readability.SpaceAfterCommas},
40+
{Credo.Check.Readability.Specs},
41+
{Credo.Check.Readability.StringSigils},
42+
{Credo.Check.Readability.TrailingBlankLine},
43+
{Credo.Check.Readability.TrailingWhiteSpace},
44+
{Credo.Check.Readability.UnnecessaryAliasExpansion},
45+
{Credo.Check.Readability.VariableNames},
46+
# Refactor
47+
{Credo.Check.Refactor.ABCSize},
48+
{Credo.Check.Refactor.AppendSingleItem},
49+
{Credo.Check.Refactor.CaseTrivialMatches},
50+
{Credo.Check.Refactor.CondStatements},
51+
{Credo.Check.Refactor.CyclomaticComplexity},
52+
{Credo.Check.Refactor.DoubleBooleanNegation},
53+
{Credo.Check.Refactor.FunctionArity},
54+
{Credo.Check.Refactor.LongQuoteBlocks},
55+
{Credo.Check.Refactor.MapInto},
56+
{Credo.Check.Refactor.MatchInCondition},
57+
{Credo.Check.Refactor.ModuleDependencies},
58+
{Credo.Check.Refactor.NegatedConditionsInUnless},
59+
{Credo.Check.Refactor.NegatedConditionsWithElse},
60+
{Credo.Check.Refactor.Nesting},
61+
{Credo.Check.Refactor.PerceivedComplexity},
62+
{Credo.Check.Refactor.PipeChainStart},
63+
{Credo.Check.Refactor.UnlessWithElse},
64+
{Credo.Check.Refactor.VariableRebinding, false},
65+
# Warning
66+
{Credo.Check.Warning.BoolOperationOnSameValues},
67+
{Credo.Check.Warning.ExpensiveEmptyEnumCheck},
68+
{Credo.Check.Warning.IExPry},
69+
{Credo.Check.Warning.IoInspect},
70+
{Credo.Check.Warning.LazyLogging},
71+
{Credo.Check.Warning.MapGetUnsafePass},
72+
{Credo.Check.Warning.OperationOnSameValues},
73+
{Credo.Check.Warning.OperationWithConstantResult},
74+
{Credo.Check.Warning.RaiseInsideRescue},
75+
{Credo.Check.Warning.UnsafeToAtom, false},
76+
{Credo.Check.Warning.UnusedEnumOperation},
77+
{Credo.Check.Warning.UnusedFileOperation},
78+
{Credo.Check.Warning.UnusedKeywordOperation},
79+
{Credo.Check.Warning.UnusedListOperation},
80+
{Credo.Check.Warning.UnusedPathOperation},
81+
{Credo.Check.Warning.UnusedRegexOperation},
82+
{Credo.Check.Warning.UnusedStringOperation},
83+
{Credo.Check.Warning.UnusedTupleOperation}
84+
]
85+
}
86+
]
87+
}

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,8 @@ erl_crash.dump
2222
# Ignore package tarball (built via "mix hex.build").
2323
crux_gateway-*.tar
2424

25+
# VS Code plugin
26+
.elixir_ls/
27+
28+
# Test file
29+
lib/test.ex

config/config.exs

-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1 @@
11
use Mix.Config
2-
3-
# Everything may be set / overriden via `Crux.Gateway.start/1´.
4-
# See documentation of the `Crux.Gateway` module.
5-
# config :crux_gateway,
6-
# # required
7-
# token: "your token",
8-
# # required, fetch via /gateway/bot
9-
# shard_count: 5,
10-
# # required, fetch via /gateway(/bot)
11-
# url: "wss://gateway.discord.gg",
12-
# # optional
13-
# shards: [1, 2, 3..5]
14-
# # optional
15-
# dispatcher: GenStage.BroadcastDispatcher

lib/gateway.ex

+19-22
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,14 @@ defmodule Crux.Gateway do
7373
| list()
7474

7575
@doc false
76+
@spec init(term()) :: {:ok, tuple()}
7677
def init(opts) when is_list(opts), do: opts |> Map.new() |> init()
7778

7879
def init(opts) do
79-
gateway_opts = transform_opts(opts)
80-
81-
gateway_opts = Map.put(gateway_opts, :gateway, self())
80+
gateway_opts =
81+
opts
82+
|> transform_opts()
83+
|> Map.put(gateway_opts, :gateway, self())
8284

8385
shards =
8486
for shard_id <- gateway_opts.shards do
@@ -158,29 +160,24 @@ defmodule Crux.Gateway do
158160
Map.put(opts, :shards, Enum.to_list(0..(shard_count - 1)))
159161
end
160162

161-
case opts do
162-
%{presence: %{}} ->
163-
nil
164-
165-
%{presence: p} when is_function(p, 1) ->
166-
nil
167-
168-
%{presence: nil} ->
169-
nil
163+
if Map.has_key?(opts, :presence) do
164+
raise_invalid_presence(opts.presence)
165+
end
170166

171-
%{presence: other} ->
172-
raise """
173-
:presence is not of the correct type.
167+
opts
168+
end
174169

175-
Received:
176-
#{inspect(other)}
177-
"""
170+
defp raise_invalid_presence(%{}), do: nil
171+
defp raise_invalid_presence(p) when is_function(p, 1), do: nil
172+
defp raise_invalid_presence(nil), do: nil
178173

179-
_ ->
180-
nil
181-
end
174+
defp raise_invald_presence(other) do
175+
raise """
176+
:presence is not of the correct type.
182177
183-
opts
178+
Received:
179+
#{inspect(other)}
180+
"""
184181
end
185182

186183
defp map_shard(num, _shards) when is_number(num), do: [num]

lib/gateway/command.ex

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Crux.Gateway.Command do
2+
# credo:disable-for-this-file Credo.Check.Readability.SinglePipe
3+
24
@moduledoc """
35
Builds [Gateway Commands](https://discordapp.com/developers/docs/topics/gateway#commands-and-events-gateway-commands).
46
Note: Only the sent ones can be found here.
@@ -56,7 +58,8 @@ defmodule Crux.Gateway.Command do
5658

5759
def identify(%{shard_id: shard_id, shard_count: shard_count, token: token} = args) do
5860
presence =
59-
case args do
61+
args
62+
|> case do
6063
%{presence: presence} when is_map(presence) ->
6164
presence
6265

lib/gateway/connection/connection.ex

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ defmodule Crux.Gateway.Connection do
33
Module handling the actual connection (shard) to Discord.
44
"""
55
alias Crux.Gateway
6-
alias Crux.Gateway.{Connection, Command, IdentifyLimiter, Util}
7-
alias Crux.Gateway.Connection.{RateLimiter, Producer}
6+
alias Crux.Gateway.{Command, Connection, IdentifyLimiter, Util}
7+
alias Crux.Gateway.Connection.{Producer, RateLimiter}
88

99
use WebSockex
1010

@@ -64,6 +64,7 @@ defmodule Crux.Gateway.Connection do
6464
end
6565

6666
@doc false
67+
@spec handle_connect(term(), term()) :: term()
6768
def handle_connect(con, [%{shard_id: shard_id} = args]) do
6869
Logger.info(fn -> "[Crux][Gateway][Shard #{shard_id}]: Connected" end)
6970

@@ -100,6 +101,7 @@ defmodule Crux.Gateway.Connection do
100101
{:ok, state}
101102
end
102103

104+
@spec handle_disconnect(term(), term()) :: term()
103105
def handle_disconnect(reason, %{hello_timeout: ref} = state) do
104106
if ref do
105107
:timer.cancel(ref)
@@ -176,6 +178,7 @@ defmodule Crux.Gateway.Connection do
176178
end
177179

178180
@doc false
181+
@spec handle_info(term(), term()) :: term()
179182
def handle_info(:stop, state), do: {:close, {1000, "Closing connection"}, state}
180183
def handle_info({:send, frame}, state), do: {:reply, frame, state}
181184

@@ -204,6 +207,7 @@ defmodule Crux.Gateway.Connection do
204207
{:close, {4000, @hello_timeout_message}, state}
205208
end
206209

210+
@spec handle_info(term(), term()) :: {:ok, term()}
207211
def handle_info(other, %{shard_id: shard_id} = state) do
208212
Logger.warn(fn ->
209213
"[Crux][Gateway][Shard #{shard_id}]: Received unexpected message: #{inspect(other)}"
@@ -213,20 +217,22 @@ defmodule Crux.Gateway.Connection do
213217
end
214218

215219
@doc false
220+
@spec terminate(term(), term()) :: nil
216221
def terminate(reason, %{shard_id: shard_id}) do
217222
Logger.warn(fn ->
218223
"[Crux][Gateway][Shard #{shard_id}]: Terminating due to #{inspect(reason)}"
219224
end)
220225
end
221226

222227
@doc false
228+
@spec handle_frame(term(), term()) :: {:ok, term()}
223229
def handle_frame({:binary, frame}, %{zlib: {buffer, z}} = state) do
224230
frame_size = byte_size(frame) - 4
225231
<<_data::binary-size(frame_size), suffix::binary>> = frame
226232

227233
buffer = buffer <> frame
228234

229-
{buffer, packet} =
235+
{new_buffer, packet} =
230236
if suffix == <<0, 0, 255, 255>> do
231237
uncompressed =
232238
buffer
@@ -249,7 +255,7 @@ defmodule Crux.Gateway.Connection do
249255
state
250256
end
251257

252-
state = %{state | zlib: {buffer, z}}
258+
state = %{state | zlib: {new_buffer, z}}
253259

254260
{:ok, state}
255261
end
@@ -275,7 +281,7 @@ defmodule Crux.Gateway.Connection do
275281
} = packet
276282
) do
277283
Logger.info(fn ->
278-
"[Crux][Gateway][Shard #{shard_id}]: Ready #{packet.d._trace |> Enum.join(" -> ")}"
284+
"[Crux][Gateway][Shard #{shard_id}]: Ready #{Enum.join(packet.d._trace, " -> ")}"
279285
end)
280286

281287
Producer.dispatch(sup, packet, shard_id)

lib/gateway/connection/producer.ex

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ defmodule Crux.Gateway.Connection.Producer do
3737
end
3838

3939
@doc false
40+
@spec init(term()) :: {:ok, tuple()}
4041
def init(dispatcher) do
4142
state = {
4243
:queue.new(),
@@ -48,13 +49,15 @@ defmodule Crux.Gateway.Connection.Producer do
4849
end
4950

5051
@doc false
52+
@spec handle_cast(term(), term()) :: {:noreply, list(), term()}
5153
def handle_cast({:dispatch, event}, {queue, demand}) do
5254
event
5355
|> :queue.in(queue)
5456
|> dispatch_events(demand, [])
5557
end
5658

5759
@doc false
60+
@spec handle_demand(term(), term()) :: {:noreply, list(), term()}
5861
def handle_demand(incoming_demand, {queue, demand}) do
5962
dispatch_events(queue, incoming_demand + demand, [])
6063
end

lib/gateway/connection/rate_limiter.ex

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ defmodule Crux.Gateway.Connection.RateLimiter do
2727
end
2828

2929
@doc false
30+
@spec init(term()) :: {:ok, tuple()}
3031
def init(_args) do
3132
state = %{
3233
remaining: @limit,
@@ -37,6 +38,7 @@ defmodule Crux.Gateway.Connection.RateLimiter do
3738
end
3839

3940
@doc false
41+
@spec handle_call(term(), GenServer.from(), term()) :: term()
4042
def handle_call(:queue, from, %{remaining: 0, reset: reset} = state) do
4143
case reset - :os.system_time(:seconds) do
4244
reset when reset > 0 ->

lib/gateway/connection/supervisor.ex

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ defmodule Crux.Gateway.Connection.Supervisor do
1111
@spec start_link(args :: term()) :: Supervisor.on_start()
1212
def start_link(args), do: Supervisor.start_link(__MODULE__, args)
1313

14+
@spec init(term()) :: {:ok, tuple()}
1415
def init(args) do
15-
args =
16-
args
17-
|> Map.put(:sup, self())
16+
args = Map.put(args, :sup, self())
1817

1918
dispatcher = Map.get(args, :dispatcher, GenStage.BroadcastDispatcher)
2019

lib/gateway/identify_limiter.ex

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ defmodule Crux.Gateway.IdentifyLimiter do
3131
end
3232

3333
@doc false
34+
@spec init(term()) :: {:ok, term()}
3435
def init(_args) do
3536
Logger.debug("[Crux][Gateway][IdentifyLimiter]: Starting")
3637

@@ -41,6 +42,7 @@ defmodule Crux.Gateway.IdentifyLimiter do
4142
end
4243

4344
@doc false
45+
@spec handle_call(term(), GenServer.from(), term()) :: term()
4446
def handle_call(:queue, _from, ratelimit_reset) do
4547
now = :os.system_time(:milli_seconds)
4648

mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ defmodule Crux.Gateway.MixProject do
4141
{:gen_stage, "~> 0.13.1"},
4242
{:websockex, "~> 0.4.1"},
4343
{:poison, "~> 3.1.0"},
44-
{:credo, "~> 0.9.2", only: [:dev, :test], runtime: false},
44+
{:credo, "~> 1.0.0", only: [:dev, :test], runtime: false},
4545
{:ex_doc,
4646
git: "https://github.com/spaceeec/ex_doc",
4747
branch: "feat/umbrella",

mix.lock

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
%{
22
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
3-
"credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
3+
"credo": {:hex, :credo, "1.0.4", "d2214d4cc88c07f54004ffd5a2a27408208841be5eca9f5a72ce9e8e835f7ede", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
44
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
55
"ex_doc": {:git, "https://github.com/spaceeec/ex_doc", "ba85b84d56c24a42db725858b07f7b2cdc4a37b7", [branch: "feat/umbrella"]},
66
"gen_stage": {:hex, :gen_stage, "0.13.1", "edff5bca9cab22c5d03a834062515e6a1aeeb7665fb44eddae086252e39c4378", [:mix], [], "hexpm"},
7+
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
78
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
89
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
910
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},

0 commit comments

Comments
 (0)